辛苦堆砌,轉載請注明出處,謝謝!
軟件開發中,我們有不少重復性的工作,這些工作,我們可以自己編寫一些小程序來實現自動化,還可以按照自己的編程習慣做簡單的定制,還是比較方便的。Android開發中,一項重復性的工作就是聲明一個成員變量,比如
PRivate Button mTestButton;然后,我們最常做的工作就是在onCreate中再調用findViewById實現從布局文件到java變量的映射mTestButton = (Button) findViewById(R.id.test_button);如果布局文件比較大,而且id比較多,我們要手動敲很多代碼,然后還要注意強制類型轉換。之前為了減少自己敲擊代碼的工作量,利用python制做了一個小工具,大家可以試著用用,也可以在此基礎上做一些修改,方便自己使用,程序員要利用自己的能力,減輕自己的工作才好。當然我們也可以使用Android Studio的代碼模板做類似的事情,但是還是避免不了我要修改模板中的一些內容,利用我自己的這個小工具,至少對我來說,符合自己的變量定義習慣和代碼風格,而且只需要復制到對應的Java文件即可。下面給出代碼
#coding=utf-8from xml.etree.ElementTree import parseimport osclass AndroidLayoutFileParser: #android:id android_id = "{http://schemas.android.com/apk/res/android}id" android_id_add = "@+id/" #成員變量聲明格式串 declare = "private %s %s;/n" #findViewById格式串 find_view_by_id = "%s = (%s) findViewById(R.id.%s);/n" def __init__(self, input_filename, need_open_file=True): self.result_list = [] self.output_filename = input_filename.replace(".xml", ".txt") self.need_open_file = need_open_file self.root_node = parse(input_filename).getroot() def start(self): self.__parse_tree__(self.root_node) def open_result_file(self): os.system('notepad %s' % self.output_filename) def __parse_tree__(self, node): if node is None: return #分析根節點 if self.root_node == node: self.__parse_node__(node) #遞歸分析子節點 for child in node: self.__parse_node__(child) self.__parse_tree__(child) self.__print_result_file__() def __parse_node__(self, node): try: element_id = node.attrib[self.android_id] if element_id.find(self.android_id_add) != -1: #[[Android布局或者視圖控件類型(如LinearLayout,Button等), id],] self.result_list.append([node.tag, element_id[len(self.android_id_add):]]) except KeyError: pass def __form_var_name__(self, id): var_name = "m" name_fragments = id.split("_") if len(name_fragments) != 1: #如果id是用下劃線分割的字符串命名id,則生成變量名修正為駝峰式 #如id為test_button,則mTestButton for name_fragment in name_fragments: var_name += name_fragment.capitalize() else: #如果id是一個單詞,如testButton,則生成mTestButton var_name += id.capitalize() return var_name def __print_result_file__(self): if len(self.result_list) != 0: output = open(self.output_filename, "w") output.write("================聲明===================/n") for result in self.result_list: type, id = result output.write(self.declare % (type, self.__form_var_name__(id))) output.write("/n") output.write("================findViewById===================/n") for result in self.result_list: type, id = result output.write(self.find_view_by_id % (self.__form_var_name__(id), type, id)) output.close()if __name__ == "__main__": layout_files = [] files = os.listdir(os.curdir) for file in files: if file.endswith(".xml"): layout_files.append(file) for file in layout_files: parser = AndroidLayoutFileParser(file) parser.start() parser.open_result_file()我使用時一般將該腳本放置在一個單獨的目錄,然后復制想要生成代碼的布局文件到該目錄下,執行Python腳本,例如,我將該腳本命名為android_findViewById.py,然后有一個測試的layout文件fragment_login.xml,這個是我從之前項目中摘取的一些控件,真正關注的是android:id,其他的沒有太大的意義。<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/root_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:oritation="vertical"> <ImageView android:id="@+id/login_title_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_icon_logo1" /> <EditText android:id="@+id/username" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginTop="40dp" /> <Button android:id="@+id/login_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登陸" /></LinearLayout>然后執行腳本,生成一個fragment_login.txt并自動打開,結果如圖:可以看到,正確生成了對應的代碼,效果還是不錯的XD。
新聞熱點
疑難解答