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;
	}

}



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