Перемещение элемента RecyclerView приводит к изменению высоты элемента

#java #android #kotlin #android-recyclerview

#java #Android #kotlin #android-recyclerview

Вопрос:

Пользовательское оформление элементов:

 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 amp;amp; 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
    }
}

 

изменить положение элемента

 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("$inna"))
                2 -> data.add(Model("$inanb"))
            }
        }
        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—>10
5-->101″ src=»https://i.stack.imgur.com/UsghY.png»></p>
<p>Высота элемента изменяется. Как сохранить высоту элемента неизменной?</p>
</div>
<h3><em>Ответ №1:</em></h3>
<div>
<p>Вы можете исправить размер элементов, которые вы создаете для recyclerview. Попробуйте указать средний размер входящих данных в виде ширины и высоты в дизайне. или в логике html: ширина: 100vw; высота: 100vh; можете ли вы попробовать</p>
</div>
<h3><em>Комментарии:</em></h3>
<blockquote class=

1. Это Android, а высота Recyclerview равна 100%