1. 程式人生 > 其它 >用RecyclerView實現滾動頁面顯示

用RecyclerView實現滾動頁面顯示

技術標籤:安卓androidjava

RecyclerView:

在安卓開發者網站上,對於RecyclerView的使用說明是:

如果您的應用需要根據大型資料集(或頻繁更改的資料)顯示元素的滾動列表,您應使用本頁所述的 RecyclerView。

從表面上看,RecyclerView的作用和ListView類似,都是用來顯示大量元素的,將元素以滾動的形式顯示,但是RecyclerView 比 ListView 更高階且更具靈活性。它是一個用於顯示龐大資料集的容器,可通過保持有限數量的檢視進行非常有效的滾動操作。 如果您有資料集合,其中的元素將因使用者操作或網路事件而在執行時發生改變,請使用 RecyclerView 。

從它類名上看,RecyclerView代表的意義是,我只管Recycler View,也就是說RecyclerView只管回收與複用View,其他的你可以自己去設定。可以看出其高度的解耦,給予你充分的定製自由(所以你才可以輕鬆的通過這個控制元件實現ListView,GirdView,瀑布流等效果)。

在ListView中 改變列表某一個item資料,然後重新整理列表,會回到最頂部,而RecyclerView可以保持原來滑動的位置不變。

當然,說到 RecyclerView 的優點,就不得不提它的 插拔式 的體驗,高度解耦:

佈局(顯示方式):可通過LayoutManager(LinearLayoutManagerGridLayoutManager,StaggeredGridLayoutManager

)設定; 分割線:通過 ItemDecoration 實現 Item 增刪動畫:通過 ItemAnimator ViewHolder
的建立和繫結:通過實現 Adapter

基礎知識補充

LayoutManager:RecyclerView 會根據 Layout Manager
提供的檢視來填充自身,常用的佈局管理器有LinearLayoutManager(線性佈局管理器)、GridLayoutManager(網格佈局管理器)、StaggeredGridLayoutManager
(瀑布流佈局管理器)等。 ViewHolder:列表中的檢視由 ViewHolder 例項展示。 ViewHolder

用於對控制元件的例項進行快取,負責顯示子項。例如,如果列表顯示了音樂集合,那麼每個 ViewHolder 可能代表一個專輯。
Adapter:ViewHolder 物件由 Adapter 管理。Adapter 按需建立
ViewHolder,併為其繫結資料。繫結意味著根據 Adapter 中的位置為子檢視填充對應的資料。

RecyclerView 的核心使用流程如下:

mRecyclerView = findView(R.id.id_recycler_view); //設定佈局管理器
mRecyclerView.setLayoutManager(mLayoutManager); //設定adapter
mRecyclerView.setAdapter(mAdapter) //設定Item增加、移除動畫
mRecyclerView.setItemAnimator(new DefaultItemAnimator()); //新增分割線
mRecyclerView.addItemDecoration(new DividerItemDecoration(
getActivity(), DividerItemDecoration.HORIZONTAL_LIST));

通過 RecyclerView 輕鬆實現一個普通列表:
首先建立一個recyclerview佈局檔案;


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:fitsSystemWindows="true"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/collect_recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

再建立一個用於在recyclerview中顯示的項,recycleritems;


<?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="wrap_content"
    android:padding="6dp"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/touxiangimg"
        android:layout_width="50dp"
        android:layout_height="50dp"
        tools:srcCompat="@drawable/tab_find_frd_pressed" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/nametext"
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:textSize="15dp"
            android:text="TextView" />

        <TextView
            android:id="@+id/numbertext"
            android:layout_width="match_parent"
            android:layout_height="25dp"
            android:textSize="15dp"
            android:text="TextView" />
    </LinearLayout>
</LinearLayout>

顯示效果如下:

在這裡插入圖片描述

建立一個用於recycleritems的物件類FriendList;

import java.io.Serializable;

public class FriendList implements Serializable {
    public String imgPath;//頭像地址
    public String FriendName;//朋友姓名
    public String FriendNumber;//朋友電話

    public FriendList(String imgPath, String FriendName, String FriendNumber) {
        this.imgPath = imgPath;
        this.FriendName = FriendName;
        this.FriendNumber = FriendNumber;
    }

    public String getImgPath() {
        return imgPath;
    }

    public void setImgPath(String imgPath) {
        this.imgPath = imgPath;
    }

    public String getFriendName() {
        return FriendName;
    }

    public void setFriendName(String FriendName) {
        this.FriendName = FriendName;
    }

    public String getFriendNumber() {
        return FriendNumber;
    }

    public void setFriendNumber(String FriendNumber) {
        this.FriendNumber = FriendNumber;
    }

    @Override
    public String toString() {
        return "FriendList{" +
                "imgPath='" + imgPath + '\'' +
                ", FriendName='" + FriendName + '\'' +
                ", FriendNumber='" + FriendNumber + '\'' +
                '}';
    }
}

建立recyclerview的介面卡;

public class CollectRecycleAdapter extends RecyclerView.Adapter<CollectRecycleAdapter.myViewHodler> {
    private Context context;
    private ArrayList<FriendList> friendListList;





    //建立建構函式
    public CollectRecycleAdapter(Context context, ArrayList<FriendList> friendListList) {
        //將傳遞過來的資料,賦值給本地變數
        this.context = context;//上下文
        this.friendListList = friendListList;//實體類資料ArrayList
    }

