Android RecyclerView 實現瀑布流交錯效果,並使最後一行子View高度佔滿RecyclerView
阿新 • • 發佈:2019-01-09
而在實現完瀑布流後,覺得滑動到底部時,最後一行的高度,沒有佔滿外部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>