package com.example.myapplication1.view;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
public class MyLinearLayoutManager extends RecyclerView.LayoutManager {
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
int offsetY = 0;
for (int i = 0; i < getItemCount(); i++) {
View viewForPosition = recycler.getViewForPosition(i);
addView(viewForPosition);
measureChildWithMargins(viewForPosition,0,0);
int measuredHeight = viewForPosition.getMeasuredHeight();
int measuredWidth = viewForPosition.getMeasuredWidth();
layoutDecorated(viewForPosition,0,offsetY,measuredWidth,offsetY+measuredHeight);
offsetY += measuredHeight;
}
}
@Override
public boolean canScrollVertically() {
return true;
}
/**
*
* @param dy 往下滑動 dy < 0 ,往上滑動, dy > 0
* @param recycler
* @param state
* @return
*/
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
View firstView = getChildAt(0);
int top = firstView.getTop();
View lastView = getChildAt(getChildCount() - 1);
int bottom = lastView.getBottom();
//RecyclerView的實際可容納空間的高度
int height = getHeight() - getPaddingBottom() - getPaddingTop();
//將偏移量轉換成符合邏輯的,即:向下爲正,向上爲負
int newDy = -dy;
//頂部:
//第一個view的頂部與RecyclerView的頂部剛好重合,不能再往下滑動了,newDy >0 代表向下滑動
if (top == 0 && newDy > 0){
return 0;
}
//top <0 說明recyclerView中的內容已經向上滑動一段距離
//如果(top + newDy,即新的top)>0 就讓它等於0,讓它等於0的條件,就是 newDy = -top
if (top < 0 && top + newDy > 0){
newDy = -top;
}
//底部:== 0,最後一個View的底邊 與RecyclerView的底邊已重合,不能再往上滑動了
//底部, < 0 的情況是內容過少 未充滿RecyclerView,就是 最後一個itemView 的bottom 天生比 RecyclerView的 height 小
if(bottom <= height && newDy <0){
return 0;
}
//已經超出了RecyclerView的底邊,但是要保證不能小於滑動到底邊裏面(即上部)
//bottom + newDy < height 時,bottom + newDy = height,所以 newDy = height - bottom = -(bottom - height)
if (bottom > height && bottom + newDy < height){
newDy = - (bottom - height);
}
offsetChildrenVertical(newDy);
return dy;
}
}