1. 程式人生 > >Android RecyclerView 實現瀑布流交錯效果,並使最後一行子View高度佔滿RecyclerView

Android RecyclerView 實現瀑布流交錯效果,並使最後一行子View高度佔滿RecyclerView

而在實現完瀑布流後,覺得滑動到底部時,最後一行的高度,沒有佔滿外部View,感覺不太好。(真正的瀑布流應該是條目數近乎無窮,可以一直載入更多)

既然是瀑布流,那麼就選用StaggeredGridLayoutManager。
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)); //縱向3列

import android.content.Context;
import android.support.annotation.Nullable;
import
android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import java.util.Arrays; /** * 實現了滑動到底部的處理,暫未新增自定義監聽器 * 實現了當LayoutManger是StaggeredGridLayoutManager時,滑到底部的那一行上的子view高度佔滿RecyclerView * * author : stone * email :
[email protected]
* time : 16/5/6 14 23 */
public class RichRecyclerView extends RecyclerView { public RichRecyclerView(Context context) { this(context, null); } public RichRecyclerView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public
RichRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthSpec, int heightSpec) { super.onMeasure(widthSpec, heightSpec); } @Override public void onScrollStateChanged(int state) { if (state == RecyclerView.SCROLL_STATE_IDLE) { LayoutManager layoutManager = getLayoutManager(); if (layoutManager instanceof StaggeredGridLayoutManager) { StaggeredGridLayoutManager lm = (StaggeredGridLayoutManager) layoutManager; // int columnCount = lm.getColumnCountForAccessibility(null,null);//列數 int columnCount = lm.getSpanCount(); // System.out.println("----" +"columnCount" + columnCount); int positions[] = new int[columnCount]; lm.findLastVisibleItemPositions(positions);//新增 可見的最後一行的 position 資料到陣列 positions System.out.println("----" +Arrays.toString(positions)); for (int i = 0; i < positions.length; i++) { // System.out.println("當前檢視上的最後可見列的位置" + positions[i]); } for (int i = 0; i < positions.length; i++) { /** * 判斷lastItem的底邊到recyclerView頂部的距離 * 是否小於recyclerView的高度 * 如果小於或等於 說明滾動到了底部 */ if (positions[i] >= lm.getItemCount() - columnCount) { // System.out.println("滑動到底了1"); // System.out.println("總adapter的條目數:" + lm.getItemCount()); //內部取的adapter的方法 // System.out.println("總的列數:" + columnCount); // System.out.println("符號條件的最後可見列上的position" + positions[i]); View child = lm.findViewByPosition(positions[i]); ViewGroup.LayoutParams layoutParams = child.getLayoutParams(); layoutParams.height = getHeight() - child.getBottom() + child.getHeight(); child.setLayoutParams(layoutParams); } } int[] into = new int[columnCount]; lm.findFirstCompletelyVisibleItemPositions(into); for (int i = 0; i < into.length; i++) { System.out.println("首次完全可見的view位置:" + into[i]); } lm.findFirstVisibleItemPositions(into); for (int i = 0; i < into.length; i++) { System.out.println("首次可見的view位置(即使部份可見):" + into[i]); } } else if (layoutManager instanceof LinearLayoutManager){ LinearLayoutManager lm = (LinearLayoutManager) layoutManager; int position = lm.findLastVisibleItemPosition(); if (position + 1 == lm.getItemCount()) { System.out.println("滑動到底了2"); } } } super.onScrollStateChanged(state); } }

相應的adapter:

/**
 * author : stone
 * email  : [email protected]
 * time   : 16/4/9 16 22
 */
public class StaggeredAdapter extends BaseRecyclerViewAdapter<String> {

    private List<Integer> mWHs; //寬或高
    private int mOrientation;

    public StaggeredAdapter(Context context, int layoutID, List<String> datas, int orientation) {
        super(context, layoutID, datas);
        this.mWHs = new ArrayList<>();
        this.mOrientation = orientation;

        for (int i = 0, len = datas.size(); i < len; i++) {
            if (mOrientation == StaggeredGridLayoutManager.VERTICAL) {
                mWHs.add((int) (100 + Math.random() * 100));
            } else {
                mWHs.add((int) (80 + Math.random() * 100));
            }
        }

    }

    @Override
    public void onBindViewHolderSetData(@NonNull BaseRecyclerViewHolder holder, int position) {

        holder.itemView.setBackgroundColor(getColor());

        String str = getItem(position);
        holder.setText(R.id.tv_text, str);

        ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
        if (params == null) {
            params = new ViewGroup.LayoutParams(-2, -2);
        }
        if (mOrientation == StaggeredGridLayoutManager.VERTICAL) {
//            holder.itemView.setMinimumHeight(mWHs.get(position));//該方法改變itemview高度,並requestLayout(),子view沒有重新請求layout
            params.height = mWHs.get(position);
        } else {
//            holder.itemView.setMinimumWidth(mWHs.get(position));
            params.width = mWHs.get(position);
        }
        holder.itemView.setLayoutParams(params);


    }


    /**
     * 隨機顏色
     *
     * @return
     */
    @CheckResult
    private int getColor() {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        String temp;
        for (int i = 0; i < 3; i++) {
            temp = Integer.toHexString(random.nextInt(0xFF));
            if (temp.length() == 1) {
                temp = "0" + temp;
            }
            sb.append(temp);
        }
        return Color.parseColor("#" + sb.toString());
    }
}

item_adapter.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/sel_item_back">

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:gravity="center"/>
</RelativeLayout>