android 布局 View初始化代碼自動產生,androidview
在android開發過程中,介面布局是及其重要的,但同時也是複雜。有的時候我們急於實際運行查看布局效果。但是android的編譯速度我實在不想吐槽啥,尤其在布局越來越複雜,項目越來越大,資源檔越來越多的情況下。
尤其是是android的view的初始化,findViewbyId 完全是體力活,我們完全可以根據布局檔案自動產生View的初始化代碼。
首先聲明:
1.這是及其容易做到的,實用性性一般,但是在複雜布局和首次寫初始化View代碼的時候及其好用。
2.只能產生有id標籤的view的初始化代碼。
思路
其實很簡單,就是解析layout 布局檔案,把有id屬性的標籤的一些資訊(標籤類型,id名稱等)存起來,然後根據這些資訊產生固定的代碼。
實現
直接上代碼,首先是對layout檔案的解析,把解析出來的資訊放在一個list中
public class SaxHander extends DefaultHandler {private List<IdNamePair> map = new ArrayList<IdNamePair>();@Overridepublic void startDocument() throws SAXException {super.startDocument();map.clear();}@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {super.startElement(uri, localName, qName, attributes);//System.out.println("-------------------------------------");String tempid = attributes.getValue("android:id");String id = null;if (tempid != null) {String[] ss = tempid.split("/");if (ss != null && ss.length == 2) {id = ss[1];}}if (id != null) {map.add(new IdNamePair(id, qName));}//System.out.println(id);//System.out.println(qName);}public List<IdNamePair> getRes() {return map;}}
public class IdNamePair {private String id;private String name;/** * @param id * @param name */public IdNamePair(String id, String name) {super();this.id = id;this.name = name;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
然後一點點的拼接代碼
public class ViewCodeUtil {static SAXParserFactory saxfac = SAXParserFactory.newInstance(); static SaxHander mySax = new SaxHander();public static String getCode(String resFileName){File f = new File(resFileName);if (!f.exists()) {return null;}try {saxfac.newSAXParser().parse(f,mySax);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}List<IdNamePair> res = mySax.getRes();StringBuilder sb = new StringBuilder();StringBuilder sb1 = new StringBuilder();sb.append("//---------- 開始定義域--------------\n");sb1.append("//----------開始initView方法------------------\n");sb1.append("public void initView() { \n");for (IdNamePair idNamePair : res) {sb.append(" private "+idNamePair.getName()+" "+ idNamePair.getId()+idNamePair.getName()+";\n"); sb1.append(" "+idNamePair.getId()+idNamePair.getName()+" = ("+idNamePair.getName()+")findViewById(R.id."+idNamePair.getId()+");\n");}sb1.append("}\n");//System.out.println(sb.toString());//System.out.println(sb1.toString());return sb.append(sb1.toString()).toString();}
最後是測試類別main方法。
public class Test {private static final String[] layoutFiles ={"./res/g_ruler.xml","./res/report.xml"}; public static void main(String[] args) {if (args!=null) {for (int i = 0; i < args.length; i++) {System.out.println("");System.out.println("---------"+args[i]+"----------");System.out.println(ViewCodeUtil.getCode(args[i]));}}for (int i = 0; i < layoutFiles.length; i++) {System.out.println("");System.out.println("//---------"+layoutFiles[i]+"----------");System.out.println(ViewCodeUtil.getCode(layoutFiles[i]));}}}
Android代碼中是否可以不用xml布局檔案進行布局,而是直接用代碼在當前View中添加系統組件?
可以的,你如果要添加的View的話你首先可以擷取布局,然後為布局添加 view.addView();
android 代碼布局簡單的例子
(引用樓上的例子)
//初始化線性布局
LinearLayout linearLayout = new LinearLayout(context);
//設定線性布局的方向為豎直方向
linearLayout.setOrientation(LinearLayout.VERTICAL);
//設定線性布局的填充方式為自適應
linearLayout.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
//設定線性布局內的對齊為控制項水平置中
linearLayout.setGravity(Gravity.CENTER_HORIZONTAL);
//初始化圖片按鈕
ImageButton news = new ImageButton(context);
//設定圖片按鈕的id
news.setId(85);
//為圖片按鈕設定監聽器
news.setOnClickListener(this);
//為圖片按鈕設定圖片
news.setBackgroundResource(R.drawable.news);
//設定圖片按鈕的屬性
news.setLayoutParams(new LayoutParams(33, 33));
//將圖片按鈕加入線性布局
linearLayout.addView(news);
簡單的小例子就像上面這樣了,其實很簡單,就像 你要蓋一間房子,裡面有桌子板凳什麼的,你就要設定桌子板凳的各種屬性,長寬高顏色,樣式什麼的,然後 設定 桌子板凳放到 什麼位置,最後 把桌子板凳按照你的想法 放在那個位置上就好了。