天天看點

RecyclerView的實用指南(一)——清單/網格/瀑布流

此篇文章主要是實用篇,使用Android Studio

先上三張結果圖:

RecyclerView的實用指南(一)——清單/網格/瀑布流
RecyclerView的實用指南(一)——清單/網格/瀑布流
RecyclerView的實用指南(一)——清單/網格/瀑布流

RecyclerView控件通過設定setLayoutManager實作以下三種布局:

RecyclerView recyclerView;
//清單布局
recyclerView.setLayoutManager(new LinearLayoutManager(Context context));
recyclerView.setLayoutManager(new LinearLayoutManager(Context context, int orientation, boolean reverseLayout));
//網格布局
recyclerView.setLayoutManager(new GridLayoutManager(Context context, int spanCount));
recyclerView.setLayoutManager(new GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout));
//瀑布流布局
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(int spanCount, int orientation));

[其中:
    參數context:上下文,一般填寫this即可
    參數spanCount:一般預設為列數,若設定方向為水準展示,則為行數
    參數orientation:例:LinearLayoutManager.HORIZONTAL(水準)/VERTICAL(垂直)
    參數reverseLayout:展示順序,true(順序)/flase(逆序)]           

取代原來經典的ListView和GridView控件,并且可以輕松實作瀑布流布局。

具體操作步驟如下:

1.首先導入RecyclerView控件的依賴包

直接将compile ‘com.android.support:recyclerview-v7:25.3.1’複制黏貼到下圖位置,注意一定要再重新buid一下程式。此時,當你再在布局檔案中輸入Rec三個字母時,AS會自動提示你有android.support.v7.widget.RecyclerView控件。

RecyclerView的實用指南(一)——清單/網格/瀑布流

2.在布局檔案中添加RecyclerView控件

一般需要兩個布局檔案,一個是RecyclerView控件所在的布局,另一個是RecyclerView中每一項的布局。

item_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        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:id="@+id/item_list"
        //這裡的名字可以自己取,前面的路徑保持一緻即可
        android:name="com.project.recyclerview.ItemList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        //布局類型,可在這裡設定,也可在控件所在的類中通過設定setLayoutManager實作
        app:layoutManager="LinearLayoutManager"
        //控件所在的類
        tools:context="com.project.recyclerview.ListActivity"
        //清單每一條内容的布局
        tools:listitem="@layout/item_list_content"/>

</LinearLayout>           
item_list_context.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:orientation="horizontal">

    <ImageView
        android:id="@+id/list_img"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_margin="@dimen/text_margin"/>

    <TextView
        android:id="@+id/list_content"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_margin="@dimen/text_margin"
        android:textAppearance="?attr/textAppearanceListItem"/>
</LinearLayout>           

3.RecyclerView所展示的資料内容存儲

public class Content {
    public static final List<ListItem> LIST_ITEMS = new ArrayList<ListItem>();

    //存放圖檔的Id
    private static final int[] imageIds = new int[]{
            R.mipmap.tudou, R.mipmap.pingguo, R.mipmap.qingcai, R.mipmap.xigua, R.mipmap.juzi,
            R.mipmap.tudou, R.mipmap.pingguo, R.mipmap.qingcai, R.mipmap.xigua, R.mipmap.juzi,
            R.mipmap.tudou, R.mipmap.pingguo, R.mipmap.qingcai, R.mipmap.xigua, R.mipmap.juzi,
            R.mipmap.tudou, R.mipmap.pingguo, R.mipmap.qingcai, R.mipmap.xigua, R.mipmap.juzi,
            R.mipmap.tudou, R.mipmap.pingguo, R.mipmap.qingcai, R.mipmap.xigua, R.mipmap.juzi,
            R.mipmap.tudou, R.mipmap.pingguo, R.mipmap.qingcai, R.mipmap.xigua, R.mipmap.juzi
    };

    static {
        // Add some sample items.
        for (int i = 0; i < imageIds.length; i++) {
            ListItem mListItem = new ListItem(imageIds[i], "蔬果" + String.valueOf(i));
            LIST_ITEMS.add(mListItem);
        }
    }

