实现了双屏摄像头显示,添加了部分代码
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
package com.sw.dualscreen.adapter
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewbinding.ViewBinding
|
||||
|
||||
abstract class BaseViewHolder<B : ViewBinding, T>(val binding: B) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
abstract fun bind(item: T)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.sw.dualscreen.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewbinding.ViewBinding
|
||||
|
||||
/**
|
||||
* 通用子项适配器(支持ViewBinding)
|
||||
*/
|
||||
class GenericItemAdapter<T, VB : ViewBinding>(
|
||||
private var items: List<T>,
|
||||
private val bindingInflater: (LayoutInflater, ViewGroup, Boolean) -> VB,
|
||||
private val bindCallback: VB.(item: T, position: Int) -> Unit,
|
||||
) : RecyclerView.Adapter<GenericItemAdapter<T, VB>.ViewHolder>() {
|
||||
|
||||
inner class ViewHolder(private val binding: VB) : RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(item: T, position: Int) {
|
||||
binding.bindCallback(item, position)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateData(newItem: List<T>) {
|
||||
this.items = newItem
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = bindingInflater(LayoutInflater.from(parent.context), parent, false)
|
||||
return ViewHolder(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
holder.bind(items[position], position)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.sw.dualscreen.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewbinding.ViewBinding
|
||||
|
||||
class GridRecyclerAdapter<T, B : ViewBinding>(
|
||||
private val itemList: List<T>,
|
||||
private val bindingInflater: (LayoutInflater, ViewGroup, Boolean) -> B,
|
||||
private val bindHolder: (B, T) -> Unit,
|
||||
private val onItemClick: ((T) -> Unit)? = null
|
||||
) : RecyclerView.Adapter<BaseViewHolder<B, T>>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<B, T> {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
val binding = bindingInflater(inflater, parent, false)
|
||||
return object : BaseViewHolder<B, T>(binding) {
|
||||
override fun bind(item: T) = bindHolder(binding, item)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: BaseViewHolder<B, T>, position: Int) {
|
||||
holder.bind(itemList[position])
|
||||
holder.itemView.setOnClickListener {
|
||||
onItemClick?.invoke(itemList[position])
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = itemList.size
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
package com.sw.dualscreen.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
/**
|
||||
* item间距
|
||||
* 为RecyclerView添加间距的ItemDecoration
|
||||
*/
|
||||
class GridSpacingItemDecoration(
|
||||
private val spanCount: Int,
|
||||
private val spacing: Int,
|
||||
private val includeEdge: Boolean
|
||||
private val spanCount: Int, // 列数
|
||||
private val spacing: Int, // 间距(dp)
|
||||
private val includeEdge: Boolean // 是否包含边缘
|
||||
) : RecyclerView.ItemDecoration() {
|
||||
|
||||
override fun getItemOffsets(
|
||||
@@ -19,18 +20,35 @@ class GridSpacingItemDecoration(
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
val position = parent.getChildAdapterPosition(view)
|
||||
val column = position % spanCount
|
||||
val position = parent.getChildAdapterPosition(view) // item position
|
||||
val column = position % spanCount // item column
|
||||
|
||||
if (includeEdge) {
|
||||
// 左右间距计算
|
||||
outRect.left = spacing - column * spacing / spanCount
|
||||
outRect.right = (column + 1) * spacing / spanCount
|
||||
if (position < spanCount) outRect.top = spacing
|
||||
outRect.bottom = spacing
|
||||
|
||||
// 第一行添加顶部间距
|
||||
if (position < spanCount) {
|
||||
outRect.top = spacing
|
||||
}
|
||||
outRect.bottom = spacing // 每行底部都添加间距
|
||||
} else {
|
||||
// 左右间距计算(不包含边缘)
|
||||
outRect.left = column * spacing / spanCount
|
||||
outRect.right = spacing - (column + 1) * spacing / spanCount
|
||||
if (position >= spanCount) outRect.top = spacing
|
||||
|
||||
// 不是第一行时添加顶部间距
|
||||
if (position >= spanCount) {
|
||||
outRect.top = spacing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将dp值转换为px
|
||||
*/
|
||||
fun Context.dpToPx(dp: Int): Int {
|
||||
return (dp * resources.displayMetrics.density).toInt()
|
||||
}
|
||||
Reference in New Issue
Block a user