如果RecyclerView嵌套在NestedScrollview中,则不会进行滚动。放置在LinearLayout中时 - 滚动项是正常的。
NestedScrollView位于CoordinatorLayout内部,NestedScrollView设置为peekHeight,并设置为屏幕高度的2/3。 我需要先将列表滚动到第一个元素,然后NestedScroll接收。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
app:behavior_hideable="false"
app:behavior_peekHeight="@dimen/ttn_list_peek_height"
app:layout_behavior="@string/bottom_sheet_behavior"
android:layout_height="wrap_content">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:descendantFocusability="blocksDescendants"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"/>
<FrameLayout
android:layout_width="match_parent"
android:background="@color/app_background"
android:visibility="gone"
android:layout_height="wrap_content">
<ProgressBar
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
Init RecyclerView:
MyLayoutManager lm = new MyLayoutManager(mContext);
lm.setAutoMeasureEnabled(true);
rcHistoryList.setLayoutManager(lm);
rcHistoryList.setAdapter(historyAdapter);
rcHistoryList.setHasFixedSize(false);
rcHistoryList.setNestedScrollingEnabled(false);
LayoutManager使用偏移量一个接一个地分解元素 - 以创建重叠元素的效果。
public class MyLayoutManager extends RecyclerView.LayoutManager {
private static final String TAG = "ScrollManager";
private SparseArray<View> viewCache = new SparseArray<>();
private Context context;
private int mAnchorPos;
public MyLayoutManager(Context context)
{
}
@Override
public boolean canScrollVertically() {
return true;
}
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
int delta = scrollVerticallyInternal(dy);
offsetChildrenVertical(-delta);
fill(recycler);
return delta;
}
private int scrollVerticallyInternal(int dy) {
int childCount = getChildCount();
int itemCount = getItemCount();
if (childCount == 0){
return 0;
}
final View topView = getChildAt(0);
final View bottomView = getChildAt(childCount - 1);
int viewSpan = getDecoratedBottom(bottomView) - getDecoratedTop(topView);
if (viewSpan <= getHeight()) {
return 0;
}
int delta = 0;
if (dy < 0){
View firstView = getChildAt(0);
int firstViewAdapterPos = getPosition(firstView);
if (firstViewAdapterPos > 0){
delta = dy;
} else {
int viewTop = getDecoratedTop(firstView);
delta = Math.max(viewTop, dy);
}
} else if (dy > 0){
View lastView = getChildAt(childCount - 1);
int lastViewAdapterPos = getPosition(lastView);
if (lastViewAdapterPos < itemCount - 1){
delta = dy;
} else {
int viewBottom = getDecoratedBottom(lastView);
int parentBottom = getHeight();
delta = Math.min(viewBottom - parentBottom, dy);
}
}
return delta;
}
private View getAnchorView() {
int childCount = getChildCount();
HashMap<Integer, View> viewsOnScreen = new HashMap<>();
Rect mainRect = new Rect(0, 0, getWidth(), getHeight());
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
int top = getDecoratedTop(view);
int bottom = getDecoratedBottom(view);
int left = getDecoratedLeft(view);
int right = getDecoratedRight(view);
Rect viewRect = new Rect(left, top, right, bottom);
boolean intersect = viewRect.intersect(mainRect);
if (intersect){
int square = viewRect.width() * viewRect.height();
viewsOnScreen.put(square, view);
}
}
if (viewsOnScreen.isEmpty()){
return null;
}
Integer maxSquare = null;
for (Integer square : viewsOnScreen.keySet()) {
if (maxSquare == null){
maxSquare = square;
} else {
maxSquare = Math.max(maxSquare, square);
}
}
return viewsOnScreen.get(maxSquare);
}
private void fill(RecyclerView.Recycler recycler) {
View anchorView = getAnchorView();
viewCache.clear();
for (int i = 0, cnt = getChildCount(); i < cnt; i++) {
View view = getChildAt(i);
int pos = getPosition(view);
viewCache.put(pos, view);
}
for (int i = 0; i < viewCache.size(); i++) {
detachView(viewCache.valueAt(i));
}
fillDown1(recycler);
fillUp1(recycler);
for (int i=0; i < viewCache.size(); i++) {
recycler.recycleView(viewCache.valueAt(i));
}
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
detachAndScrapAttachedViews(recycler);
fill(recycler);
}
private void fillUp1(RecyclerView.Recycler recycler) {
boolean fillUp = true;
int pos = 0; //anchorPos - 1;
int viewBottom = 0;// = anchorTop;
while (fillUp && pos >= 0){
View view = viewCache.get(pos);
if (view == null){
view = recycler.getViewForPosition(pos);
addView(view, 0);
measureChildWithMargins(view, 0, 0);
layoutDecorated(view, 0, viewBottom - getDecoratedMeasuredHeight(view), getDecoratedMeasuredWidth(view), viewBottom);
} else {
attachView(view, 0);
viewCache.remove(pos);
}
viewBottom = getDecoratedTop(view);
fillUp = (viewBottom > 0);
pos--;
}
}
private void fillDown1(RecyclerView.Recycler recycler) {
int pos = 0;
boolean fillDown = true;
int height = getHeight();
int viewTop = 0;
int itemCount = getItemCount();
View view1 = recycler.getViewForPosition(getChildCount());
pos = getChildCount();
viewTop = getDecoratedTop(view1);
while (fillDown && pos < itemCount){
View view = viewCache.get(pos);
if (view == null){
view = recycler.getViewForPosition(pos);
addView(view);
measureChildWithMargins(view, 0, 0);
layoutDecorated(view, 0, viewTop, getDecoratedMeasuredWidth(view), viewTop + getDecoratedMeasuredHeight(view));
viewHeight);
}
else
{
attachView(view);
viewCache.remove(pos);
}
viewTop = getDecoratedBottom(view) - 70;
fillDown = viewTop <= height;
pos++;
}
}
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT);
}
}
答案 0 :(得分:0)
将Recyclervirw可滚动属性设置为false。
mRecyclerView.setNestedScrollingEnabled(假);