RecycleView使用体验(一)

来源:互联网 发布:如何免费创建企业域名 编辑:程序博客网 时间:2024/05/16 12:34

RecycleView替代ListView势在必行,网上有关于RecycleView介绍的博客有很多,现在我把我最近使用它的一些体会和它的一些使用用法总结如下:

一、ListView只有一个notifyDataSetChanged()一个方法,而RecycleView却有很多执行不同场景的方法

<span style="white-space:pre"></span>public final void notifyDataSetChanged()        public final void notifyItemChanged(int position)        public final void notifyItemRangeChanged(int positionStart, int itemCount)        public final void notifyItemInserted(int position)         public final void notifyItemMoved(int fromPosition, int toPosition)        public final void notifyItemRangeInserted(int positionStart, int itemCount)        public final void notifyItemRemoved(int position)        public final void notifyItemRangeRemoved(int positionStart, int itemCount) 
现对这几个方法的使用总结如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:fitsSystemWindows="true"    tools:context=".MainActivity">    <android.support.design.widget.AppBarLayout        android:layout_height="wrap_content"        android:layout_width="match_parent"        android:theme="@style/AppTheme.AppBarOverlay">        <android.support.v7.widget.Toolbar            android:id="@+id/toolbar"            android:layout_width="match_parent"            android:layout_height="?attr/actionBarSize"            android:background="?attr/colorPrimary"            app:popupTheme="@style/AppTheme.PopupOverlay"/>    </android.support.design.widget.AppBarLayout>    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:orientation="vertical">        <LinearLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:orientation="horizontal">            <Button                android:id="@+id/ItemChanged"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="1"/>            <Button                android:id="@+id/ItemRangeChanged"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="2"/>            <Button                android:id="@+id/ItemInserted"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="3"/>        </LinearLayout>        <LinearLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:orientation="horizontal">            <Button                android:id="@+id/ItemMoved"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="4"/>            <Button                android:id="@+id/ItemRangeInserted"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="5"/>            <Button                android:id="@+id/ItemRemoved"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="6"/>            <Button                android:id="@+id/ItemRangeRemoved"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="7"/>        </LinearLayout>    </LinearLayout>    <android.support.v7.widget.RecyclerView        android:id="@+id/rv_news"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:fastScrollAlwaysVisible="true"        android:fastScrollEnabled="true"        android:scrollbarStyle="insideOverlay"        android:scrollbars="vertical"/></LinearLayout>
这是MainActivity的布局文件,每个点击一个button,调用对应的方法,显示不同的结果:

MainActivity中代码如下:

