查看原文
其他

教你打造一个万能的适配器

2017-02-24 androidstarjack 终端研发部

androidstarjack的博客地址:

http://blog.csdn.net/androidstarjack/article/details/56841473

最近项目中 经常用listView和GridView ,可以说是项目中Listview GridView几乎是必用的组件,Android也提供一套机制,为这些控件绑定数据,那就是Adapter 最近抽了时间,自己也打造了一个万能的适配器

看我们之前的一些写法:

public class BillAdapter extends BaseAdapter{ List<BillVo> newsList; Activity activity; LayoutInflater inflater = null; public BillAdapter(Activity activity, List<BillVo> newsList) { this.activity = activity; this.newsList = newsList; inflater = LayoutInflater.from(activity); } @Override public int getCount() { return newsList == null ? 0 : newsList.size(); } @Override public Object getItem(int position) { if (newsList != null && newsList.size() != 0) { return newsList.get(position); } return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { BillVo item = newsList.get(position); ViewHolder holder = ViewHolder.get(parent, convertView, R.layout.item_bill, position); if(item.getScore().contains("-")){ holder.setText(R.id.jia_bill_money, item.getScore()); holder.getView(R.id.jian_bill_money).setVisibility(View.INVISIBLE); holder.getView(R.id.jia_bill_money).setVisibility(View.VISIBLE); }else{ holder.setText(R.id.jian_bill_money, "+" + item.getScore()); holder.getView(R.id.jian_bill_money).setVisibility(View.VISIBLE); holder.getView(R.id.jia_bill_money).setVisibility(View.INVISIBLE); } holder.setText(R.id.bill_name, item.getSource()); holder.setText(R.id.bill_time, Util.timeStampDate(item.getCreatetime(), "yyyy-MM-dd")); return holder.getConvertView(); } }

这样用起来虽然还不错,但每次都需要去继承一个BaseAdapter,然后实现里面的一大堆方法,而我们每次最关心的无非就是getView方法,其余的方法几乎都是相同代码。这里是不是就可以优化起来呢?在其次,我们在使用Adapter的时候,为了优化性能,常常会创建一个Holder。而Holder里面每次存放的都是View,对Holer的操作无非也就是初始化,绑定数据,复用。这里是不是也可以抽取抽取? 如果我们封装后:

/** * 类功能描述:</br> *v Viewholder * @author yuyahao * @version 1.0 </p> 修改时间:</br> 修改备注:</br> */public class VolTeamAdapter extends CommonAdapter<Bean> {    private Context context;    public VolTeamAdapter(Context context, List<Bean> listDatas,   int layoutId) {        super(context, listDatas, layoutId);    }    @Override    protected void fillData(ViewHolder holder, int position) {        TextView actNum = holder.getView(R.id.team_item_active_num);        TextView time = holder.getView(R.id.team_item_time);        TextView title = holder.getView(R.id.team_item_title);        ImageView icon = holder.getView(R.id.team_item_icon);        Bean item = listDatas.get(position);        actNum.setText(String.valueOf(item.getActiveSum()) + "个");        time.setText(String.valueOf(item.getTimeSun()) + "h");        title.setText(item.getName());        GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);    } }

这样是不是简单多了。每次 写adapter都可以这样用。

第一步:构造 BaseAdapter

** * 类功能描述:</br> *v 使用 * @author yuyahao * @version 1.0 </p> 修改时间:</br> 修改备注:</br> */ public class VolTeamAdapter extends CommonAdapter<Bean> {    private Context context;    public VolTeamAdapter(Context context, List<Bean> listDatas,   int layoutId) {        super(context, listDatas, layoutId);        this.context = context;    }    @Override    protected void fillData(ViewHolder holder, int position) {        TextView actNum = holder.getView(R.id.team_item_active_num);        TextView time = holder.getView(R.id.team_item_time);        TextView title = holder.getView(R.id.team_item_title);        ImageView icon = holder.getView(R.id.team_item_icon);        Bean item = listDatas.get(position);        actNum.setText(String.valueOf(item.getActiveSum()) + "个");        time.setText(String.valueOf(item.getTimeSun()) + "h");        title.setText(item.getName());        GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);    } }

好了,别卖关子了,直接上全部代码。

/** * 类功能描述:</br> *v Viewholder * @author yuyahao * @version 1.0 </p> 修改时间:</br> 修改备注:</br> */public abstract class CommonAdapter<T> extends BaseAdapter {    /*** 上下文的Context*/    protected Context mContext;    /*** list的数据*/    protected List<T> listDatas;    /** Item布局ID*/    protected int layoutId;    public CommonAdapter(Context context, List<T> listDatas, int layoutId) {        this.mContext = context;        this.listDatas = listDatas;        this.layoutId = layoutId;    }    @Override    public int getCount() {        return listDatas == null ? 0 : listDatas.size();    }/** * 获取当前点击的Item的数据时用 * 在onItemClick中 parent.getAdapter().getItem(),获取当前点击的Item的数据 */    @Override    public Object getItem(int position) {        return listDatas.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    /**     *加载每一个Item,该方法是最关键的     */@   Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = ViewHolder.getViewHolder(mContext, convertView,  parent, layoutId, position);        fillData(holder, position);        return holder.getMConvertView();    }    /**     *     * 抽象方法,用于子类实现,填充数据     * @param holder     * @param position     */    protected abstract void fillData(ViewHolder holder, int position); }

