RecyclerView筆記

一. RecyclerView的基礎(chǔ)用法

  1. 添加依賴
compile 'com.android.support:recyclerview-v7:25.2.0'
  1. xml使用布局
<!--下拉刷新控件-->
    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh_linear_recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view_linear"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </android.support.v7.widget.RecyclerView>

    </android.support.v4.widget.SwipeRefreshLayout>
  1. 新建recycler_item的布局(recyclerview中的item的布局,此處的布局是CardView嵌套了ImageView)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardElevation="@dimen/cardview_default_elevation"
    app:cardCornerRadius="@dimen/cardview_default_radius"
    android:layout_margin="8dp">

    <ImageView
        android:id="@+id/iv_meizi"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"/>
</android.support.v7.widget.CardView>
  1. 新建Adapter
public class LinearRecyclerAdapter extends RecyclerView.Adapter<LinearRecyclerAdapter.ViewHolder> {

    private Context mContext;
    private List<Meizi> mMeiziList;

    /*構(gòu)造函數(shù),進(jìn)行初始化(一般傳入context和數(shù)據(jù)列表)*/
    public LinearRecyclerAdapter(Context context,List<Meizi> meiziList) {
        mContext = context;
        mMeiziList = meiziList;
    }

    /*創(chuàng)建ViewHolder*/
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_item_linear_recycler,parent,false);
        return new ViewHolder(view);
    }

    /*數(shù)據(jù)綁定到ViewHolder*/
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Meizi meizi = mMeiziList.get(position);
        Picasso.with(mContext).load(meizi.getImageUrl()).into(holder.mImageView);
    }

    /*item的數(shù)量,一般就是數(shù)據(jù)List的大小*/
    @Override
    public int getItemCount() {
        return mMeiziList.size();
    }

    /*內(nèi)部類ViewHolder*/
    class ViewHolder extends RecyclerView.ViewHolder {
        private ImageView mImageView;
        ViewHolder(View itemView) {
            super(itemView);
            mImageView = (ImageView) itemView.findViewById(R.id.iv_meizi);
        }
    }

    /*添加item的函數(shù)*/
    public void addItem(Meizi meizi, int position) {
        mMeiziList.add(position, meizi);
        notifyItemInserted(position);
    }

    /*滑動(dòng)刪除會(huì)調(diào)用的函數(shù)*/
    public void removeItem(final int position) {
        final Meizi removed=mMeiziList.get(position);
        mMeiziList.remove(position);
        notifyItemRemoved(position);
        Toast.makeText(mContext,"你刪除了第"+position+"個(gè)item",Toast.LENGTH_SHORT).show();
    }
}
  1. 實(shí)例化RecyclerView,設(shè)置布局管理器和Adapter
        mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.recycler_view_linear);//初始化recyclerview
        mLayoutManager = new LinearLayoutManager(getContext());//初始化布局管理器
        mRecyclerView.setLayoutManager(mLayoutManager);//設(shè)置布局管理器
  1. 獲取數(shù)據(jù),封裝到List中,實(shí)例化Adapter,給RecyclerView設(shè)置Adapter

二. 下拉刷新的實(shí)現(xiàn)

  1. 實(shí)例化SwipeRefreshLayout
/*初始化下拉刷新控件*/
mSwipeRefreshLayout = (SwipeRefreshLayout) mRootView.findViewById(R.id.swipe_refresh_linear_recycler);
  1. 下拉刷新監(jiān)聽
        /*swipeRefreshLayout刷新監(jiān)聽*/
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //下拉刷新之后要進(jìn)行的操作,一般是重新加載數(shù)據(jù)
                new GetMeiziTask().execute("http://gank.io/api/data/福利/10/1 ");
            }
        });
  1. 刷新之后記得調(diào)用mSwipeRefreshLayout.setRefreshing(false);取消顯示刷新的按鈕,每次在刷新之前可以調(diào)用mSwipeRefreshLayout.setRefreshing(true);顯示刷新按鈕(一般在AsyncTask的onPreExecute中)

三. 滑動(dòng)刪除和長(zhǎng)按交換位置的實(shí)現(xiàn)

  1. 原理
  • 滑動(dòng)刪除就是監(jiān)聽滑動(dòng)事件,然后在回調(diào)方法中,將數(shù)據(jù)list中的對(duì)應(yīng)元素刪除
  • 長(zhǎng)按交換位置就是長(zhǎng)按事件,然后在回調(diào)方法中,將數(shù)據(jù)list中的對(duì)應(yīng)元素進(jìn)行移動(dòng)
  1. 使用方法
  • 實(shí)例化ItemTouchHelper類,在回調(diào)方法中實(shí)現(xiàn)滑動(dòng)刪除
