1. 程式人生 > >【Android】用RecycleView實現可以橫向滾動的ListView效果

【Android】用RecycleView實現可以橫向滾動的ListView效果

終於閒下來了,總結一下RecycleView的使用。

一、概述

與常見的ListView和GridView一樣,RecycleView也用來在有限的介面上展示大量的資料。它提供了一種插拔式的體驗,高度的解耦,使用非常靈活,可以通過support-v7包進行匯入。先看以下RecycleView可以實現的效果:

(單列上下滾動)

(多列上下滾動)

(多項橫向滾動)

(瀑布流)

二、實現一個可以左右滑動的ListView的效果

1、RecycleView的佈局

其實佈局很簡單,與ListView一樣:

<LinearLayout
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recy_bringinto"
            android:layout_width="match_parent"
            android:layout_height="125dp">

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

    </LinearLayout>

2、RecycleView的使用設定

相比於ListView使用時,只需要設定一個adapter就OK了,RecycleView的使用則要相對複雜一點。通過設定它的LayoutManager,ItemDecoration , ItemAnimator可以實現各種那個各樣的效果,詳情參見

在這裡我們主要用到了LayoutManager和ItemAnimator.

recycleView=(RecyclerView)findViewById(R.id.recy_bringinto);
        recycleView.setHasFixedSize(true);//設定固定大小
        recycleView.setItemAnimator(new DefaultItemAnimator());//設定預設動畫
        mLayoutManage=new LinearLayoutManager(this);
        mLayoutManage.setOrientation(OrientationHelper.HORIZONTAL);//設定滾動方向,橫向滾動
        recycleView.setLayoutManager(mLayoutManage);
        adapter=new  RecycleViewAdapter(this,R.layout.recycleview_bringinto,listBrings);
其中,setOrientation()方法設定其只能橫向滾動。

3、自定義RecycleView使用的adapter

在上一步最後一行,你看到了我自己定義RecycleViewAdapter類,它接受三個引數,分別是上下文物件Context、單個Item的佈局檔案、要顯示的資料。

這裡我們定義了一個內部類MyViewHolder繼承於系統的RecyclerView.ViewHolder,然後RecycleViewAdapter繼承RecycleView.Adapter。因為系統沒有給我們的RecycleView控制元件實現OnClick方法,所以這裡我讓自定義的Adapter實現了View的OnClickListener介面,方便我們點選一個Item的時候可以做出響應。

熟悉ListView的人都知道,它是通過ViewHolder來提高效能的。onCreateViewHolder負責建立檢視,解析單個Item的頁面佈局,並傳入到MyViewHolder類中,進行findviewbyId。當滑動或者展示到手機螢幕上的時候通過onBindViewHolder方法將應該要顯示的資料展示的螢幕上,在這個方法中因為用到了Volley,所以有個imageLoader,如果你用不到的話直接刪除就好了。

詳細程式碼:

public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.MyViewHoler> implements View.OnClickListener {
    int ResourceID;
    Context mContext;
    ArrayList<BringInto> mData;
    private OnRecycleViewItemClickListener mOnItemClickListener;
    private ImageLoader imageLoader;

    public RecycleViewAdapter(Context context, int resourceID, ArrayList<BringInto> brings) {
        mContext=context;
        mData=brings;
        ResourceID=resourceID;
    }

    @Override
    public void onBindViewHolder(MyViewHoler holder, int position) {

        //相當於listview的adapter中的getview方法
        //負責將資料繫結到檢視上
        if (imageLoader == null)
            imageLoader = ApplicationController.getInstance().getImageLoader();
        BringInto brin=mData.get(position);
        holder.tvToolName.setText(brin.getToolname());
        if(brin.getNotes().equals("人員進入"))
        {
            holder.ivPicIn.setBackgroundResource(R.drawable.user);
        }else {
            holder.ivPicIn.setImageUrl(brin.getPicIn(), imageLoader);
        }
        if(brin.iscorrect())
        {
            holder.ivCheck.setBackgroundResource(R.drawable.correct);
        }else{
            holder.ivCheck.setBackgroundResource(0);
        }
        holder.itemView.setTag(position);//將位置儲存在tag中
    }

    @Override
    public MyViewHoler onCreateViewHolder(ViewGroup parent, int viewType) {
        //負責建立檢視
        View view= LayoutInflater.from(mContext).inflate(ResourceID,null);
        view.setOnClickListener(this);
        return new MyViewHoler(view);
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    @Override
    public void onClick(View v) {
        if (mOnItemClickListener!=null)
        {
            mOnItemClickListener.OnItemClick(v,(int)v.getTag());
        }
    }

    public void setOnItemClickListener(OnRecycleViewItemClickListener listener)
    {
        this.mOnItemClickListener=listener;
    }
    public static interface OnRecycleViewItemClickListener{
        void OnItemClick(View view,int position);
    }
    class MyViewHoler extends RecyclerView.ViewHolder
    {
        private final NetworkImageView ivPicIn;
        private final TextView tvToolName;
        private final ImageView ivCheck;

        public MyViewHoler(View itemView) {
            super(itemView);
            ivPicIn=(NetworkImageView)itemView.findViewById(R.id.iv_picIn);
            tvToolName=(TextView)itemView.findViewById(R.id.tv_toolname);
            ivCheck=(ImageView)itemView.findViewById(R.id.iv_check);

        }
    }


}
單個的Item佈局:
<LinearLayout
        android:layout_marginRight="5dp"
        android:gravity="center"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <com.android.volley.toolbox.NetworkImageView
            android:background="@drawable/default_picture"
            android:id="@+id/iv_picIn"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:text="縮圖"/>
        <TextView
            android:layout_marginTop="5dp"
            android:id="@+id/tv_toolname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#000000"
            android:textSize="15sp"
            android:text="名稱"/>
        <ImageView
            android:id="@+id/iv_check"
            android:layout_width="25dp"
            android:layout_height="25dp"/>

    </LinearLayout>

4.如何讓RecycleView響應我們的點選事件?

在上面你看到了我定義了一個公共方法:setOnItemClickListener,一旦要使用這個方法必須實現介面:OnRecycleViewItemClickListener,然後在onCreateViewHolder中View的點選事件中,就會自動執行介面中的OnItemClick方法,此方法有兩個引數,一個是當前點選的View,另一個是View所在的位置。

5.將自定義的adapter繫結到RecycleView上

recycleView.setAdapter(adapter);
        //recycleview的點選事件
        adapter.setOnItemClickListener(new RecycleViewAdapter.OnRecycleViewItemClickListener() {
            @Override
            public void OnItemClick(View view, int position) {

                //ShowDetail(listBrings.get(position),position);

            }
        });
是不是感覺與ListView的click有點不一樣?我們是在adapter中進行點選事件繫結的。不管怎樣,你還是拿到的點選後的View和Position。