有没有一种方法可以使RecyclerView requireFadingEdge不受paddingTop和paddingBottom的影响

时间:2019-03-27 08:37:25

标签: android android-recyclerview

当前,我需要在paddingTop的第一个项目和最后一个项目中使用paddingBottom的{​​{1}}和RecyclerView,因为要避免复杂的空间计算。 / p>

但是,我注意到RecyclerView的效果也会受到影响。

这是我的XML

requiresFadingEdge

当paddingTop和paddingBottom为40dp

enter image description here

如您所见,淡入淡出效果下降了40dp,这不是我想要的。


当paddingTop和paddingBottom为0dp

enter image description here

淡入效果看起来不错。但是,我的<androidx.recyclerview.widget.RecyclerView android:requiresFadingEdge="vertical" android:paddingTop="0dp" android:paddingBottom="0dp" android:overScrollMode="always" android:background="?attr/recyclerViewBackground" android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" /> 必须具有非零的paddingToppaddingBottom


是否有办法使RecyclerViewRecyclerView不影响requiresFadingEdge的{​​{1}}?

4 个答案:

答案 0 :(得分:5)

我为此找到了最好的官方解决方案。覆盖RecyclerView的这3种方法。哪一个对衰落边缘起着最重要的作用。

首先创建您的recyclerView。

public class MyRecyclerView extends RecyclerView {

    // ... required constructor

    @Override
    protected boolean isPaddingOffsetRequired() {
        return true;
    }

    @Override
    protected int getTopPaddingOffset() {
        return -getPaddingTop();
    }

    @Override
    protected int getBottomPaddingOffset() {
        return getPaddingBottom();
    }
}

就是这样。使用此回收视图,您将看到褪色边缘不受影响。

以下内容仅用于说明。如果您想在幕后知道。

要了解这种边缘效果是如何工作的,我深入研究了使用android:requiresFadingEdge的类,然后发现它不是由RecyclerView处理,而是由View类处理的,所有视图的父级。

onDraw类的View方法中,我找到了通过使用此方法isPaddingOffsetRequired来绘制淡入淡出边缘的代码。仅用于处理淡入淡出效果。

根据文档,如果要更改衰落边缘的行为,则此方法应由子类覆盖。默认情况下,它返回false。因此,通过返回true,我们要求视图在绘制视图时对边缘应用一些偏移。

请遵循onDraw类的View方法的摘要以了解计算。

final boolean offsetRequired = isPaddingOffsetRequired();
if (offsetRequired) {
    paddingLeft += getLeftPaddingOffset();
}

int left = mScrollX + paddingLeft;
int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
int top = mScrollY + getFadeTop(offsetRequired);
int bottom = top + getFadeHeight(offsetRequired);

if (offsetRequired) {
    right += getRightPaddingOffset();
    bottom += getBottomPaddingOffset();
}

我们可以看到top变量是使用getFadeTop(offsetRequired)初始化的。

protected int getFadeTop(boolean offsetRequired) {
    int top = mPaddingTop;
    if (offsetRequired) top += getTopPaddingOffset();
    return top;
}

在此方法中,top通过在需要偏移量时将topOffSet的值相加来计算。因此,要反转效果,我们需要传递您要传递的填充的负值。因此我们需要返回-getPaddingTop()

现在,对于bottom,我们没有传递负值,因为bottom正在top + height上工作。因此,传递负值会使从底部开始的淡入淡出更短,因此我们需要添加底部填充以使其正确可见。

您可以覆盖这4种方法进行播放。 getLeftPaddingOffset(), getRightPaddingOffset(), getTopPaddingOffset(), getBottomPaddingOffset()

答案 1 :(得分:1)

我建议一些解决方案 ,希望对您有所帮助

1- RecyclerView.ItemDecoration (保留requiresFadingEdge

class ItemDecoration(private val spacing: Int) : RecyclerView.ItemDecoration(){

   override fun getItemOffsets(outRect: Rect, view: View, parent: 
   RecyclerView, state: RecyclerView.State?) {

   val position = parent.getChildAdapterPosition(view)
   when(position)
    0 ->                          { outRect.top    = spacing /*40dp*/ }
    parent.adapter.itemCount-1 -> { outRect.bottom = spacing /*40dp*/ }

}

2-多个ViewHolders (取决于ViewHolder是保留还是删除requiresFadingEdgehttps://stackoverflow.com/a/26245463/5255963

3-渐变(删除requiresFadingEdge

使用可绘制对象制作两个渐变,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
    android:type="linear"
    android:angle="90"
    android:startColor="#000"
    android:endColor="#FFF" />
</shape>

然后将background设置为Recyclerview顶部和底部的两个视图。

答案 2 :(得分:1)

有很多方法可以实现这一目标,但我更喜欢以下对我有用的解决方案。 您可以使用名为Android-FadingEdgeLayout的第三方库here

这里是一个依赖项。

implementation 'com.github.bosphere.android-fadingedgelayout:fadingedgelayout:1.0.0'

在yours.xml

<com.bosphere.fadingedgelayout.FadingEdgeLayout
    android:id="@+id/fading_edge_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:fel_edge="top|left|bottom|right"
    app:fel_size_top="40dp"
    app:fel_size_bottom="40dp"
    app:fel_size_left="0dp"
    app:fel_size_right="0dp">

    <androidx.recyclerview.widget.RecyclerView   
        android:paddingTop="0dp"
        android:paddingBottom="0dp"
        android:overScrollMode="always"
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false" />

</com.bosphere.fadingedgelayout.FadingEdgeLayout>

根据需要更改ReacyclerView属性。下面是带有所有侧面悲伤的示例图像。希望对您有帮助。

enter image description here

积分Android-FadingEdgeLayout

答案 3 :(得分:0)

我认为您应该使用此:

#fullpage {
    transition-delay: 1s !important;
}