Android 在每 10 个项目(如 tumblr)中添加回收器视图下方的背景视图



我正在尝试制作一个像 tumblr 应用程序这样的回收器视图。你可以在这里看到: https://streamable.com/s/gpyec/kxvjnz

我的问题是如何在回收器视图下方添加视频(或任何可点击的视频(?我添加了一个项目装饰实现,如下所示:

class RecyclerViewAdItemDecoration(private val func:() -> Unit) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
super.getItemOffsets(outRect, view, parent, state)
val position = parent.getChildLayoutPosition(view)
val mLayoutManager = parent.layoutManager
if (mLayoutManager is GridLayoutManager) {
setGridParams(view, position, parent)
} else if (mLayoutManager is LinearLayoutManager) {
setLinearParams(view, position, parent)
}
}
private fun setGridParams(view: View, position: Int, parent: RecyclerView) {
val p = view.layoutParams as ViewGroup.MarginLayoutParams
if (position == 0) {
p.setMargins(0,0,0, 0)
} else if (position >= 10 && (position % 10 == 0 || position % 11 == 0)) {
p.setMargins(0,0,0, parent.height)
func()
} else {
p.setMargins(0,0,0, 0)
}
}
private fun setLinearParams(view: View, position: Int, parent: RecyclerView) {
val p = view.layoutParams as ViewGroup.MarginLayoutParams
if (position == 0) {
p.setMargins(0,0,0, 0)
} else if (position >= 10 && (position % 10 == 0)) {
p.setMargins(0,0,0, parent.height)
func()
} else {
p.setMargins(0,0,0, 0)
}
}
}

这样我就可以为背景视图添加足够的空间,但现在无法单击。我也找不到任何用于此类实现的库。感谢任何帮助。

编辑: 澄清一下,我想在回收器视图中每 10 个项目之后立即显示背景视频(或任何视图(。就像在链接中的视频中看到的那样,回收器视图中每 10 个项目之间有一个空格,这也触发了在后台播放视频(在回收商视图下方(

中每 10 项之后立即显示背景视频(或任何视图( 回收商视图。

如果背景视频每 10 项之后,则表示有一个项目(第 11 项(,它是透明的。

您在这里真正想要的是具有多种视图类型的回收器视图。


使用允许放置视图的activity_main.xmlRelativeLayout在其他人之上(在 Z 轴上(。

例如:RecyclerView是这里最顶层的视图。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:focusable="true">
<View
android:id="@+id/ad"
android:background="@color/colorAccent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_posts"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>

为两种类型的回收器视图类型创建两个项目布局

前任:

item_normal.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100dp">
<TextView
android:id="@+id/tv_post"
tools:text="Post"
android:background="@android:color/white"
android:textSize="32sp"
android:gravity="center_horizontal|center_vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

item_transparent.xml(其中布局背景是透明的,可以看到表面积下方的视图(

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"/>

在item_transparent中设置android:clickable=false不会停止触发透明项上的单击事件,因此请使用使用接口的通信流,以便在单击透明项时将其他视图(ad(置于前面。

MainActivity.kt

class MainActivity : AppCompatActivity(), RvAdpater.OnItemClick {
private lateinit var adView: View
private lateinit var rvPosts: RecyclerView
override fun onClick() {
bringAdFront()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rvPosts = findViewById(R.id.rv_posts)
rvPosts.layoutManager = LinearLayoutManager(this)
val rvAdpater = RvAdpater()
rvAdpater.setListener(this)
rvPosts.adapter = rvAdpater
}
private fun bringAdFront() {
adView = findViewById<View>(R.id.ad)
adView.bringToFront()
}
override fun onBackPressed() {
// to go back to the normal recycler view when back button is pressed
val parent = rvPosts.parent as ViewGroup
parent.removeAllViews()
parent.addView(adView, 0)
parent.addView(rvPosts, 1)
}
}

RvAdapter.kt

const val TAG = "RvAdpater"
class RvAdpater : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private lateinit var listener:OnItemClick

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val viewNormal = LayoutInflater.from(parent.context).inflate(R.layout.item_normal, parent, false)
val viewTransparent = LayoutInflater.from(parent.context).inflate(R.layout.item_transparent, parent, false)
return when(viewType){
0 -> NormalViewHolder(viewNormal)
2 -> TransparentViewHolder(viewTransparent)
else -> NormalViewHolder(viewNormal)
}
}
override fun getItemCount(): Int = 10
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when(getItemViewType(position)){
0 -> {
val normalHolder = holder as NormalViewHolder
normalHolder.tv.text = "Post"
normalHolder.itemView.setOnClickListener {
Log.d(TAG, "Clicked on Normal item")
}
}
2 -> {
val transparentHolder = holder as TransparentViewHolder
transparentHolder.itemView.setOnClickListener {
listener.onClick()
}
}
}
}
fun setListener(onItem:OnItemClick){
listener = onItem
}
interface OnItemClick{
fun onClick()
}
override fun getItemViewType(position: Int): Int = position % 2 * 2
class NormalViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val tv:TextView = itemView.findViewById(R.id.tv_post)
}
class TransparentViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
}

签出存储库以获取工作示例


要处理多种视图类型,您可以使用环氧树脂库。

最新更新