繁体   English   中英

移动 RecyclerView 项目导致项目高度发生变化

[英]Move RecyclerView item causes item height to change

自定义物品装饰:

class DemoDecoration(context: Context, left: Float, top: Float, right: Float, bottom: Float) : ItemDecoration() {

    companion object {
        private const val dividerHeight = 8f
        private const val dividerPaddingLeft = 0f
    }

    private val left: Int
    private val top: Int
    private val right: Int
    private val bottom: Int
    private val dividerPaddingRight = 0f
    private val dividerPaint: Paint
    private val textPaint: Paint

    init {
        val density = context.resources.displayMetrics.density
        this.left = (density * left).toInt()
        this.top = (density * top).toInt()
        this.right = (density * right).toInt()
        this.bottom = (density * bottom).toInt()
        dividerPaint = Paint()
        dividerPaint.isAntiAlias = true
        dividerPaint.style = Paint.Style.FILL
        dividerPaint.color = ContextCompat.getColor(context, android.R.color.darker_gray)
        textPaint = Paint()
        textPaint.isAntiAlias = true
        textPaint.style = Paint.Style.FILL
        textPaint.textSize = 30f
        textPaint.typeface = Typeface.DEFAULT_BOLD
        textPaint.color = Color.BLACK
    }

    override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        draw(canvas, parent)
    }

    override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        draw(canvas, parent)
    }

    private fun draw(canvas: Canvas, parent: RecyclerView) {
        if (parent.layoutManager == null) {
            return
        }
        canvas.save()
        drawRect(canvas, parent)
        canvas.restore()
    }

    private fun drawRect(canvas: Canvas, parent: RecyclerView) {
        val childCount = parent.childCount
        val spanCount = getSpanCount(parent)
        val space = 0f.coerceAtLeast(((top + bottom).toFloat() - dividerHeight) / 2)
        var i = 0
        if (i < childCount) {
            val view = parent.getChildAt(i)
            val position = parent.getChildAdapterPosition(view)
            if (position / spanCount % 2 == 0) {
                canvas.drawRect(dividerPaddingLeft, view.bottom + space,
                    parent.right - dividerPaddingRight, view.bottom + space + dividerHeight,
                    dividerPaint)
            }
            i += spanCount
        }
    }

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        if (parent.layoutManager == null) {
            return
        }
        val position = parent.getChildAdapterPosition(view)
        val spanCount = getSpanCount(parent)
        val index = position / spanCount
        if (index > 0 && index % 2 == 0) {
            outRect[left, 56, right] = bottom
        } else {
            outRect[left, top, right] = bottom
        }
    }

    private fun getSpanCount(parent: RecyclerView): Int {
        var spanCount = -1
        val layoutManager = parent.layoutManager
        if (layoutManager is GridLayoutManager) {
            spanCount = layoutManager.spanCount
        } else if (layoutManager is StaggeredGridLayoutManager) {
            spanCount = layoutManager.spanCount
        }
        return spanCount
    }
}

更改项目 position

class MainActivity: AppCompatActivity() {

    private lateinit var change: Button
    private lateinit var recycler: RecyclerView
    private val demoAdapter: DemoAdapter = DemoAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        change = findViewById(R.id.change)
        change.setOnClickListener {
            val list = ArrayList(demoAdapter.currentList)
            list.add(10, list.removeAt(5))
            demoAdapter.submitList(list)
        }

        recycler = findViewById(R.id.recycler)
        recycler.apply {
            layoutManager = GridLayoutManager(this@MainActivity, 5)
            setHasFixedSize(true)
            isNestedScrollingEnabled = false
            itemAnimator = DefaultItemAnimator()
            addItemDecoration(DemoDecoration(this@MainActivity, 2f, 4f, 2f, 4f))
            adapter = demoAdapter
        }

        val data: MutableList<Model> = ArrayList()
        for (i: Int in 0 .. 39) {
            when ((1..2).random()) {
                1 -> data.add(Model("$i\n\na"))
                2 -> data.add(Model("$i\na\nb"))
            }
        }
        demoAdapter.submitList(data)
    }
}

适配器

class DemoAdapter: ListAdapter<Model, DemoAdapter.ViewHolder>(TaskDiffCallback()) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false))
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val model = getItem(position)
        holder.text.text = model.text
    }

    class ViewHolder(view: View): RecyclerView.ViewHolder(view) {
        val container: ConstraintLayout
        val text: TextView

        init {
            container = view.findViewById(R.id.container)
            text = view.findViewById(R.id.text)
        }
    }

    private class TaskDiffCallback : DiffUtil.ItemCallback<Model>() {
        override fun areItemsTheSame(oldItem: Model, newItem: Model): Boolean {
            return oldItem == newItem
        }

        override fun areContentsTheSame(oldItem: Model, newItem: Model): Boolean {
            return oldItem == newItem
        }
    }

}

data class Model(val text: String)

项目布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/shape_stroke_black">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center"
        android:paddingTop="4dp"
        android:paddingBottom="4dp"
        android:background="@android:color/holo_blue_light"
        android:textColor="@android:color/black"
        android:textSize="12sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

RecyclerviewDemo

5-->105-->101

项目高度改变了。如何保持项目高度不变?

看起来您的帖子主要是代码; 请添加更多细节。 看起来您的帖子主要是代码; 请添加更多细节。 看起来您的帖子主要是代码; 请添加更多细节。 看起来您的帖子主要是代码; 请添加更多细节。

您可以修复为 recyclerview 创建的项目的大小。 尝试在设计中将传入数据的平均大小作为宽度高度。 或在 html 逻辑中:宽度:100vw; 高度:100vh; 你能试一下吗

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM