2333,看這標題就知道不是什麼正經技術文章,花了點時間,寫了個「無用良品」,之後請叫我「Android界愛迪生——樊少皇」,蟹蟹~android
最近公司APP版本迭代,一我的寫界面,寫到我真的想吐:git
有些路人可能會說:不喜歡寫,你不會拖拉控件嗎,憨憨。github
可能各位都是:i9 9900K,850 PRO,64G DDR4,拖拽控件絲滑流暢,不知人間疾苦…
若是您像小弟同樣用着公司配的:i3家用臺式機,你也會秒變「祖安人」web
拖拽卡頓不靈活不說,拖拽完還得進代碼調來調去,有時效率還不如手敲。
Google好久之前出的ConstraintLayout約束佈局是挺好用的,就是要寫多一堆屬性,好比每一個控件必不可少的:算法
雖然說AS自動補全,可是寫起來,效率並非很高。做爲一個「具備4點多堆砌佈局經驗的Android開發仔」一個重要的標準就是:看到一個設計圖,立馬在心中解析出「頁面佈局的層次結構」好比這樣的我的中心的頁面:apache
直接解析:ruby
約束佈局
相對佈局
回退- Button
標題-TextView
卡片視圖
約束佈局
頭像-ImageView
登錄提示-TextView
更多箭頭-ImageView
卡片視圖
約束佈局
訂單圖標-ImageView
訂單文本-TextView
訂單更多-ImageView
兌換圖標-ImageView
兌換文本-TextView
兌換更多-ImageView
...略
複製代碼
解析卻是挺簡單,不顧敲起來,大部分是機器式重複,。前不久在逼乎上看到這段話:markdown
以爲還挺有道理,着實須要一種智識和能力去改進,從這樣的「時間泥潭」中跳出。app
腦海中萌生了「模板代碼」思路:編輯器
和AS自帶新建佈局模板的方式有點不同,精確到控件級別,用 關鍵字匹配 控件對應的模板代碼。
當我輸入tv的時候,導入對應的一大串代碼,輸入tvc的時候導入另外一串代碼。
不過這個思路在我寫完一個TextView後就放棄了,TM的那麼多控件,要寫多少套,並且不少屬性是多餘的…
這種思路妥妥滴不行,因而又萌生了另外一種思路:
「定義一套本身的語法規則,寫少許,用腳本翻譯成AS裏的XML文件」
嘖嘖嘖,這樣也意味着能夠
「能夠脫離Android Studio寫佈局文件,並且比一個個字母手敲xml高效!」
想一想,你能夠「在地鐵上用便籤寫佈局,而後到公司用腳本直接翻譯成XML佈局」太酷了吧!
定義這套語法規則以前,咱們先要了解一下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
複製代碼
上面也說了,標籤由三種,這裏引入三個符號來進行標記(+-*),好比:
+ 線性佈局
* 文本視圖
- 線性佈局
複製代碼
新建配置文件config.ini用於保存「自定義簡稱 與 控件的映射關係」
注意:這裏的簡稱能夠定義成你本身喜歡的,中文也行!
接着寫個讀取配置文件的腳本config_getter.py,讀取下:
再接着新建一個輸入源test.txt文件,內容以下:
最後寫腳本讀取txt文件,按行讀取,過濾空格和換行,根據字符串第一個字符進行過濾:
運行後能夠看到輸出的xml文件:
堆一塊兒,看不出什麼,格式化看看效果:
嘖嘖嘖,有內味了。
一個控件能夠有多個屬性,多個屬性怎麼進行分割呢?筆者用的是「>」
而後屬性和值又怎麼分割呢?原本是想用 :或| 的,後面發現都用到了,最後決定用「-」來分割。
一個簡單的示例以下:
* 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,說明是後者,不然是前者
嘖嘖嘖,能夠,繼續~
值的情形稍微複雜一點,常見的有下面這些:
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: 判斷是否包含此屬性,是填充模板,不然直接填充
也很簡單,接下來就是寫代碼來組裝咱們的「老八祕製小漢堡」了!!!
先是完善配置文件:config.ini
這裏能夠根據本身的習慣自定義在對應的區域,增長或者減小,動態配置~
在翻譯腳本 AutoTranslate.py 的開頭讀取一波配置信息:
接着定義一個讀取節點列表的方法:
再接着定義一個解析翻譯結點內容的方法:
最後定義一個寫入文件的方法:
接着花幾分鐘寫個佈局txt文件:
轉換腳本調用下相關方法:
運行一波,能夠看到生成了一個test.xml的佈局文件,打開瞅瞅:
嘖嘖,格式化?
把xml複製到項目中,看看效果?
此處應該有掌聲!啪啪啪!
腳本的大概雛形完成了,後面能夠優化下交互和小細節,不過感受沒技術含量?巧了,最近在 刷題,加個算法耍耍?來個LeetCode原題「有效的括號」,題目描述以下:
就是 匹配符號開閉,跟咱們這個場景很是類似哇,匹配開閉節點:
# 開閉節點須要一一對應,好比:
+ cly
- cly
# 多了少了,都不行(以下兩種都是錯誤的)
+ cly
+ cly
- cly
+ cly
+ ly
- cly
- ly
複製代碼
怎麼解決?最標準解法就是用 棧 了,比較簡單,直接擼代碼:
接着調用下:
故意寫錯結點,運行看看:
能夠,大功告成~
久違的摸魚閒暇時光,給你們作了一個老八祕製做小🍔,呸…
「Android佈局翻譯器」
有了它,你能夠在🚇🚍上用文本編輯器,便籤等來完成Android佈局的編寫。
固然,目前只是雛形,你能夠根據本身須要,進行動態配置,優化等,以此提升你的效率~
此時我忽然想起:曾揚言收購蘋果,現在直播帶貨的老羅,當初提出的TNT系統,結合下這個腳本,
寫佈局徹底能夠靠喊:
文本框 > 居中 > 變黑 > 變大 > 加粗…
嘖嘖嘖,有點意思,本節的一本正經的胡說八道到此結束,感謝閱讀~