/*item觸摸助手類,用于實(shí)現(xiàn)滑動(dòng)刪除等操作*/
        mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {

            //用于設(shè)置拖拽和滑動(dòng)的方向
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                int dragFlags=0,swipeFlags=0;
                if(recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager ||recyclerView.getLayoutManager() instanceof GridLayoutManager){
                    //網(wǎng)格式布局有4個(gè)方向
                    dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
                }else if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){
                    //線性式布局有2個(gè)方向
                    dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN;

                    swipeFlags = ItemTouchHelper.START|ItemTouchHelper.END; //設(shè)置側(cè)滑方向?yàn)閺膬蓚€(gè)方向都可以
                }
                return makeMovementFlags(dragFlags,swipeFlags);//swipeFlags 為0的話item不滑動(dòng)
            }

            //長(zhǎng)摁item拖拽時(shí)會(huì)回調(diào)這個(gè)方法
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                /*int from=viewHolder.getAdapterPosition();
                int to=target.getAdapterPosition();
                Meizi moveItem=mMeiziList.get(from);
                mMeiziList.remove(from);
                mMeiziList.add(to,moveItem);//交換數(shù)據(jù)鏈表中數(shù)據(jù)的位置
                mLinearRecyclerAdapter.notifyItemMoved(from,to);//更新適配器中item的位置*/
                int from=viewHolder.getAdapterPosition();
                int to=target.getAdapterPosition();
                Collections.swap(mMeiziList,from,to);
                mLinearRecyclerAdapter.notifyItemMoved(from,to);
                return true;
            }

            /*滑動(dòng)刪除*/
            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                mLinearRecyclerAdapter.removeItem(viewHolder.getAdapterPosition());
            }
        });
  • 將ItemTouchHelper與RecyclerView綁定
mItemTouchHelper.attachToRecyclerView(mRecyclerView);//觸摸事件關(guān)聯(lián)到RecyclerView

四. 簡(jiǎn)單的RecyclerItem動(dòng)畫的實(shí)現(xiàn)

/*設(shè)置item加載或移除時(shí)的動(dòng)畫*/
mRecyclerView.setItemAnimator(new DefaultItemAnimator());

五. item的點(diǎn)擊事件實(shí)現(xiàn)

  1. 在Adapter里面實(shí)現(xiàn)事件監(jiān)聽
  • 在ViewHolder里直接給控件添加監(jiān)聽事件
ViewHolder(View itemView) {
            super(itemView);
            mImageView = (ImageView) itemView.findViewById(R.id.iv_meizi);
            mImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext,"You clicked item "+getAdapterPosition(),Toast.LENGTH_SHORT).show();
                }
            });
        }
  • 在onBindViewHolder方法里給控件添加監(jiān)聽事件
@Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        Meizi meizi = mMeiziList.get(position);
        Picasso.with(mContext).load(meizi.getImageUrl()).into(holder.mImageView);
        /*holder.mImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext,"You clicked item "+holder.getAdapterPosition(),Toast.LENGTH_SHORT).show();
            }
        });*/
    }
  1. 在調(diào)用的地方實(shí)現(xiàn)回調(diào)的監(jiān)聽和處理
  • Adapter實(shí)現(xiàn)回掉接口,在調(diào)用處進(jìn)行調(diào)用

六. 上拉加載

  1. 上拉加載就是先設(shè)置onScrollListener,在listener方法里面進(jìn)行判斷然后加載數(shù)據(jù),加載數(shù)據(jù)的原理是獲取新的數(shù)據(jù)然后添加到List集合中,然后再調(diào)用Adapter的notifyDataSetChanged通知更新數(shù)據(jù)。

七. 四大角色

  1. RecyclerView

RecyclerView就是一個(gè)控件,和普通控件一樣,只不過(guò)他的作用是用來(lái)展示列表,回收和定位屏幕上的view

  1. Adapter

適配器,用來(lái)創(chuàng)建RecyclerView的界面(ViewHolder),加載數(shù)據(jù)到界面上,當(dāng)RecyclerView需要顯示view時(shí),就會(huì)去找它的adapter。具體過(guò)程如下:

  • 調(diào)用adapter的getIemCount()方法,詢問(wèn)列表對(duì)象的總個(gè)數(shù)
  • 調(diào)用adapter的createViewHolder()方法,創(chuàng)建ViewHolder和要顯示的視圖
  • 傳入ViewHolder和要加載的視圖位置,調(diào)用adapter的onBindViewHolder()方法,為視圖綁定數(shù)據(jù)
    每當(dāng)需要加載一個(gè)item的時(shí)候就會(huì)調(diào)用以上方法,直到需要加載的item都加載完成
  1. LayoutManager

用來(lái)定義RecyclerView的顯示規(guī)則(如定位列表項(xiàng),定義屏幕的滾動(dòng)行為等),正因?yàn)橛蠰ayoutManager的存在,才使得RecyclerView顯示變得更靈活

  1. ViewHolder

ViewHolder在這里用來(lái)容納每個(gè)item里面的控件引用,然后執(zhí)行findViewById方法。因?yàn)閞ecyclerView里面的每個(gè)item都有相同的控件引用,所以使用ViewHolder之后就可以減少findViewById方法的調(diào)用從而提高性能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容