如何向回收器视图中的最后一个视图添加填充,仅当回收器视图可滚动时?



我想在回收器视图中的最后一个视图中添加底部填充,但前提是回收器视图是可滚动的 - 换句话说,如果最后一个适配器项完全可见且没有滚动,请不要添加填充。我意识到,从 onBindViewHolder 中,findLastCompletelyVisibleItemPosition()将始终返回前一项的位置,因为当前视图在技术上尚不可见。我也尝试了一个 ItemDecorator,但这也不起作用,因为它们是在视图之前添加的,所以我们仍然不知道 RecyclerView 是否可滚动。我的理想方法看起来像这样:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
...
if (position == items.size() - 1 && [is scrollable]) {
((MyViewHolder) viewHolder).addBottomPadding(...);
}
}

那个[可滚动]位是我不确定的。有没有其他方法可以做到这一点?

android:clipToPadding属性添加到您的视图中,并为您的视图提供填充,该填充将与 recylerview 项目一起滚动。

<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="16dp"
android:paddingTop="16dp"
/>

希望这会有所帮助

好的,所以我:)为您提供解决方案。 核心概念是将viewTreeObserver OnGlobalLayoutListener附加到onBind中的最后一项。然后,在测量视图后,将调用它的OnGlobalLayout方法,这对您的要求至关重要。调用后,只需计算y + itemViewHeight并将其与height of the RecyclerView进行比较即可。要获得此高度,您还必须将OnGlobalLayoutListener附加到回收器视图,然后设置Adapter with the height of it as parameter。在调用onGobalLayout之前,您可能需要设置一个"空"适配器以防止错误。

要记住的两件重要事情:

-永远不要忘记删除OnGlobalLayoutListener
- 下面的代码是 丑陋,只是一个最小的可行产品

活动:

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rvTest.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
//maybe an adapter without content has to be provided so you won't get the error: no adapter attached skipping layout
rvTest.viewTreeObserver.addOnGlobalLayoutListener(object: ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
rvTest.adapter = RvTestAdapter(this@MainActivity, rvTest.height)
rvTest.viewTreeObserver.removeOnGlobalLayoutListener(this) //must remove! 
}
})
}
}

适配器:

class RvTestAdapter(val context: Context, val recyclerViewHeight: Int): RecyclerView.Adapter<TestViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = TestViewHolder(LayoutInflater.from(context).inflate(R.layout.vh_test, parent, false))
override fun getItemCount() = 3
override fun onBindViewHolder(holder: TestViewHolder, position: Int) {
if (position == 2) { //last position
holder.itemView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
if (holder.itemView.y + holder.itemView.height  > recyclerViewHeight) {
Log.d("YESSSS", "WOOP WOOP")
}
holder.itemView.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
}
}
}

(希望你不介意 Kotlin 代码(

最新更新