Android 筆記 RecyclerView的簡單使用

RecyclerView

創建列表與卡片
顯示一列項目一般會使用基本的ListView或者GridView。後來在supper library裏面增加了一個RecyclerView,裏面封裝了更全面的功能,官方教程更推薦使用這個新的顯示列表項目的組件。

在一本書《Android編程權威教程》裏面介紹RecycleView的時候是這麼講的。假如一個列表有100項,每個項目包括1個TextView,那我們豈不是要準備100個TextView?這樣肯定會消耗大量資源。實際上,我們只需要準備剛好填滿屏幕的數量就好。RecyclerView顧名思義,就是可以把子View重複使用,只創建適應屏幕的數量,重複使用,可以節約資源。

除此以外,RecycleView還提供了一些有用的功能,比如可以在動態增加刪除資源的時候提供動畫效果等。這些我還沒有實踐過,僅測試了顯示功能。

開始使用

首先,需要在supper library裏面添加RecyclerView,然後就可以像普通的View一樣添加到Layout裏面去了。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_test_recycle"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.septem.firstapp.TestRecycleActivity">

    <android.support.v7.widget.RecyclerView
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recycler_view_test"
        android:background="#70b0e7" />
</RelativeLayout>

然後在程序裏添加

private void addViews() {
        mRecyclerView = (RecyclerView)findViewById(R.id.recycler_view_test);
        mLayoutManager = new GridLayoutManager(this,1);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mAdapter = new MyRecyclerAdapter();
        mRecyclerView.setAdapter(mAdapter);
    }

正如上面所寫,必須添加的項目包括
1,一個layoutManager,一般情況是gridLayoutManager或者LinearLayoutManager.
2,一個Adapter,用來添加數據

下面,需要定義一個MyRecyclerAdapter

private class MyRecyclerAdapter extends RecyclerView.Adapter<MyHolder> {

        @Override
        public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            ImageView iv = new ImageView(thisActivity);
            LinearLayout.LayoutParams ivLayoutParams =
                    new LinearLayout.LayoutParams(300,
                            300);
            ivLayoutParams.setMargins(5,5,0,0);
            iv.setLayoutParams(ivLayoutParams);
            iv.setBackgroundColor(Color.parseColor("#78daa8"));
            iv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
            iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
            //以上是代碼定義一個ImageView,也可以用XML定義,然後添加,如下
            //View v = LayoutInflater.from(parent.getContext())
            //                   .inflate(R.layout.my_text_view, parent, false);
            MyHolder mHolder = new MyHolder(iv);
            return mHolder;
        }

        @Override
        public void onBindViewHolder(MyHolder holder, int position) {
            mCursor.moveToFirst();
            mCursor.move(position);
            holder.iv.setImageBitmap(null);
            LoadTask loadTask = new LoadTask();
            loadTask.execute(position);
        }

        @Override
        public int getItemCount() {
            return mCursor.getCount();
        }
    }

自定義一個Adapter最少需要重寫3個方法,就是上面這3個
onCreateViewHolder獲得一個viewHolder,是專門用於控制子View的,這裏需要在合適的地方建立一個新的類

private class MyHolder extends RecyclerView.ViewHolder {
        public ImageView iv;

        public MyHolder(View v) {
            super(v);
            this.iv = (ImageView) v;
        }
    }

這樣就可以創建一個最簡單的ViewHolder。之前在onCreateViewHolder裏面創建的子View被傳遞到這個裏面來。

onBindViewHolder(MyHolder holder, int position)
用於在子View裏面顯示數據,而子View是從參數的holder裏面找到的

getItemCount()用於獲取子View的個數

在以上設置好以後,一個最簡單的RecycleView就建立好了。

注意事項

一般會在一個單獨的線程裏面讀取數據,然後顯示出來,這時候,需要獲得對應Position的子View
ImageView iv = (ImageView)mLayoutManager.findViewByPosition(position);

還有一個方法,getChildAt(index)也可以獲得子View,但是實際測試中發現經常出現錯誤。總結出原因是,這個方法返回的是屏幕可見的View
比如,getChildAt(1)返回屏幕上第2個可見的View
而之前那個方法是我們需要的,就是返回整個列表中對應位置的View。這一點需要注意。
官網的文檔裏面居然沒寫清楚。

還有一個需要注意的,如果對應整個列表位置的View已經被移到屏幕外了,那麼這個View會返回爲null,如果這時候對其操作會出現NullPointer exception。所以,在操作的時候要判斷一下

if(iv!=null)
    iv.setImageBitmap(bitmap);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章