[android]再也不用一行一行的写findViewById代码了
前因:最近新做项目,由于现有项目中并没有使用注解,结果写findViewById代码写吐了,于是接想了下解决方案,谷歌了下,发现还真有人实现了,但是不能下载了。于是决定自己写一个工具类。
概述:Android项目开发中,尤其在项目开发的初期,我们总是要重复的写大量的TextView testTv= (TextView)findViewById(R.id.testTv);代码语句,耗时耗力,而且还没什么技术含量。
下面这个java类可以帮你彻底的解脱这个烦恼。(当然,早就有大神使用注解来解决这个问题了)。
使用方法: 将 XML_NAME 和 PROJECT_PATH 两个字段替换为你自己的
使用规范:
1:layout 布局xml文件中的id必须是"@+id/..."这种形式,不得是引用id.
2:在生成代码之前,必须 (CTRL+SHIFT+F )格式化布局xml文件,这个很重要,因为这个工具类的原理仅仅是简单的逐行读取数据而已。
3:为避免出错,请不要有注释。
小提示
1:如果不想对某个id生成对应的成员变量,请将这个id命名成以"_fake"为结尾的后缀,(RelativeLayout中有些节点起id名称可能仅仅是作为相对元素定位之用)
package tdc.opt.xml.to.code; import java.io.BufferedReader; import java.io.FileReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class MakeAndroidXml2Code { private static final String NULL_STRING_2 = " ";// " " private static final String NULL_STRING_1 = " ";// " " private static final String XML_SUFFX = ".xml"; private static final String TEXT_VIEW = "TextView"; private static final String BUTTON = "Button"; private static final String VIEW_HOLDER_CLASS_NAME = "ViewHolder"; private static final String FAKE_TAG = "_fake"; private static final String CONVERT_VIEW = "convertView"; private final String XML_NAME = "shou_ye_ji_fen_item.xml"; private String PROJECT_PATH = "/Users/tangdengcheng/Documents/android_workplace/CaiMiLottery"; private String xmlPath = PROJECT_PATH + "/res/layout/" + XML_NAME; private boolean isMakeOnClickListener = true; private boolean isMakeSetText = true; public static void main(String[] args) { MakeAndroidXml2Code makeAndroidXml2Code = new MakeAndroidXml2Code(); makeAndroidXml2Code.makeOnCreateCode(); makeAndroidXml2Code.makeGetViewCode(); } /** * 根据ID在Activity onCreate 方法中生成findViewById的方法以及对应的成员变量 */ public void makeOnCreateCode() { Map<String, String> map = new HashMap<String, String>(); BufferedReader bufferedReader = null; String lastLine = ""; try { bufferedReader = new BufferedReader((new FileReader(xmlPath))); while (bufferedReader.read() != -1) { final String readLine = bufferedReader.readLine().toString() .trim(); if (readLine.contains("android:id=\"@+id/") && !readLine.contains(FAKE_TAG)) { String key = readLine.replace("android:id=\"@+id/", "") .replace("\"", ""); String value = lastLine.replace("<", ""); map.put(key, value); } lastLine = readLine; } } catch (Exception e) { e.printStackTrace(); } for (Iterator<String> iterator = map.keySet().iterator(); iterator .hasNext();) { String id = (String) iterator.next(); System.out.println(NULL_STRING_1 + "private " + map.get(id) + " " + id + ";"); } System.out.println(); System.out.println(NULL_STRING_1 + "private void initView(){"); System.out.println(); for (Iterator<String> iterator = map.keySet().iterator(); iterator .hasNext();) { String id = iterator.next(); System.out.println(NULL_STRING_2 + id + " = (" + map.get(id) + ")findViewById(R.id." + id + ");"); } if (isMakeOnClickListener) { System.out.println(); for (String key : map.keySet()) { if (BUTTON.equals(map.get(key))) { System.out.println(NULL_STRING_2 + key + ".setOnClickListener(this);"); } } } if (isMakeSetText) { System.out.println(); for (String key : map.keySet()) { if (TEXT_VIEW.equals(map.get(key))) { System.out .println(NULL_STRING_2 + key + ".setText(" + ");"); } } } System.out.println(NULL_STRING_1 + "}"); } /** * 在BaseAdapter类中,根据指定的xml布局文件生成对应的findViewById方法以及对应的ViewHolder */ public void makeGetViewCode() { Map<String, String> map = new HashMap<String, String>(); BufferedReader bufferedReader = null; String lastLine = ""; try { bufferedReader = new BufferedReader((new FileReader(xmlPath))); while (bufferedReader.read() != -1) { final String readLine = bufferedReader.readLine().toString() .trim(); if (readLine.contains("android:id=\"@+id/") && !readLine.contains(FAKE_TAG)) { String key = readLine.replace("android:id=\"@+id/", "") .replace("\"", ""); String value = lastLine.replace("<", ""); map.put(key, value); } lastLine = readLine; } } catch (Exception e) { e.printStackTrace(); } System.out.println(" " + "private final class " + VIEW_HOLDER_CLASS_NAME + " { "); for (Iterator<String> iterator = map.keySet().iterator(); iterator .hasNext();) { String id = (String) iterator.next(); System.out.println(NULL_STRING_2 + "private " + map.get(id) + " " + id + ";"); } System.out.println(NULL_STRING_1 + "}"); System.out.println(); System.out.println(); System.out.println(NULL_STRING_1 + "@Override"); System.out.println(NULL_STRING_1 + "public View getView(int position, View " + CONVERT_VIEW + ", ViewGroup parentViewGroup) {"); String xmlString = XML_NAME.contains(XML_SUFFX) ? XML_NAME.replace( XML_SUFFX, "") : XML_NAME; final String firstString = new String( new char[] { VIEW_HOLDER_CLASS_NAME.charAt(0) }); final String classObject = firstString.toLowerCase() + VIEW_HOLDER_CLASS_NAME.substring(1, VIEW_HOLDER_CLASS_NAME.length()); System.out.println(NULL_STRING_2 + VIEW_HOLDER_CLASS_NAME + " " + classObject + " = null ;"); System.out.println(NULL_STRING_2 + "if (" + CONVERT_VIEW + " == null) { "); System.out.println(NULL_STRING_2 + CONVERT_VIEW + " = LayoutInflater.from(context) .inflate(R.layout." + xmlString + ", parentViewGroup,false);"); System.out.println(NULL_STRING_2 + classObject + " = new " + VIEW_HOLDER_CLASS_NAME + " ();"); for (Iterator<String> iterator = map.keySet().iterator(); iterator .hasNext();) { String id = (String) iterator.next(); System.out.println(NULL_STRING_2 + classObject + "." + id + " = (" + map.get(id) + ")" + CONVERT_VIEW + "." + "findViewById(R.id." + id + ");"); } if (isMakeOnClickListener) { System.out.println(); for (String key : map.keySet()) { if (BUTTON.equals(map.get(key))) { System.out.println(NULL_STRING_2 + classObject + "."+key + ".setOnClickListener(this);"); } } System.out.println(); } System.out.println(NULL_STRING_2 + CONVERT_VIEW + ".setTag(" + classObject + ");"); System.out.println(NULL_STRING_2 + "} " + "else { "); System.out.println(" " + classObject + " = (" + VIEW_HOLDER_CLASS_NAME + ")" + CONVERT_VIEW + ".getTag(); "); System.out.println(NULL_STRING_2 + "}"); if (isMakeSetText) { System.out.println(); for (String key : map.keySet()) { if (TEXT_VIEW.equals(map.get(key))) { System.out.println(NULL_STRING_2 + classObject + "."+key + ".setText();"); } } System.out.println(); } System.out.println(NULL_STRING_2 + "return convertView;"); System.out.println(NULL_STRING_1 + "}"); } }
XML
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="90dp" android:background="@drawable/icaimi_gc_item_bg_selector_ming" > <TextView android:id="@+id/gridItemTitleTv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="5dp" android:text="竞彩足球" android:textColor="#666666" android:textSize="15sp" /> <TextView android:id="@+id/gridItemTitleDescTv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/gridItemTitleTv" android:layout_centerHorizontal="true" android:layout_marginBottom="3dp" android:layout_marginTop="2.5dp" android:ellipsize="end" android:singleLine="true" android:text="2快中100元" android:textColor="#b0b0b0" android:textSize="@dimen/text_size_ten" /> <ImageView android:id="@+id/gridItemIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/gridItemTitleDescTv" android:layout_centerHorizontal="true" android:src="@drawable/shouye_pig" /> <View android:layout_width="@dimen/divider_height" android:layout_height="match_parent" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" android:background="@color/fa_xian_divider" /> </RelativeLayout>
生成的代码有
private TextView gridItemTitleTv; private ImageView gridItemIcon; private TextView gridItemTitleDescTv; private void initView(){ gridItemTitleTv = (TextView)findViewById(R.id.gridItemTitleTv); gridItemIcon = (ImageView)findViewById(R.id.gridItemIcon); gridItemTitleDescTv = (TextView)findViewById(R.id.gridItemTitleDescTv); gridItemTitleTv.setText(); gridItemTitleDescTv.setText(); }
如果是ListView的item则会是:
private final class ViewHolder { private TextView gridItemTitleTv; private ImageView gridItemIcon; private TextView gridItemTitleDescTv; } @Override public View getView(int position, View convertView, ViewGroup parentViewGroup) { ViewHolder viewHolder = null ; if (convertView == null) { convertView = LayoutInflater.from(context) .inflate(R.layout.shou_ye_ji_fen_item, parentViewGroup,false); viewHolder = new ViewHolder (); viewHolder.gridItemTitleTv = (TextView)convertView.findViewById(R.id.gridItemTitleTv); viewHolder.gridItemIcon = (ImageView)convertView.findViewById(R.id.gridItemIcon); viewHolder.gridItemTitleDescTv = (TextView)convertView.findViewById(R.id.gridItemTitleDescTv); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder)convertView.getTag(); } viewHolder.gridItemTitleTv.setText(); viewHolder.gridItemTitleDescTv.setText(); return convertView; }