打造AbsListView、RecyclerView的通用Adapter

该库用于简化AbsListView类型与RecyclerView的Adapter构建,在ListViewAdapter和RecyclerAdapter封装了固定的业务逻辑,使得用户只需要实现变化的部分即可,简化代码,避免重复的模板代码。

该库的接口参考了base-adapter-helper,在此基础上添加了RecyclerView Adapter的支持。两种类型的Adapter之间通过桥接模式简化代码,参考ViewHolderImpl

例如,我们要实现一个适用于AbsListView的Adapter时,通常代码如下:

/**
 * Created by mrsimple on 28/9/15.
 */
public class FeedAdapter extends BaseAdapter {
    /**
     * 数据集
     */
    protected List<String> mDataSet = new ArrayList<String>();

    public FeedAdapter(List<String> datas) {
        mDataSet = datas;
    }

    @Override
    public String getItem(int position) {
        return mDataSet.get(position);
    }

    @Override
    public int getCount() {
        return mDataSet.size();
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        FeedViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_type_1, parent, false);
            viewHolder = new FeedViewHolder(convertView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (FeedViewHolder) convertView.getTag();
        }
        // 设置数据
        viewHolder.textView.setText( getItem(position));
        return convertView;
    }

    /**
     * Feed ViewHolder
     */
    public static class FeedViewHolder {
        public ImageView imageView;
        public TextView textView;

        public FeedViewHolder(View itemView) {
            imageView = (ImageView) itemView.findViewById(R.id.imageview);
            textView = (TextView) itemView.findViewById(R.id.textview);
        }
    }
}

当Adapter的数量有几个时,就会反复编写getCount、getItem、getView等函数,但是它们的实现都是非常类似的,反复编写这类代码会使得代码重复率很高。Common Adapter对这些逻辑进行了二次封装,使得用户可以更方便的构建Adapter类,示例如下:

添加Gradle依赖

在项目的build.gradle中添加上如下依赖:

dependencies {
    // 其他依赖

    // Common Adapter的依赖
    compile 'org.simple:adapter:1.0.0'
}

1、使用代码

    /**
     * 初始化ListView
     */
    private void initListView() {
        ListView listView = (ListView) findViewById(R.id.listview);
        final ListViewAdapter<String> adapter = new ListViewAdapter<String>(R.layout.list_item_type_1) {
            @Override
            protected void onBindData(GodViewHolder viewHolder, int position, String item) {

                viewHolder
                        .setText(R.id.textview, item)             // 设置文本内容
                        .setImageResource(R.id.imageview, R.drawable.big_smile) ; // 设置图片资源
            }
        };
        // 添加数据
        adapter.addItems(mockDatas());
        listView.setAdapter(adapter);
        // 设置ListView的点击事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(MainActivity.this, "Click List : " + adapter.getItem(position), Toast.LENGTH_SHORT).show();
            }
        });
    }

针对于AbsListView类族的组件需要使用ListViewAdapter类型的Adapter,泛型参数就是单个实体类的数据类型。在构造ListViewAdapter对象时覆写onBindData函数完成数据的绑定即可。GodViewHolder中包含了各类View属性的设置,具体请直接查看GodViewHolder中的setter函数。

对于RecyclerView则需要使用RecyclerAdapter,使用方式与ListViewAdapter类似,示例代码如下所示。

    /**
     * 初始化RecyclerView
     */
    private void initRecyclerView() {
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        // 线性
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

        // 初始化adapter
        final RecyclerAdapter<String> adapter = new RecyclerAdapter<String>(R.layout.list_item_type_1, mockDatas()) {
            @Override
            protected void onBindData(RecyclerViewHolder viewHolder, int position, String item) {
                viewHolder.setText(R.id.textview, item);
                ImageView imageView = viewHolder.findViewById(R.id.imageview);
                Glide
                        .with(viewHolder.getContext())
                        .load("http://img4.duitang.com/uploads/blog/201402/19/20140219232639_Cda2j.thumb.600_0.jpeg")
                        .into(imageView);
            }

            // 如果有多个布局,那么覆写getItemViewType与getItemLayout即可
            @Override
            public int getItemViewType(int position) {
                return position % 5 == 0 ? 2 : 1;
            }

            @Override
            protected int getItemLayout(int type) {
                if (type == 2) {
                    return R.layout.list_item_type_2;
                }
                return R.layout.list_item_type_1;
            }
        };

        // 设置RecyclerView的点击事件
        adapter.setOnItemClickListener(new RecyclerAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                Toast.makeText(MainActivity.this, "Click Recycler : "
                        + adapter.getItem(position), Toast.LENGTH_SHORT).show();
            }
        });
        recyclerView.setAdapter(adapter);
    }

在使用Common Adapter时不需要担心数据源发生改变导致列表数据不更新的问题,因为Adapter基类中将数据集设置为final,所有的数据都会添加到该数据集中;在增加、减少数据时也不需要调用notifyDataSetChanged,只需要调用Adapter对应的的addItem或者remove函数即可。

2、效果

Github地址

AndroidCommonAdapter地址

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值