import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.Toolbar;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity implements OnClickListener{    private RecyclerView mRecyclerView;    private List<News> mNewsList;    private NewsAdapter mAdapter;    private Button ItemChanged;    private Button ItemRangeChanged;    private Button ItemInserted;    private Button ItemMoved;    private Button ItemRangeInserted;    private Button ItemRemoved;    private Button ItemRangeRemoved;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);        setSupportActionBar(toolbar);        setupViews();        setupEvent();        setupData();    }    private void setupViews(){        /**         * 设置RecyclerView显示方向         */        mRecyclerView = (RecyclerView) findViewById(R.id.rv_news);        LinearLayoutManager llm = new LinearLayoutManager(this);        llm.setOrientation(LinearLayout.VERTICAL);        mRecyclerView.setLayoutManager(llm);        /**         * RecyclerView增加分隔线         */        DividerItemDecoration divider = new DividerItemDecoration(this,LinearLayoutManager.VERTICAL,                DensityUtil.dip2px(this,12),DensityUtil.dip2px(this,12));        mRecyclerView.addItemDecoration(divider);        ItemChanged = (Button) findViewById(R.id.ItemChanged);        ItemRangeChanged = (Button) findViewById(R.id.ItemRangeChanged);        ItemInserted = (Button) findViewById(R.id.ItemInserted);        ItemMoved = (Button) findViewById(R.id.ItemMoved);        ItemRangeInserted = (Button) findViewById(R.id.ItemRangeInserted);        ItemRemoved = (Button) findViewById(R.id.ItemRemoved);        ItemRangeRemoved = (Button) findViewById(R.id.ItemRangeRemoved);    }    private void setupEvent(){        ItemChanged.setOnClickListener(this);        ItemRangeChanged.setOnClickListener(this);        ItemInserted.setOnClickListener(this);        ItemMoved.setOnClickListener(this);        ItemRangeInserted.setOnClickListener(this);        ItemRemoved.setOnClickListener(this);        ItemRangeRemoved.setOnClickListener(this);    }    private void setupData(){        mNewsList = new ArrayList<News>();        for (int i = 0; i < 20; i++) {            News news = new News();            news.news_title = "title=" + i;            news.news_content = "content=" + i;            mNewsList.add(news);        }        mAdapter = new NewsAdapter(this,mNewsList,mRecyclerView);        mRecyclerView.setAdapter(mAdapter);    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.ItemChanged :                mNewsList.get(2).news_content = "只刷新指定的Item";                /**                 * 只刷新指定的Item                 */                mAdapter.notifyItemChanged(2);                break;            case R.id.ItemRangeChanged :                mNewsList.get(3).news_content = "刷新指定范围的Item";                mNewsList.get(4).news_content = "刷新指定范围的Item";                mNewsList.get(5).news_content = "刷新指定范围的Item";                /**                 * 刷新指定范围的Item                 * 第一个参数:从什么位置开始(下标从0开始)                 * 第二个参数:刷新多少个Item                 */                mAdapter.notifyItemRangeChanged(3,3);                break;            case R.id.ItemInserted :                /**                 * 当插入的时候,需要数据有新增;                 * 当指定插入的位置的时候,插入的数据需要在数据列表中相同的位置                 * 例如:下面就新增了一个News对象,如果需要将其插入到第三个item,                 * 则需要将新增的News放入mNewsList的第三个位置,然后notifyItemInserted(2)即可                 */                News news = new News();                news.news_title = "title=ItemInserted";                news.news_content = "content=ItemInserted";                mNewsList.add(news);                mAdapter.notifyItemInserted(mNewsList.size() - 1);                /**                 * 滑动到最底部                 */                mRecyclerView.scrollToPosition(mNewsList.size() - 1);                break;            case R.id.ItemMoved :                mAdapter.notifyItemMoved(0,3);                break;            case R.id.ItemRangeInserted :                /**                 * 某个范围插入,原理和ItemInsert相同                 * 第一个参数:从什么位置开始插入                 * 第二个参数:插入多少条数据                 */                for (int i = 0; i < 3; i++) {                    News n = new News();                    n.news_title = "title=ItemRangeInserted" + i;                    n.news_content = "content=ItemRangeInserted" + i;                    mNewsList.add(n);                }                mAdapter.notifyItemRangeChanged(mNewsList.size() - 1, 3);                mRecyclerView.scrollToPosition(mNewsList.size() - 1);                break;            case R.id.ItemRemoved :                /**                 * 移除第四个item                 */                mAdapter.notifyItemRemoved(3);                break;            case R.id.ItemRangeRemoved :                /**                 * 从第一个item开始,移除3item                 */                mAdapter.notifyItemRangeRemoved(0,3);                break;        }    }}


