Android 布 局 翻 譯 器

0x一、引言


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佈局」太酷了吧!


0x二、規律 => 規則


定義這套語法規則以前,咱們先要了解一下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: 判斷是否包含此屬性,是填充模板,不然直接填充

也很簡單,接下來就是寫代碼來組裝咱們的「老八祕製小漢堡」了!!!


0x三、組裝老八祕製小漢堡


先是完善配置文件:config.ini

這裏能夠根據本身的習慣自定義在對應的區域,增長或者減小,動態配置~
在翻譯腳本 AutoTranslate.py 的開頭讀取一波配置信息:

接着定義一個讀取節點列表的方法:

再接着定義一個解析翻譯結點內容的方法:


最後定義一個寫入文件的方法:

接着花幾分鐘寫個佈局txt文件:

轉換腳本調用下相關方法:

運行一波,能夠看到生成了一個test.xml的佈局文件,打開瞅瞅:

嘖嘖,格式化?

把xml複製到項目中,看看效果?

此處應該有掌聲!啪啪啪!


0x四、奧利給,吃粑粑


腳本的大概雛形完成了,後面能夠優化下交互和小細節,不過感受沒技術含量?巧了,最近在 刷題,加個算法耍耍?來個LeetCode原題有效的括號,題目描述以下:

就是 匹配符號開閉,跟咱們這個場景很是類似哇,匹配開閉節點

# 開閉節點須要一一對應,好比:
cly
cly

# 多了少了,都不行(以下兩種都是錯誤的)
cly
cly
cly

cly
ly
cly
ly
複製代碼

怎麼解決?最標準解法就是用 了,比較簡單,直接擼代碼:

接着調用下:

故意寫錯結點,運行看看:

能夠,大功告成~


0x五、小結


久違的摸魚閒暇時光,給你們作了一個老八祕製做小🍔,呸…

Android佈局翻譯器

有了它,你能夠在🚇🚍上用文本編輯器,便籤等來完成Android佈局的編寫。
固然,目前只是雛形,你能夠根據本身須要,進行動態配置,優化等,以此提升你的效率~
此時我忽然想起:曾揚言收購蘋果,現在直播帶貨的老羅,當初提出的TNT系統,結合下這個腳本,
寫佈局徹底能夠靠喊:

文本框 > 居中 > 變黑 > 變大 > 加粗…

嘖嘖嘖,有點意思,本節的一本正經的胡說八道到此結束,感謝閱讀~



相關文章
相關標籤/搜索