Android 不正确的RecyclerView项';禁用滚动时的高度

Android 不正确的RecyclerView项';禁用滚动时的高度,android,android-recyclerview,Android,Android Recyclerview,我的目标是能够将当前选定的项目放置在RecyclerView的中心,同时禁用用户滚动的功能(我只想通过我的代码来实现) 为此,我添加了较大的顶部和底部填充,以便将第一个和最后一个项目滚动到中心(垂直)。我还添加了clipToPadding=“false”以使滚动像上面描述的那样工作 <android.support.v7.widget.RecyclerView android:id="@+id/playRecyclerView" android:layout_width="

我的目标是能够将当前选定的项目放置在RecyclerView的中心,同时禁用用户滚动的功能(我只想通过我的代码来实现)

为此,我添加了较大的顶部和底部填充,以便将第一个和最后一个项目滚动到中心(垂直)。我还添加了
clipToPadding=“false”
以使滚动像上面描述的那样工作

<android.support.v7.widget.RecyclerView
    android:id="@+id/playRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="290dp"
    android:paddingBottom="290dp"
    android:clipToPadding="false"/>
TestAdapter
也非常简单,实际上在这里可能并不重要,所以我将跳过这段代码

项目的布局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="wrap_content"
    android:orientation="horizontal"
    android:background="@drawable/list_item_bg">

    <TextView
        android:id="@+id/taskListItem_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_margin="@dimen/fab_margin"
        android:textAppearance="?attr/textAppearanceListItem"
        android:textColor="@color/colorPrimary"
        android:textSize="20sp" />
</RelativeLayout>
我对项目的渲染不正确:

我注意到,这个高度等于

itemHeight =  recyclerViewHeight - (TopPaddding + BottomPadding) 
因为当我在RecyclerView上设置
clipToPadding=true
时,我得到这样一个视图:

项目的高度以相同的方式剪切


是否有可能以某种方式使其工作?

更新:添加了替代方法。

我的猜测是
clipToPadding=false
通过使
RecyclerView
不可滚动而被否定。尝试以下操作以允许正确的布局,并在最后禁用滚动。如果我明白你想做什么,这应该行得通

public class TestLayoutManager extends LinearLayoutManager {
    boolean mCanScroll = true;

    public TestLayoutManager(Context context) {
        super(context, VERTICAL, false);
    }

    @Override
    public boolean canScrollVertically() {
        return super.canScrollVertically() && mCanScroll;
    }

    @Override
    public void onLayoutCompleted(RecyclerView.State state) {
        super.onLayoutCompleted(state);
        mCanScroll = false;
    }
}


上述方法适用于API 24,但不适用于API 23,并且可能不适用于API更新:添加了替代方法。

我的猜测是
clipToPadding=false
通过使
RecyclerView
不可滚动而被否定。尝试以下操作以允许正确的布局,并在最后禁用滚动。如果我明白你想做什么,这应该行得通

public class TestLayoutManager extends LinearLayoutManager {
    boolean mCanScroll = true;

    public TestLayoutManager(Context context) {
        super(context, VERTICAL, false);
    }

    @Override
    public boolean canScrollVertically() {
        return super.canScrollVertically() && mCanScroll;
    }

    @Override
    public void onLayoutCompleted(RecyclerView.State state) {
        super.onLayoutCompleted(state);
        mCanScroll = false;
    }
}


上述方法适用于API 24,但不适用于API 23,并且可能不适用于API固定高度问题,代码通过覆盖onLayoutChildren来检测布局开始,onLayoutCompleted来检测布局完成

public class ScrollBlockingLayoutManager extends LinearLayoutManager {
    private boolean isInLayout = false;

    public ScrollBlockingLayoutManager(Context context) {
        super(context);
    }

    @Override
    public boolean canScrollVertically() {
        //Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
        return isInLayout || (mAdapter.scrollEnabled && super.canScrollVertically());
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        Log.e(TAG, "onLayoutChildren" + state.toString());
        isInLayout = true;
        super.onLayoutChildren(recycler, state);

    }

