Android中通用配器的使用

来源:互联网 发布:李鸿章杀降 知乎 编辑:程序博客网 时间:2024/05/24 02:02

1、简介
在Android开发过程中,我们经常需要写一些ListView和GridView等控件,如果给每一个都写一个适配器的话,过程无疑十分的枯燥,只会消耗大量的时间做这写毫无意义的事情,下面给大家介绍一个通用适配器。
2.一般的适配器的使用
普通的用法是:每一个ListView或者是GridView需要一个资源配置的XML文件,一个ViewHolder,一个普通的继承BaseAdapter的适配器。
1.布局文件

<ListView        android:id="@+id/listView"        android:layout_width="match_parent"        android:layout_height="match_parent"</ListView>

2.Item的布局文件:item.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:id="@+id/textView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="20sp"        android:text="您好!"/></RelativeLayout>

3.Adapter

package com.fly.adapter;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.List;/** * Created by fly on 2016/10/9. */public class MyAdapter extends BaseAdapter {    private Context context;    private LayoutInflater inflater;    private List<String> list;    public MyAdapter(Context context, List<String> list) {        this.context = context;        this.list = list;        inflater = LayoutInflater.from(context);    }    @Override    public int getCount() {        return list.size();    }    @Override    public String getItem(int position) {        return list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;        if (convertView == null) {            convertView = inflater.inflate(R.layout.item, parent);            holder = new ViewHolder();            holder.textView = (TextView) convertView.findViewById(R.id.textView);            convertView.setTag(holder);        } else {            holder = (ViewHolder) convertView.getTag();        }        holder.textView.setText(list.get(position));        return convertView;    }    private class ViewHolder {        TextView textView;    }}

相信大家对以上的写法并不陌生,估计有的人都已经写的要吐血了。下面给大家介绍一种通用的适配器。下面我们来总结一下写适配器的所需要的步骤:
1、现在主布局中添加一个ListView的控件;
2、编写一个Item的布局文件;
3、声明一个类继承BaseAdapter,并重写所需要重写的方法;
4、写一个ViewHoler的内部类,里面声明Item中的控件;当是第一次调用该适配器时存储控件,之后直接调用ViewHolder里面声明的控件,用来提高效率。
5、通过getView()方法来实现所需要的功能。
通过总结我们发现上面步骤中1~4完全相同,那么我们的问题来了:能不能将之前的第三步和第四步完全封装到一个类中,以方便我们使用呢?
答案当然是可以的,要不然我怎么接着往下写呢!

首先我们来换个思路,每一个适配器中都需要有一个ViewHolder,那么我们干脆写一个ViewHolder用来放置所有的控件。要放置很多个控件我们可以用到集合和数组,我们还需要通过特定的条件来找到该控件,不然我们怎么用。因此我们可以使用到Map集合来存储各种控件,通过控件的id来获取。有一个SparseArray是对Map集合的封装,是key为Integer的Map集合。因为我们所使用的控件的id都是int类型,所以可以使用该集合。
1、通用的ViewHolder

package com.fly.adapter;import android.content.Context;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;/** * Created by fly on 2016/10/9. */public class CommonViewHolder {    //key是Integer类型的Map集合    private SparseArray<View> mViews;    private View convertView;    private CommonViewHolder(Context context, ViewGroup parent, int layoutId, int position) {        //初始化        mViews = new SparseArray<>();        //加载视图        convertView = LayoutInflater.from(context).inflate(layoutId, parent,false);        convertView.setTag(this);    }    //CommonViewHolder的入口方法    public static CommonViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) {        if (convertView == null) {            return new CommonViewHolder(context, parent, layoutId, position);        }        return (CommonViewHolder) convertView.getTag();    }    //这里是获取各种view    public <T extends View> T getView(int viewId){        View view = mViews.get(viewId);        if (view == null) {            view = convertView.findViewById(viewId);            mViews.put(viewId,view);        }        return (T) view;    }    //获取convertView    public View getConvertView(){        return convertView;    }}

写完ViewHolder之后,可以在适配器中使用了,下面是之后的Adapter的代码:

package com.fly.adapter;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.List;/** * Created by fly on 2016/10/9. */public abstract class CommonAdapter<T> extends BaseAdapter {    protected Context context;    protected List<T> list;    protected LayoutInflater inflater;    protected int itemLayoutId;    public CommonAdapter(Context context, List<T> list, int itemLayoutId) {        this.context = context;        this.list = list;        inflater.from(context);        this.itemLayoutId = itemLayoutId;    }    @Override    public int getCount() {        return list.size();    }    @Override    public T getItem(int position) {        return list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        //获取CommonViewHolder        CommonViewHolder holder = getCommonViewHolder(position, convertView, parent);        //通过getView()获取控件        TextView textView = holder.getView(R.id.textView);        textView.setText(getItem(position).toString());        return holder.getConvertView();    }}

上面的代码可以根据需要传入不同的Java bean或者是类型,就不一一实现了。
下面开始写通用的适配器:
首先我们来分析一下写适配器的步骤:
1、传入一个Context对象;
2、传入一个LayoutInflater对象
3、传入一个List集合
4、根据需求在getView方法中写需求
这样的话我们其实是可以将getView方法提取出来,让其子类去实现该方法。这样的话代码就可以改成这样了:

package com.fly.adapter;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.List;/** * Created by lihb on 2016/10/9. */public abstract class CommonAdapter<T> extends BaseAdapter {    protected Context context;    protected List<T> list;    protected LayoutInflater inflater;    protected int itemLayoutId;    public CommonAdapter(Context context, List<T> list, int itemLayoutId) {        this.context = context;        this.list = list;        inflater.from(context);        this.itemLayoutId = itemLayoutId;    }    @Override    public int getCount() {        return list.size();    }    @Override    public T getItem(int position) {        return list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public abstract View getView(int position, View convertView, ViewGroup parent);}
package com.fly.picasso;import android.content.Context;import android.widget.TextView;import java.util.List;/** * Created by fly on 2016/9/30. */public class MyAdapter extends CommonAdapter {    public MyAdapter(Context context, List list, int itemLayoutId) {        super(context, list, itemLayoutId);    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        //获取CommonViewHolder        CommonViewHolder holder = getCommonViewHolder(position, convertView, parent);        //通过getView()获取控件        TextView textView = holder.getView(R.id.textView);        textView.setText(getItem(position).toString());        return holder.getConvertView();    }}

这样的话一个简单的通用适配器就完成了。

0 0