标题: 商城开发笔记-04-RecycleView的基本使用 [打印本页]

作者: 51黑bing    时间: 2016-3-22 17:18
标题: 商城开发笔记-04-RecycleView的基本使用
一、RecycleView的简介


       RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相
似的渲染方式。该控件用于在有限的窗口中展示大量数据集,它被作为ListViewGridView控件的继承者。
       那么有了ListViewGridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManagerItemDecoration, ItemAnimator实现令人瞠目的效果。


二、RecycleView的基本使用
1、在Gradle中引入RecycleView的依赖库。
compile 'com.android.support:recyclerview-v7:23.1.1'
2、在布局文件当中放置我们的RecycleView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>
3、创建适配器类继承RecycleViewAdapter,步骤为:
代码如下:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    List<String> mDatas = null;
    Context mContext = null;
    //通过构造函数把要显示的数据读取进来
    public MyAdapter(List<String> mDatas, Context context) {
        this.mDatas = mDatas;
        this.mContext = context;
    }
    //相当于ListView中的getView()方法
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//      View v = View.inflate(mContext,R.layout.item, null);
        LayoutInflater inflater = LayoutInflater.from(mContext);
        //加载布局的时候需要注意要把parent传进去
        View v = inflater.inflate(R.layout.layout_item, parent, false);
        MyViewHolder holder = new MyViewHolder(v);
        return holder;
    }
    //在这里需要设置显示的数据
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.tv_num.setText(mDatas.get(position));
    }
    @Override
    public int getItemCount() {
        return mDatas.size();
    }
    //自定义ViewHolder必须继承RecyclerView.ViewHolder,在构造函数中进行ID绑定控件,条目监听等
    class MyViewHolder extendsRecyclerView.ViewHolder {
        TextView tv_num;
        public MyViewHolder(final View itemView) {
            super(itemView);
            tv_num = (TextView) itemView.findViewById(R.id.tv_num);
            tv_num.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (onItemClickListener != null) {
                        onItemClickListener.onItemClick(itemView, getLayoutPosition(), mDatas.get(getLayoutPosition()));
                    }
                }
            });
        }
    }
    //自定义监听
    private OnItemClickListener onItemClickListener;
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.onItemClickListener = listener;
    }
    public interface OnItemClickListener {
        void onItemClick(View v, int position, String data);
    }
    public void addData(int position, String data) {
        mDatas.add(position, data);
        notifyItemInserted(position);
    }
    public void removeData(int position) {
        mDatas.remove(position);
        notifyItemRemoved(position);
    }
}

4、下面是MainActivity中需要进行的处理。核心的步骤(某些步骤可不分先后)如下:
代码如下:
public class MainActivity extendsAppCompatActivity {
    List<String> datas = null;
    private RecyclerView recyclerView;
    private MyAdapter myAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        recyclerView = (RecyclerView) findViewById(R.id.recycle);
        //设置RecycleView的适配器
        myAdapter = new MyAdapter(datas, this);
        recyclerView.setAdapter(myAdapter);
        //设置布局管理器,以渲染出不同的效果
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //设置插入、删除数据的动画效果(这里使用默认的动画)
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        //设置每个Item之间的装饰(这里设置为分隔线)
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
        //设置条目监听,需要自定义接口
        myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View v, int position, String data) {
                Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
            }
        });
    }
    private void initData() {
        datas = new ArrayList<>();
        for (int i = 0; i < 300; i++) {
            datas.add(i + "");
        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_add:
                myAdapter.addData(0, "new data");
                recyclerView.scrollToPosition(0);
                break;
            case R.id.action_delete:
                myAdapter.removeData(0);
                break;
            case R.id.action_gridview:
                recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
                break;
            case R.id.action_listview:
                recyclerView.setLayoutManager(new LinearLayoutManager(this));
                break;
            case R.id.action_staggeredgridview:
                recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,
                       StaggeredGridLayoutManager.VERTICAL));
                break;
        }
        return true;
    }
}


三、运行效果
                                

先上图三张,具体的一些动画效果需要自己体会。

对啦,notifyDataSetChanged方法以及弃用了,请注意RecycleView的新规矩:
notifyDataSetChanged()弃用
notifyItemChanged(intposition)
notifyItemInserted(intposition)
notifyItemMoved(intfromPosition, int toPosition)
notifyItemRemoved(intposition)
//range系列,多个item的操作
notifyItemRangeChanged(intpositionStart, int itemCount)
notifyItemRangeInserted(intpositionStart, int itemCount)
notifyItemRangeRemoved(intpositionStart, int itemCount)

补充:可以通过AdaptergetViewType(intposition)方法实现多种不同的条目。
具体做法是根据position的不同例如奇数偶数,或者特定值,然后根据viewType参数的不同去inflate不同的item布局即可。
如下图所示:
   







欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1