public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder>{    private Context mContext;    private List<News> mNewsList;    private RecyclerView mRecyclerView;    public NewsAdapter(Context context, List<News> newsList, RecyclerView mRecyclerView) {        this.mContext = context;        this.mNewsList = newsList;        this.mRecyclerView = mRecyclerView;    }    @Override    public NewsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = LayoutInflater.from(mContext).inflate(R.layout.item_news, parent, false);        //view.setOnClickListener(this);        return new NewsViewHolder(view);    }    @Override    public void onBindViewHolder(NewsViewHolder holder, int position) {        holder.news_title.setText(mNewsList.get(position).news_title);        holder.news_content.setText(mNewsList.get(position).news_content);    }    @Override    public int getItemCount() {        return mNewsList == null ? 0 : mNewsList.size();    }    class NewsViewHolder extends RecyclerView.ViewHolder{        ImageView news_pic;        TextView news_title;        TextView news_content;        LinearLayout news_lay;        public NewsViewHolder(View itemView) {            super(itemView);            news_pic = (ImageView) itemView.findViewById(R.id.news_pic);            news_title = (TextView) itemView.findViewById(R.id.news_title);            news_content = (TextView) itemView.findViewById(R.id.news_content);            news_lay = (LinearLayout) itemView.findViewById(R.id.news_lay);        }    }}

代码上的解释已经很清楚了,可以仔细看下代码上的注释,就不多做详细讲解了。


二、对RecycleView的监听

通过添加OnScrollListener监听

mRecyclerView.addOnScrollListener(new OnScrollListener() {    @Override    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {        super.onScrollStateChanged(recyclerView, newState);        if (newState == RecyclerView.SCROLL_STATE_IDLE) {/**滑动停止**/            Log.d("test", "recyclerView总共的Item个数:" +                    String.valueOf(recyclerView.getLayoutManager().getItemCount() - 1));            Log.d("test", "recyclerView可见的Item个数:" +                    String.valueOf(recyclerView.getChildCount()));            /**             * 监听是否滑动到底部             */            //获取可见的最后一个view            View lastChildView = recyclerView.getChildAt(                    recyclerView.getChildCount() - 1);            //获取可见的最后一个view的位置            int lastChildViewPosition = recyclerView.getChildAdapterPosition(lastChildView);            //判断lastPosition是不是最后一个position            if (lastChildViewPosition == recyclerView.getLayoutManager().getItemCount() - 1) {                Toast.makeText(MainActivity.this, "滑动到底部了", Toast.LENGTH_SHORT).show();            }            /**监听是否滑动到顶部**/            //获取可见的第一个view            View firstVisibleView = recyclerView.getChildAt(0);            //获取可见的第一个view的位置            int firstVisiblePosition = recyclerView.getChildAdapterPosition(firstVisibleView);            if (firstVisiblePosition == 0) {                Toast.makeText(MainActivity.this, "滑动到顶部了", Toast.LENGTH_SHORT).show();            }        } else if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {/**手指还在recycleview**/        } else if (newState == RecyclerView.SCROLL_STATE_SETTLING) {/**手指离开屏幕,单recycleview仍在滚动**/        }    }    /**     * 滑动过程中执行该函数     * @param recyclerView     * @param dx     * @param dy     */    @Override    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {        super.onScrolled(recyclerView, dx, dy);    }});
注意:

recyclerView.getChildCount()只是获取的是可见的item个数

recyclerView.getLayoutManager().getItemCount()获取的是所有的item的个数

recyclerView.getChildAt(int position) 获取某个位置的view

recyclerView.getChildAdapterPosition(View view) 获取某个view的位置


三、为RecycleView添加OnItemClickListener

我们发现,当用RecycleView来实现GridView的功能的时候,缺少点击某个Item的监听,因此可根据实际需求写个接口来监听Item的点击事件。

public class RecycleViewItemClickListener {    private OnItemClickListener mListener;    private static RecycleViewItemClickListener mRecycleViewItemClickListener;    private RecycleViewItemClickListener(){}    public static RecycleViewItemClickListener getInstance(){        if(mRecycleViewItemClickListener == null){            mRecycleViewItemClickListener = new RecycleViewItemClickListener();        }        return mRecycleViewItemClickListener;    }    /**监听接口**/    public interface OnItemClickListener{        void OnItemClick();    }    public void setOnItemClickListener(OnItemClickListener mItemClickListener){        this.mListener = mItemClickListener;    }    public void notifyItemClickListener(){        if(mListener != null){            mListener.OnItemClick();        }    }}
当然,还有最直接的办法,直接在创建ViewHolder类的时候实现OnClickListener接口就可以达到监听每个Item


未完待续,敬请期待第二篇。

0 0
原创粉丝点击