0x1、引言
2333,看這標題就知道不是什麼正經技術文章,花了點時間,寫了個「無用良品」,以後請叫我「Android界愛迪生——樊少皇」,蟹蟹~
最近公司APP版本迭代,一個人寫介面,寫到我真的想吐:
有些路人可能會說:不喜歡寫,你不會拖拉控制元件嗎,憨憨。
可能各位都是:i9 9900K,850 PRO,64G DDR4,拖拽控制元件絲滑流暢,不知人間疾苦…
如果您像小弟一樣用著公司配的:i3家用桌上型電腦,你也會秒變「祖安人」
拖拽卡頓不靈活不說,拖拽完還得進程式碼調來調去,有時效率還不如手敲。
Google很久以前出的ConstraintLayout約束佈局是挺好用的,就是要寫多一堆屬性,比如每個控制元件必不可少的:
雖說AS自動補全,但是寫起來,效率並不是很高。作為一個「具有4點多堆砌佈局經驗的Android開發仔」一個重要的標準就是:看到一個設計圖,立馬在心中解析出「頁面佈局的層次結構」比如這樣的個人中心的頁面:
直接解析:
約束佈局
相對佈局
回退- Button
標題-TextView
卡片檢視
約束佈局
頭像-ImageView
登陸提示-TextView
更多箭頭-ImageView
卡片檢視
約束佈局
訂單圖示-ImageView
訂單文字-TextView
訂單更多-ImageView
兌換圖示-ImageView
兌換文字-TextView
兌換更多-ImageView
...略
複製程式碼
解析倒是挺簡單,不顧敲起來,大部分是機器式重複,。前不久在逼乎上看到這段話:
覺得還挺有道理,著實需要一種智識和能力去改進,從這樣的「時間泥潭」中跳出。
腦海中萌生了「模板程式碼」思路:
和AS自帶新建佈局模板的方式有點不一樣,精確到控制元件級別,用 關鍵字匹配 控制元件對應的模板程式碼。
當我輸入tv的時候,匯入對應的一大串程式碼,輸入tvc的時候匯入另一串程式碼。
不過這個思路在我寫完一個TextView後就放棄了,TM的那麼多控制元件,要寫多少套,而且很多屬性是多餘的…
這種思路妥妥滴不行,於是又萌生了另一種思路:
「定義一套自己的語法規則,寫少量,用指令碼翻譯成AS裡的XML檔案」
嘖嘖嘖,這樣也意味著可以
「可以脫離Android Studio寫佈局檔案,而且比一個個字母手敲xml高效!」
想想,你可以「在地鐵上用便籤寫佈局,然後到公司用指令碼直接翻譯成XML佈局」太酷了吧!
0x2、規律 => 規則
定義這套語法規則之前,我們先要了解一下xml佈局的規律:
# XML由一個個標籤(結點)構成,分為:單標籤 和 雙標籤(可巢狀),如:
<TextView .../> 和 <LinearLayout ..></LinearLayout>
# 然後標籤的組成
<控制元件名
屬性:值
屬性:值
.../>
複製程式碼
綜上,不難得出兩個規律:
① 標籤其實有三種:開標籤,關標籤,閉合標籤,要進行區分
② 標籤 = <控制元件名 若干屬性:值>
另外,Android是建議,每個控制元件都設定一個id屬性的,不難定義一個類來代表一個標籤:
class Node:
def __init__(self, widget=None, id=None, kv=None):
self.widget = widget
self.id = id
self.kv = kv
複製程式碼
1、標籤的區分
上面也說了,標籤由三種,這裡引入三個符號來進行標記(+-*),比如:
+ 線性佈局
* 文字檢視
- 線性佈局
複製程式碼
新建配置檔案config.ini用於儲存「自定義簡稱 與 控制元件的對映關係」
注意:這裡的簡稱可以定義成你自己喜歡的,中文也行!
接著寫個讀取配置檔案的指令碼config_getter.py,讀取下:
再接著新建一個輸入源test.txt檔案,內容如下:
最後寫指令碼讀取txt檔案,按行讀取,過濾空格和換行,根據字串第一個字元進行過濾:
執行後可以看到輸出的xml檔案:
堆一起,看不出什麼,格式化看看效果:
嘖嘖嘖,有內味了。
2、屬性
一個控制元件可以有多個屬性,多個屬性怎麼進行分割呢?筆者用的是「>」
然後屬性和值又怎麼分割呢?本來是想用 :或| 的,後面發現都用到了,最後決定用「-」來分割。
一個簡單的示例如下:
* bt > bt_back > w-56 > h-56 > t-返回
複製程式碼
上述的程式碼代表:
定義一個按鈕,id為bt_back,寬56dp,高56dp,文字為返回
另外,有些常用的屬性-值,可以簡化下,比如:
android:layout_width="wrap_content"
# 可以寫成
w-wrap_content
# 簡化
w-w
# 再簡化
ww
複製程式碼
用 ww 就可以代替:android:layout_width="wrap_content"
程式處理的時候需要對:w-w 和 ww進行區分,區分方法也很簡單:
len(split("-")) == 1,說明是後者,否則是前者
嘖嘖嘖,可以,繼續~
3、值
值的情形稍微複雜一點,常見的有下面這些:
android:gravity="center|start"
android:layout_width="match_parent"
android:background="@drawable/ic_back_white"
android:layout_marginStart="60dp"
app:layout_constraintDimensionRatio="16:9"
複製程式碼
其實劃分下,筆者需要只需區分三種型別
- ① 直接填充 -> 屬性="xxx"
- ② 數字dp -> 屬性="xdp"
- ③ @資源引用 -> 屬性="@x/y"
所以處理的流程:
Step 1:判斷是否為數字,是的話加上dp,否則跳Step 2
Step 2:利用正則判斷是否為@型別,是的話提取下型別與值,否則跳Step3
Step 3: 判斷是否包含此屬性,是填充模板,否則直接填充
也很簡單,接下來就是寫程式碼來組裝我們的「老八祕製小漢堡」了!!!
0x3、組裝老八祕製小漢堡
先是完善配置檔案:config.ini
這裡可以根據自己的習慣自定義在對應的區域,增加或者減少,動態配置~
在翻譯指令碼 AutoTranslate.py 的開頭讀取一波配置資訊:
接著定義一個讀取節點列表的方法:
再接著定義一個解析翻譯結點內容的方法:
最後定義一個寫入檔案的方法:
接著花幾分鐘寫個佈局txt檔案:
轉換指令碼呼叫下相關方法:
執行一波,可以看到生成了一個test.xml的佈局檔案,開啟瞅瞅:
嘖嘖,格式化?
把xml複製到專案中,看看效果?
此處應該有掌聲!啪啪啪!
0x4、奧利給,吃粑粑
指令碼的大概雛形完成了,後面可以優化下互動和小細節,不過感覺沒技術含量?巧了,最近在 刷題,加個演算法耍耍?來個LeetCode原題「有效的括號」,題目描述如下:
就是 匹配符號開閉,跟我們這個場景非常相似哇,匹配開閉節點:
# 開閉節點需要一一對應,比如:
+ cly
- cly
# 多了少了,都不行(如下兩種都是錯誤的)
+ cly
+ cly
- cly
+ cly
+ ly
- cly
- ly
複製程式碼
怎麼解決?最標準解法就是用 棧 了,比較簡單,直接擼程式碼:
接著呼叫下:
故意寫錯結點,執行看看:
可以,大功告成~
0x5、小結
久違的摸魚閒暇時光,給大家做了一個老八祕製作小?,呸…
「Android佈局翻譯器」
有了它,你可以在??上用文字編輯器,便籤等來完成Android佈局的編寫。
當然,目前只是雛形,你可以根據自己需要,進行動態配置,優化等,以此提高你的效率~
此時我突然想起:曾揚言收購蘋果,如今直播帶貨的老羅,當初提出的TNT系統,結合下這個指令碼,
寫佈局完全可以靠喊:
文字框 > 居中 > 變黑 > 變大 > 加粗…
嘖嘖嘖,有點意思,本節的一本正經的胡說八道到此結束,感謝閱讀~
- Github倉庫:github.com/coder-pig/A…