目前,我需要在第一个
paddingTop
项和最后一项中使用 paddingBottom
的 RecyclerView
和 RecyclerView
,因为我想避免复杂的空间计算。
但是,我注意到,
requiresFadingEdge
效果也会受到影响。
这是我的 XML
<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" />
如你所见,淡入淡出效果下移了40dp,这不是我想要的。
褪色效果看起来不错。但是,对于我的
paddingTop
,我需要非零 paddingBottom
和 RecyclerView
。
有没有办法让
RecyclerView
的requiresFadingEdge
不受paddingTop
和paddingBottom
的影响?
我找到了最好的官方解决方案。重写
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;
}
在此方法中,当需要偏移时,通过添加topOffSet的值来计算
top
。因此,为了扭转效果,我们需要传递您正在传递的填充的负值。所以我们需要返回-getPaddingTop()
。
现在对于底部,我们不会传递负值,因为底部正在处理
top + height
。因此,传递负值会使淡入淡出距离底部更短,因此我们需要添加底部填充以使其正确可见。
你可以重写这4个方法来玩它。
getLeftPaddingOffset(), getRightPaddingOffset(), getTopPaddingOffset(), getBottomPaddingOffset()
我建议一些解决方案 ,希望对你有帮助
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-多个ViewHolder(取决于ViewHolder保留或删除
requiresFadingEdge
)
https://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 顶部和底部的两个视图。
有很多方法可以实现这一目标,但我更喜欢下面适合我的解决方案。 您可以使用名为
Android-FadingEdgeLayout
checkout here 的第三方库
这是一个依赖项。
implementation 'com.github.bosphere.android-fadingedgelayout:fadingedgelayout:1.0.0'
在你的.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
属性。下面是带有所有侧面的示例图像。我希望这对你有帮助。
一些简单的解决方法对我有用。 由于我不想扩展或导入更多库,因此我用 LinearLayout 包装了 RecyclerView。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="[some #]dp"
android:paddingBottom="[some #]dp">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdgeLength="[some #]"
android:requiresFadingEdge="vertical"/>
</LinearLayout>
环绕线性布局的宽度和高度可以是任意的。