    public static class ListItem {
        public final int img;
        public final String content;

        public ListItem(int img, String content) {
            this.img = img;
            this.content = content;
        }
    }
}           

4.Activity中執行個體化RecyclerView控件

public class ListActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private ListAdapter listAdapter = new ListAdapter(LIST_ITEMS);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.item_list);

        recyclerView =(RecyclerView) findViewById(R.id.item_list);
        recyclerView.setAdapter(listAdapter);
    }
}           

5.RecyclerView的Adapter(資料與RecyclerView的綁定)

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder>{
    //與傳進來的資料清單格式一緻
    private List<Content.ListItem> mValues;

    //将傳進來的資料清單指派給此函數中自定義的清單
    public ListAdapter(List<Content.ListItem> items) {
        mValues = items;
    }

    //加載清單每項的布局
    @Override
    public ListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_list_content, parent, false);
        return new ViewHolder(view);
    }

    //資料與控件的綁定,即每項布局中的控件展示對應的資料
    @Override
    public void onBindViewHolder(ListAdapter.ViewHolder holder, int position) {
        holder.mItem = mValues.get(position);
        holder.mImgView.setBackgroundResource(mValues.get(position).img);
        holder.mContentView.setText(mValues.get(position).content);
    }

    //展示的項數
    @Override
    public int getItemCount() {
        return mValues.size();
    }

    //執行個體化每項布局中的控件
    public class ViewHolder extends RecyclerView.ViewHolder {
        public final View mView;
        public final ImageView mImgView;
        public final TextView mContentView;
        public Content.ListItem mItem;

        public ViewHolder(View view) {
            super(view);
            mView = view;
            mImgView = (ImageView) view.findViewById(R.id.list_img);
            mContentView = (TextView) view.findViewById(R.id.list_content);
        }
    }
}           

6.在AndroidManifest.xml中添加activity标簽

【注:若是自己新建立的activity,不要忘了以上标題的步驟】

在AndroidManifest.xml中,application标簽中添加activity标簽,位置如下圖所示:

RecyclerView的實用指南(一)——清單/網格/瀑布流

添加代碼如下:

<activity
     android:name=".ListActivity"
     android:label="RecyclerViewList"
     //activity的主題,此處AppTheme.NoActionBar為自定義的主題
     android:theme="@style/AppTheme.NoActionBar"/>

//自定義主題:AppTheme.NoActionBar
//在res/values/styles.xml中,resource标簽中添加如下代碼:
<style name="AppTheme.NoActionBar">
     <item name="windowActionBar">false</item>
     <item name="windowNoTitle">true</item>
</style>
           

通過上面六步,已實作了清單布局,另外兩個布局的實作大同小異,主要也為上面六步實作。

這裡講一下瀑布流布局實作的局部重要代碼:

//瀑布流與網格的主要差別:網格每項大小都是相同的,而瀑布流每項大小不同
//在StaggeredGridAdapter.java中,以下兩個方法中代碼實作每項高度不一,進而實作瀑布流效果
     @Override
    public StaggeredGridAdapter(List<Content.ListItem> items) {
        mValues = items;
        mHeights = new ArrayList<>();
        //随機定一組每項高度數值
        for (int i = 0; i < mValues.size(); i++)
        {
            mHeights.add( (int) (100 + Math.random() * 300));
        }
    }

     @Override
    public void onBindViewHolder(StaggeredGridAdapter.ViewHolder holder, int position) {
        holder.mItem = mValues.get(position);
        //設定每項的高度
        ViewGroup.LayoutParams lp = holder.mImgView.getLayoutParams();
        lp.height = mHeights.get(position);
        holder.mImgView.setLayoutParams(lp);
        holder.mImgView.setBackgroundResource(mValues.get(position).img);

        holder.mContentView.setText(mValues.get(position).content);
    }           

三個布局完整源代碼下載下傳位址:http://download.csdn.net/detail/zhengchu321/9846484