android通過反射代替findViewById的過多使用


開發android應用時,在activity中總是要寫很多findViewById來獲取XML佈局中的各種組件,而它們都是相似的,只是組件類型和id不同而已,根據DRY原則,我們可以把一些

相同的代碼進行封裝,這樣就節省了很多代碼量,在一個複雜的activity中不會顯得臃腫。


   我們可以寫一個類,利用反射來實現,通過反射獲得各個組件並初始化它們:


  AndFrameWork.java如下所示:

package com.example.andframework;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.app.Activity;
import android.view.View;

public class AndFrameWork {
	/**
	 * 初始化組件
	 * @param context 
	 * @throws NoSuchMethodException 
	 * @throws ClassNotFoundException 
	 * @throws NoSuchFieldException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 * @throws InvocationTargetException 
	 */
	public static void initComponent(Activity context) throws NoSuchMethodException, ClassNotFoundException, NoSuchFieldException, 
	                                   IllegalArgumentException, IllegalAccessException, InvocationTargetException{
		//獲得Class對象實例
		Class clazz = context.getClass();
		//獲得context所有屬性
		Field[] fields = clazz.getDeclaredFields();
		//遍歷fields
		for (Field field : fields) {
			//獲得屬性名
			String fieldName = field.getName();
			//獲得set方法名
			String setMethodName = "set" + initCap(fieldName);
			//獲得set方法
			Method setMethod = clazz.getDeclaredMethod(setMethodName, field.getType());
			String packageName = "com.example.andframework";
			//R類的Class實例
			Class Rclazz = Class.forName(packageName + ".R$id");
			//獲得組件的id值
			Field fName = Rclazz.getDeclaredField(fieldName);
			int id = fName.getInt(null);
			//通過findViewById獲得UI視圖
			View view = context.findViewById(id);
			//將視圖設置到界面屬性中
			setMethod.invoke(context, view);
		}
		
	}
	/**
	 * 對給定字符串進行首字母大寫 
	 * @param name
	 * @return
	 */
	public static String initCap(String name){
		StringBuilder sb = new StringBuilder(name.substring(0,1).toUpperCase()); 
		sb.append(name.substring(1));
		return sb.toString();
	}
}

  MainActivity.java如下所示:

package com.example.andframework;

import java.lang.reflect.InvocationTargetException;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
	
	
	//聲明個組件屬性,注意名字要跟XML中id值相同,提供set get方法
	private TextView textView1;
	private Button button1;
	private Button button2;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
//		textview1 = (TextView) findViewById(R.id.textView1);
//		button1 = (Button) findViewById(R.id.button1);
//		button2 = (Button) findViewById(R.id.button2);
		
		//調用initComponent方法初始化視圖界面
		try {
			AndFrameWork.initComponent(this);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		//設置監聽器
		button1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Toast.makeText(getApplicationContext(), "反射測試完畢!", Toast.LENGTH_SHORT).show();
			}
		});
		
		button2.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				textView1.setText("世界,你好!");
				Toast.makeText(getApplicationContext(), "上面文字以改變!", Toast.LENGTH_SHORT).show();
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public TextView getTextView1() {
		return textView1;
	}

	public void setTextView1(TextView textView1) {
		this.textView1 = textView1;
	}

	public Button getButton1() {
		return button1;
	}

	public void setButton1(Button button1) {
		this.button1 = button1;
	}

	public Button getButton2() {
		return button2;
	}

	public void setButton2(Button button2) {
		this.button2 = button2;
	}

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章