    /**
     * 建立viewhodler,相當於listview中getview中的建立view和viewhodler
     *
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public myViewHodler onCreateViewHolder(ViewGroup parent, int viewType) {
        //建立自定義佈局
        View itemView = View.inflate(context, R.layout.recycleritems, null);
        return new myViewHodler(itemView);
    }

    /**
     * 繫結資料,資料與view繫結
     *
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(myViewHodler holder, int position) {
        //根據點選位置繫結資料
        FriendList data = friendListList.get(position);
        //holder.mItemImg.setImageResource(R.drawable.mars2);
        holder.mItemFriendName.setText(data.FriendName);//獲取實體類中的name欄位並設定
        holder.mItemFriendNumber.setText(data.FriendNumber);//獲取實體類中的price欄位並設定

    }

    /**
     * 得到總條數
     *
     * @return
     */
    @Override
    public int getItemCount() {
        return friendListList.size();
    }

    //自定義viewhodler
    class myViewHodler extends RecyclerView.ViewHolder {
        private ImageView mItemImg;
        private TextView mItemFriendName;
        private TextView mItemFriendNumber;

        public myViewHodler(View itemView) {
            super(itemView);
            mItemImg = (ImageView) itemView.findViewById(R.id.touxiangimg);
            mItemFriendName = (TextView) itemView.findViewById(R.id.nametext);
            mItemFriendNumber = (TextView) itemView.findViewById(R.id.numbertext);
            //點選事件放在adapter中使用,也可以寫個介面在activity中呼叫
            //方法一:在adapter中設定點選事件
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //可以選擇直接在本位置直接寫業務處理
                    //Toast.makeText(context,"點選了xxx",Toast.LENGTH_SHORT).show();
                    //此處回傳點選監聽事件
                    if(onItemClickListener!=null){
                        onItemClickListener.OnItemClick(v, friendListList.get(getLayoutPosition()));
                    }
                }
            });
            itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    if (onItemClickListener != null) {
                        onItemClickListener.OnItemLongClick(v, friendListList.get(getLayoutPosition()));
                    }
                    return true;
                }
            });

        }
    }

    /**
     * 設定item的監聽事件的介面
     */
    public interface OnItemClickListener {
        /**
         * 介面中的點選每一項的實現方法,引數自己定義
         *
         * @param view 點選的item的檢視
         * @param data 點選的item的資料
         */
        void OnItemClick(View view, FriendList data);

        void OnItemLongClick(View view, FriendList data);
    }

    //需要外部訪問,所以需要設定set方法,方便呼叫
    private OnItemClickListener onItemClickListener;

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
}


將recyclerview封裝在fragment,呼叫Adapter中的方法;

public class LianxirenFragment extends Fragment {
    private View view;//定義view用來設定fragment的layout
    public RecyclerView mCollectRecyclerView;//定義RecyclerView
    //定義以goodsentity實體類為物件的資料集合
    private ArrayList<FriendList> friendLists = new ArrayList<FriendList>();
    //自定義recyclerveiw的介面卡
    private CollectRecycleAdapter mCollectRecyclerAdapter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //獲取fragment的layout
        view = inflater.inflate(R.layout.tab02, container, false);
        //對recycleview進行配置
        initRecyclerView();
        //模擬資料
        initData();
        //CollectRecycleAdapter.initData();
        return view;
    }

    /**
     * TODO 模擬資料
     */
    private void initData() {
        for (int i=0;i<20;i++){
            FriendList friendList =new FriendList("","","");
            friendList.setImgPath("C:\\Users\\VULCAN\\AndroidStudioProjects\\MyWeChat\\app\\src\\main\\res\\drawable\\earth2.png");
            friendList.setFriendName("name"+i);
            friendList.setFriendNumber("10100"+i);
            friendLists.add(friendList);
        }
    }

    /**
     * TODO 對recycleview進行配置
     */

    private void initRecyclerView() {
        //獲取RecyclerView
        mCollectRecyclerView=(RecyclerView)view.findViewById(R.id.collect_recyclerView);
        //建立adapter
        mCollectRecyclerAdapter = new CollectRecycleAdapter(getActivity(), friendLists);
        //給RecyclerView設定adapter
        mCollectRecyclerView.setAdapter(mCollectRecyclerAdapter);
        //設定layoutManager,可以設定顯示效果,是線性佈局、grid佈局,還是瀑布流佈局
        //引數是:上下文、列表方向(橫向還是縱向)、是否倒敘
        mCollectRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
        //設定item的分割線
        mCollectRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(),DividerItemDecoration.VERTICAL));
        //RecyclerView中沒有item的監聽事件,需要自己在介面卡中寫一個監聽事件的介面。引數根據自定義
        mCollectRecyclerAdapter.setOnItemClickListener(new CollectRecycleAdapter.OnItemClickListener() {
            @Override
            public void OnItemClick(View view, FriendList data) {
                //此處進行監聽事件的業務處理
                Toast.makeText(getActivity(),"我是name",Toast.LENGTH_SHORT).show();
            }
            @Override
            public void OnItemLongClick(View view,FriendList data){
                Toast.makeText(getActivity(),"Long click"+data.getFriendNumber(),Toast.LENGTH_SHORT).show();
            }

        });
}}

到這裡,在fragment裡面實現recyclerview就基本結束了,你可以將配置好的fragment在mainactivility裡面呼叫,在這裡我是在之前寫的類微信介面的專案中使用,可以在gitee上檢視具體的程式碼。

程式碼地址
https://gitee.com/fyl253711android/Android_project.git