介面無小事(二): 讓RecyclerView展示更多不同檢視

Sorrower發表於2018-04-24

介面無小事(一): RecyclerView+CardView瞭解一下

介面無小事(二): 讓RecyclerView展示更多不同檢視

介面無小事(三):用RecyclerView + Toolbar做個檔案選擇器

介面無小事(四):來寫個滾動選擇器吧!

介面無小事(五):自定義TextView

介面無小事(六):來做個好看得側拉選單!


目錄

  • 前言
  • GridLayoutManager的使用
  • Glide載入圖片
  • 讓RecyclerView支援更多不同佈局
  • 來看看橫向滾動
  • 還有瀑布流
  • 最後

前言

之前設定佈局的時候用了最簡單的LinearLayoutManager, 而且是單一佈局, 這次來感受下GridLayoutManager和瀑布流以及多佈局.


GridLayoutManager的使用

比起LinearLayoutManager, GridLayoutManager可以適用的場景就更多了. 來看一段程式碼:

RecyclerView rvTest = (RecyclerView) findViewById(R.id.rv_test);
//rvTest.setLayoutManager(new LinearLayoutManager(this));

final GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
rvTest.setLayoutManager(gridLayoutManager);

final MyRVAdapter myRVAdapter = new MyRVAdapter(this);

if (gridLayoutManager != null) {
    gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            if (position == 0
                    || position == 4
                    || position == (myRVAdapter.getItemCount() - 1)) {
                return gridLayoutManager.getSpanCount();
            } else {
                return 1;
            }
        }
    });
}

rvTest.setAdapter(myRVAdapter);
複製程式碼

將原本的LinearLayoutManager替換為GridLayoutManager, 並將0和4以及最後一個條目設定為填充父容器. 來看看效果圖:

效果圖


Glide載入圖片

這是谷歌推薦的一個圖片載入庫. 我個人的評價就是, 異常強大, 可以滿足各種花式載入. 而這裡我們只是簡單用一下, 不細說. 在構建當中加入:

compile 'com.github.bumptech.glide:glide:3.7.0'
複製程式碼

使用類似:Glide.with(context).load(R.drawable.pic).centerCrop().into(imageView);載入即可. 第一個引數是上下文, 第二個引數是圖片資源, 第三個引數是ImageView控制元件.


讓RecyclerView支援更多不同佈局

快速寫一個帶圖佈局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cv_test"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:foreground="@drawable/card_foreground"
    card_view:cardCornerRadius="4dp">

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

        <ImageView
            android:id="@+id/iv_test"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:scaleType="centerCrop" />

        <TextView
            android:id="@+id/tv_test"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="20dp" />
    </LinearLayout>

</android.support.v7.widget.CardView>
複製程式碼

getItemViewType用來設定檢視的型別. 這裡我們把0, 4, 和最後一個設定為圖片型. 和之前在GridLayoutManager中設定填充父容器的position一樣.

public enum ITEM_TYPE {
    ITEM_TYPE_IMAGE,
    ITEM_TYPE_TEXT
}

private int[] mImageId = {R.drawable.test, R.drawable.test2, R.drawable.test3};
複製程式碼
@Override
public int getItemViewType(int position) {
    if (position == 0 || position == 4 || position == (getItemCount() - 1)) {
        return ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal();
    } else {
        return ITEM_TYPE.ITEM_TYPE_TEXT.ordinal();
    }
}
複製程式碼

新增一個新的viewHolder:

public static class MyTVHolder extends RecyclerView.ViewHolder {
    TextView mTextView;

    public MyTVHolder(View itemView) {
        super(itemView);
        mTextView = (TextView) itemView.findViewById(R.id.tv_test);
    }
}

public static class MyIVHolder extends RecyclerView.ViewHolder {
    TextView mTextView;
    ImageView mImageView;

    MyIVHolder(View view) {
        super(view);
        mTextView = (TextView) view.findViewById(R.id.tv_test);
        mImageView = (ImageView) view.findViewById(R.id.iv_test);
    }
}
複製程式碼

然後就是修改onCreateViewHolder和onBindViewHolder部分, 區別處理文字item帶圖item, 順帶一提, 類上繼承的RecyclerView.Adapter的泛型要變更, public class MyRVAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal()) {
        return new MyIVHolder(mLayoutInflater.inflate(R.layout.rv_image_item, parent, false));
    } else {
        return new MyTVHolder(mLayoutInflater.inflate(R.layout.rv_item, parent, false));
    }
}
複製程式碼
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {

    if (holder instanceof MyTVHolder) {
        ((MyTVHolder) holder).mTextView.setText(mArray[position]);
    } else if (holder instanceof MyIVHolder) {
        Glide.with(mContext)
                .load(mImageId[position % 3])
                .centerCrop()
                .into(((MyIVHolder) holder).mImageView);
        ((MyIVHolder) holder).mTextView.setText(mArray[position]);
    }

    if (mOnItemClickListener != null) {
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int pos = holder.getLayoutPosition();
                mOnItemClickListener.onItemClick(holder.itemView, pos);
            }
        });
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                int pos = holder.getLayoutPosition();
                mOnItemClickListener.onItemLongClick(holder.itemView, pos);
                return false;
            }
        });
    }
}
複製程式碼

其實目的就是根據getItemViewType的設定載入不同佈局. 來看看效果圖:

不同佈局載入


來看看橫向滾動

一行程式碼足矣: gridLayoutManager.setOrientation(GridLayoutManager.HORIZONTAL);

橫著滾


還有瀑布流

對, 還有瀑布流. 記得註釋掉GridLayoutManager設定寬度那部分.

StaggeredGridLayoutManager layoutManager
                = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
        rvTest.setLayoutManager(layoutManager);
複製程式碼

瀑布流


最後

這是第二篇的全部內容, 感興趣的還有第三篇哦, 或者你還沒有看第一篇如果喜歡記得點贊或者關注我哦.


相關文章