android 巧妙利用反射机制得到ListView中的view

我们在使用ListView的时候,经常会使用的ViewHolder方式作为缓存,每次都需要手动的通过viewholder.icon = convertview.findVIewByid(id);一般的app都会有好几个页面会用到ListView,这样的话我们的代码量就会很大,有没有好点的办法呢,其实今天学习了反射机制,利用所有的控件的超类都是View这个特点,循环给ViewHolder里边的控件赋值,下边是具体代码:
public final class ResouceHandleUtil {
public interface ReflectResouce{
public View findViewById(int viewId);
}
/**
* 注意Java中只有值传递。
* @param target
* @param mconContext
*/
public static final void reflectView(ReflectResouce target ,Context mContext){
Field[] fields = target.getClass().getDeclaredFields();//得到所有属性,注意target.getClass() 得到是具体堆内存里边的对象的类型
for (Field field : fields) {
final String fieldName = field.getName();//得到属性名称
View childView = target.findViewById(getResoucesId(mContext, fieldName));//得到view控件对象
try {
if(View.class.isAssignableFrom(childView.getClass())){//如果childView是View的子类
boolean accessible = field.isAccessible();//得到属性的访问权限
field.setAccessible(true);//打开修改权限
try {
field.set(target, childView);//这一步是关键,最后的结果是target.field=childView
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
field.setAccessible(accessible);
}
} catch (Exception e) {
new IllegalArgumentException("the childView is not the child of View").printStackTrace();
}
}
}
/**
* get the id value of view, According to view name
* @param mContext
* @param fName
* @return 根据反射得到view的id值
*/
public static final int getResoucesId(Context mContext ,String fName){
return mContext.getResources().getIdentifier(fName, "id", mContext.getPackageName());
}


/**
 * 适配器的通用性使用泛型
 * @author Administrator
 *
 * @param <P>
 */
public abstract class CommonAdapter<P> extends BaseAdapter {
private List<P> data = null;
protected Context mContext = null;
protected LayoutInflater layoutInflater = null;
public CommonAdapter(List<P> list, Context mContext){
this.data = list;
this.mContext = mContext;
layoutInflater = LayoutInflater.from(this.mContext);
}
@Override
public int getCount() {
return data==null?0:data.size();
}

@Override
public P getItem(int position) {
return (data==null||data.size()==0)?null:data.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

public void setDatas(List<P> da){
this.data = da;
notifyDataSetChanged();
}

public void appendData(List<P> da){
if(this.data == null){
setDatas(da);
}else {
this.data.addAll(da);
notifyDataSetChanged();
}
}
}
public class StudentAdapter extends CommonAdapter<Students> {

public StudentAdapter(Context mContext,List<Students> list) {
super(list,mContext);
}

@SuppressLint("InflateParams")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if(convertView==null){
convertView = layoutInflater.inflate(R.layout.student_item, null);
viewHolder = new ViewHolder(convertView);
ResouceHandleUtil.reflectView(viewHolder, mContext);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
Students student = getItem(position);
viewHolder.head_icon.setImageResource(R.drawable.ic_launcher);
viewHolder.banji_view.setText(student.getBanji());
viewHolder.name_view.setText(student.getName());
return convertView;
}
class ViewHolder implements ReflectResouce{
private View rootView;
public ViewHolder(View rootView){
this.rootView = rootView;
}
@Override
public View findViewById(int viewId) {
return rootView.findViewById(viewId);
}
/**
* 注意下边的属性名字必须和xml里边的id名字一样
*/
private ImageView head_icon;
private TextView name_view,banji_view;
}

student_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/head_icon"
        android:layout_width="wrap_content"
        android:layout_height="40dp"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="10dp" />

    <TextView
        android:id="@+id/name_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/head_icon"
        android:maxLength="10"
        android:singleLine="true"
        android:textSize="14sp" />
    <TextView
        android:id="@+id/banji_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/name_view"
        android:layout_toRightOf="@id/head_icon"
        android:maxLength="10"
        android:singleLine="true"
        android:textSize="14sp" />

</RelativeLayout>

这样的话 ListView的适配性很好的扩展性能,ViewHolder中view的具体值很好的封装起来了。
源码地址:http://download.csdn.net/detail/zhanwei_30/8842573
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值