天天看點

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

界面無小事(一): RecyclerView+CardView了解一下 界面無小事(二): 讓RecyclerView展示更多不同視圖 界面無小事(三):用RecyclerView + Toolbar做個檔案選擇器 界面無小事(四):來寫個滾動選擇器吧! 界面無小事(五):自定義TextView 界面無小事(六):來做個好看得側拉菜單!

目錄

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

之前設定布局的時候用了最簡單的LinearLayoutManager, 而且是單一布局, 這次來感受下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以及最後一個條目設定為填充父容器. 來看看效果圖:
界面無小事(二): 讓RecyclerView展示更多不同視圖

效果圖

這是谷歌推薦的一個圖檔加載庫. 我個人的評價就是, 異常強大, 可以滿足各種花式加載. 而這裡我們隻是簡單用一下, 不細說.

在建構當中加入:

compile 'com.github.bumptech.glide:glide:3.7.0'
           
使用類似:

Glide.with(context).load(R.drawable.pic).centerCrop().into(imageView);

加載即可. 第一個參數是上下文, 第二個參數是圖檔資源, 第三個參數是ImageView控件.

快速寫一個帶圖布局:
<?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的設定加載不同布局. 來看看效果圖:
界面無小事(二): 讓RecyclerView展示更多不同視圖

不同布局加載

一行代碼足矣:

gridLayoutManager.setOrientation(GridLayoutManager.HORIZONTAL);

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

橫着滾

對, 還有瀑布流. 記得注釋掉GridLayoutManager設定寬度那部分.
StaggeredGridLayoutManager layoutManager
                = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
        rvTest.setLayoutManager(layoutManager);
           
界面無小事(二): 讓RecyclerView展示更多不同視圖

瀑布流

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

繼續閱讀