码迷,mamicode.com
首页 > 其他好文 > 详细

RecyclerView使用

时间:2015-05-29 23:21:37      阅读:1032      评论:0      收藏:0      [点我收藏+]

标签:android   listview   recyclerview   

RecyclerView是android5.0提供的新组件(最新的support.v7中也提供了该组件),类似于ListView,但是比ListView更灵活、更先进,我觉得主要表现在以下几个方面:

1、  把ViewHolder的实现封装起来,规范了ViewHolder,把item的view写入ViewHolder中,通过复用ViewHolder来实现view的复用。

2、  RecyclerView.Adapter中把view的回收和内容改变等操作分开解耦了,比传统的Adapter更为灵活。

3、  独立的LayoutManager,可以灵活的控制RecyclerView中items的布局:LinearLayoutManager(垂直布局、水平布局)、GridLayoutManager(网格布局)、StaggeredGridLayoutManager(瀑布流布局);

4、  提供了RecyclerView.ItemAnimator可以设置items增加、删除时的动画(默认已有定义了动画);

 

下面通过官方例子来看一下RecyclerView的使用。

1、  布局文件xml的编写,没什么好说的。

<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

2、在activity中使用RecyclerView

public class MyActivity extends Activity {
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
    }
    ...
}

代码很简单,看一下我们使用到RecyclerView的几个地方:首先是mRecyclerView.setHasFixedSize(true),从上面的注释可以知道,如果item的内容不改变view布局大小,那使用这个设置可以提高RecyclerView的效率。接着再看mLayoutManager = new LinearLayoutManager(this);mRecyclerView.setLayoutManager(mLayoutManager),这里就使用LayoutManager来控制item的排列方式,这里用的是LinearLayoutManager,也就是线性布局,默认是垂直布局,如果要设置成水平布局,只需在把new LinearLayoutManager(this)改成newLinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false)就可以了,最后一项如果为true的话,item会反向排列。

3、编写Adapter

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private String[] mDataset;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ViewHolder(TextView v) {
            super(v);
            mTextView = v;
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                               .inflate(R.layout.my_text_view, parent, false);
        // set the view's size, margins, paddings and layout parameters
        ...
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.mTextView.setText(mDataset[position]);

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}

首先看一下ViewHolder,这里不再是自己随便定义的ViewHolder了,而是继承了RecyclerView.ViewHolder,规范了ViewHolder。不同于传统的Adapter,这里没有getView,取而代之的是onCreateViewHolder和onBindViewHolder,把view的复用和数据的绑定解耦开了。

 

上面就是官方的简单例子,接下来我们来实现两个比较常用的功能,item的点击和上拉加载。

 

RecyclerView并没有提供item的点击事件,这也让我们有了多种实现方式,不管什么方式,归根到底就是对view的点击事件。我们可以在Adapter中添加对view的点击事件,有两个地方可以添加,大家看哪种方法更好。


1、  在ViewHolder中添加。

public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ViewHolder(TextView v) {
            super(v);
            mTextView = v;
			v. setOnClickListener….
        }
    }



2、  在onBindViewHolder中添加。

@Override
   public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.mTextView.setText(mDataset[position]);
		holder.itemView.setOnClickListener…;
    }



再来看看上拉加载更多,我觉得最好的方法就是在onBindViewHolder添加对上拉加载事件的判断,因为如果用传统的监听scroll的方法来做的话,那么如果我改变了LayoutManager,从垂直线性布局改成水平线性布局,或者从线性布局改成网格布局,那么对scroll监听的方法又得重新写了。下面看下具体的写法。

@Override
    public void onBindViewHolder(ViewHolder holder, int position) {
       if (position == list.size() - 1&&onLoadListener!=null&&(list.size()%limit)==0) {
        onLoadListener.load();
        Log.i("zhuang","触发");
      }
    }

如果当前绑定的ViewHolder的position是最后一项,则触发加载更多。这里的onLoadListener是我自定义加载接口

public interface OnLoadListener {
    public void load();
}

在Adapter中定义OnLoadListener变量,然后生成get和set方法,我们在activity中可以通过adapter.setOnLoadListener来为加载更多设置加载的具体实现。(list.size()%limit)==0)中的limit是每次加载的item数量,如果list.size()%limit)==0,表示每次从服务器加载的item数和我们请求的item数是一样的,证明还有其他记录,再次把list拉到最后面的item时,我们可以继续触发load方法,如果list.size()%limit)!=0,则说明我们从服务器加载过来的item数和我们请求的item数不一样,那么证明数据已经全部都加载完了,没必要再次请求了,就算list拉到最后一项,也不再请求。当然还有一种情况就是加载的数据数和我们请求的数据数是一样的,而刚好也请求完所有数据,这时候我们上拉到最后一项时,还会再触发一次加载。

下面贴上稍微完整的代码

OnLoadListener:

public interface OnLoadListener {
    public void load();
}

MyActivity

public class MyActivity extends Activity {
        private RecyclerView mRecyclerView;
        private RecyclerView.Adapter mAdapter;
        private RecyclerView.LayoutManager mLayoutManager;
        private String[] myDataset = {...};
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.my_activity);
            mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

            // use this setting to improve performance if you know that changes
            // in content do not change the layout size of the RecyclerView
            mRecyclerView.setHasFixedSize(true);

            // use a linear layout manager
            mLayoutManager = new LinearLayoutManager(this);
            mRecyclerView.setLayoutManager(mLayoutManager);

            // specify an adapter (see also next example)
            mAdapter = new MyAdapter(myDataset,limit);
            mAdapter.setOnLoadListener(new OnLoadListener() {
                @Override
                public void load() {
                    ...
                }
            });
            mRecyclerView.setAdapter(mAdapter);
            
        }
        ...
    }

MyAdapter:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
        private String[] mDataset;
        private OnLoadListener onLoadListener;
        private int limit;

        // Provide a reference to the views for each data item
        // Complex data items may need more than one view per item, and
        // you provide access to all the views for a data item in a view holder
        public static class ViewHolder extends RecyclerView.ViewHolder {
            // each data item is just a string in this case
            public TextView mTextView;
            public ViewHolder(TextView v) {
                super(v);
                mTextView = v;
            }
        }

        // Provide a suitable constructor (depends on the kind of dataset)
        public MyAdapter(String[] myDataset,int limit) {
            this.mDataset = myDataset;
            this.limit = limit;
        }

        // Create new views (invoked by the layout manager)
        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                       int viewType) {
            // create a new view
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.my_text_view, parent, false);
            // set the view's size, margins, paddings and layout parameters
            ...
            ViewHolder vh = new ViewHolder(v);
            return vh;
        }

        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            // - get element from your dataset at this position
            // - replace the contents of the view with that element
            holder.mTextView.setText(mDataset[position]);
            holder.itemView.setOnClickListener(...);
            if (position == list.size() - 1&&onLoadListener!=null&&(list.size()%limit)==0) {
                onLoadListener.load();
                Log.i("zhuang","触发");
            }


        }

        // Return the size of your dataset (invoked by the layout manager)
        @Override
        public int getItemCount() {
            return mDataset.length;
        }
    }








RecyclerView使用

标签:android   listview   recyclerview   

原文地址:http://blog.csdn.net/weihuangcool/article/details/46238063

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!