    @Override
    public void onLayoutCompleted(RecyclerView.State state) {
        super.onLayoutCompleted(state);
        Log.e(TAG, "onLayoutCompleted" + state.toString());
        isInLayout = false;

        //mCanScroll = false;
    }
}

通过覆盖onLayoutChildren以检测布局开始和onLayoutCompleted以检测布局完成,修复了代码的高度问题

public class ScrollBlockingLayoutManager extends LinearLayoutManager {
    private boolean isInLayout = false;

    public ScrollBlockingLayoutManager(Context context) {
        super(context);
    }

    @Override
    public boolean canScrollVertically() {
        //Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
        return isInLayout || (mAdapter.scrollEnabled && super.canScrollVertically());
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        Log.e(TAG, "onLayoutChildren" + state.toString());
        isInLayout = true;
        super.onLayoutChildren(recycler, state);

    }

    @Override
    public void onLayoutCompleted(RecyclerView.State state) {
        super.onLayoutCompleted(state);
        Log.e(TAG, "onLayoutCompleted" + state.toString());
        isInLayout = false;

        //mCanScroll = false;
    }
}

您可能正在寻找此小部件@我不知道,它没有任何文档。只有几个中文单词。它看起来更像一个选择器,而不是一个列表。我发现了另一个看起来更有希望的包,但我仍然想知道,我的代码中发生了什么。:)
CanScrollVertical()
似乎用于测量子视图,根据返回值,逻辑不同。试着在
RecyclerView
中将你的填充设置为比290dp小得多的值,看看这是否会有所不同——我想会的。下一个问题是为什么会这样。@Cheticamp是的,这确实会有所不同。正如我在问题
itemHeight=RecycleServiceWheight-(TopAdding+BottomPadding)
中所说的那样。但既然RecyclerView已经设置了
cliptoppadding=false
您可能正在寻找这个小部件,那么为什么它要计算填充呢@我不知道,它没有任何文档。只有几个中文单词。它看起来更像一个选择器,而不是一个列表。我发现了另一个看起来更有希望的包,但我仍然想知道,我的代码中发生了什么。:)
CanScrollVertical()
似乎用于测量子视图,根据返回值,逻辑不同。试着在
RecyclerView
中将你的填充设置为比290dp小得多的值,看看这是否会有所不同——我想会的。下一个问题是为什么会这样。@Cheticamp是的,这确实会有所不同。正如我在问题
itemHeight=RecycleServiceWheight-(TopAdding+BottomPadding)
中所说的那样。既然RecyclerView已经设置了
Cliptoppadding=false
,那么为什么要计算填充呢?好吧,是和否。在
onLayoutCompleted
中将
mCanScroll
设置为
false
没有帮助,但我已经尝试过以后在一些其他事件上设置它,比如“onClick”这确实有帮助。因此,这可能是一个很好的方法,但我需要找到一个在
onLayoutCompleted
之后触发的事件。如果
CanScrollVertical()
在布局过程中返回
true
,通常情况下,您应该会得到一个良好的显示
CanScrollVertical()
应该在布局完成后才开始返回
false
。是的,我理解。看来,
onlayoutpleted
还为时过早那一定是出了什么事。我已经能够复制您的问题,主要是使用您提供的代码,这个解决方案的工作说明。我不知道在
onLayoutCompleted
之后会出现什么布局会导致问题。您是否可以通过Github等共享您的工作代码?我想将它与我的进行详细比较。是和否。将
mCanScroll
设置为
false
onLayoutCompleted
中没有帮助,但我尝试稍后在其他一些事件(如“onClick”)中设置它,它确实有帮助。因此,这可能是一个很好的方法,但我需要找到一个在
onLayoutCompleted
之后触发的事件。如果
CanScrollVertical()
在布局过程中返回
true
,通常情况下,您应该会得到一个良好的显示
CanScrollVertical()
应该在布局完成后才开始返回
false
。是的,我理解。看来,
onlayoutpleted
还为时过早那一定是出了什么事。我已经能够复制您的问题,主要是使用您提供的代码,这个解决方案的工作说明。我不知道在
onLayoutCompleted
之后会出现什么布局会导致问题。您是否可以通过Github等共享您的工作代码?我想将它与m进行详细比较