第二步Holer的通用化

/** * 类功能描述:</br> *v Viewholder * @author yuyahao * @version 1.0 </p> 修改时间:</br> 修改备注:</br> */ public class ViewHolder {    private  int mPosition;    /**     * View容器,用于存放Holer中的View     * 据网上说是 SparseArray是这样的     * SparseArray 是Android推荐使用的一个优化容器,相当于一个Map<integer,View>     */    private SparseArray<View> mViews;    /**     * Item布局View convertView     */    private View mConvertView;    public ViewHolder(Context context, ViewGroup parent, int layoutId) {        mViews = new SparseArray<View>();        mConvertView = LayoutInflater.from(context).inflate(layoutId, null);        mConvertView.setTag(this);    }    /**     * 获取ViewHolder     * @param context     *  上下文     * @param convertView     * @param parent     * @param layoutId     *            布局layout Id     * @param     * @return     */    public static ViewHolder getViewHolder(Context context, View convertView,  ViewGroup parent, int layoutId) {        if (convertView == null)            return new ViewHolder(context, parent, layoutId);        return (ViewHolder) convertView.getTag();    }    public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {        this.mViews = new SparseArray<View>();        this.mPosition = position;        this.mConvertView = LayoutInflater.from(context).inflate(layoutId,                parent, false);        this.mConvertView.setTag(this);    }    /**     * 拿到一个ViewHolder对象     * @param context     * @param convertView     * @param parent     * @param layoutId     * @param position     * @return     */    public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutId, int position) {        if (null == convertView) {            return new ViewHolder(context, parent, layoutId, position);        } else {            ViewHolder holder = (ViewHolder) convertView.getTag();            holder.mPosition = position;            return holder;        }    }    /**     * 获取Holder中的ItemView     * @param viewId     * @return     */    @SuppressWarnings("unchecked")    public <T extends View> T getView(int viewId) {        View item = mViews.get(viewId);        if (item == null) {            item = mConvertView.findViewById(viewId);            mViews.put(viewId, item);        }        return (T) item;    }    /** * 获取convertView***/    public View getMConvertView() {        return mConvertView;    } }

这样已经写完。

第三步使用

/** * 类功能描述:</br> *v 使用 * @author yuyahao * @version 1.0 </p> 修改时间:</br> 修改备注:</br> */public class VolTeamAdapter extends CommonAdapter<Bean> {    private Context context;    public VolTeamAdapter(Context context, List<Bean> listDatas,   int layoutId) {        super(context, listDatas, layoutId);        this.context = context;    }    @Override    protected void fillData(ViewHolder holder, int position) {        TextView actNum = holder.getView(R.id.team_item_active_num);        TextView time = holder.getView(R.id.team_item_time);        TextView title = holder.getView(R.id.team_item_title);        ImageView icon = holder.getView(R.id.team_item_icon);        Bean item = listDatas.get(position);        actNum.setText(String.valueOf(item.getActiveSum()) + "");        time.setText(String.valueOf(item.getTimeSun()) + "");        title.setText(item.getName());        GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title);    } }

mainActivity:

public class MyTextActivity extends BaseActivity{    private Context cnt;    @Bind(R.id.lv_list)    ListView  lv_list;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        addViewFillInRoot(R.layout.ctivity_mytext);        ButterKnife.bind(this);        cnt = this;        initView();    }    private void initView() {        try {            List<Bean>  list = DataTest.getMyTestList();            VolTeamAdapter volTeamAdapter = new VolTeamAdapter(cnt,list,R.layout.my_listr);            lv_list.setAdapter(volTeamAdapter);        } catch (Exception e) {            e.printStackTrace();        }    } }

xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal" android:layout_width="match_parent"    android:gravity="center_vertical"    android:layout_height="match_parent">    <ImageView        android:layout_width="@dimen/dp80"        android:layout_height="@dimen/dp80"        android:background="@drawable/default_head"        android:scaleType="fitXY"        android:id="@+id/team_item_icon"/>    <LinearLayout        android:layout_width="match_parent"        android:layout_marginLeft="@dimen/dp10"        android:orientation="vertical"        android:layout_height="@dimen/dp80">        <TextView            android:layout_width="match_parent"            android:layout_height="match_parent"            android:id="@+id/team_item_title"            android:gravity="center_vertical"            android:layout_weight="1"            android:text="卡卡罗特"/>        <LinearLayout            android:layout_width="match_parent"            android:layout_weight="1"            android:layout_height="match_parent"            android:gravity="center_vertical">            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="天不排名"                android:id="@+id/team_item_time"/>            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginLeft="@dimen/dp20"                android:text="战斗值: "                android:id="@+id/team_item_active_num"/>        </LinearLayout>    </LinearLayout></LinearLayout>

效果图:

相信自己,没有做不到的,只有想不到的

如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809 微信公众号:终端研发部

(欢迎关注学习和交流)


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存