键盘关闭后 RecyclerView 高度被包裹 [英] RecyclerView height gets wrapped after keyboard gets closed

查看:24
本文介绍了键盘关闭后 RecyclerView 高度被包裹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 2 个字段的表单,在这些字段下,RecyclerView 中生成的按钮很少.RecyclerView 有一个 2 列的 GridLayout.我的细胞

I have a form which contains 2 fields and under those, few generated buttons in a RecyclerView. The RecyclerView has a GridLayout of 2 columns. My cells

我刚刚注意到关闭本机键盘时出现的错误(在我填写了两个字段后它已打开)

I just noticed a bug which appears when I close the native keyboard (it has opened after I filled my two fields)

如果我以 3 个按钮为例,我的 RecyclerView 中会有一行包含 2 个单元格,第二行包含一个单元格.

If I take the example of 3 buttons, I would have in my RecyclerView one row with 2 cells and a second row with one.

关闭键盘后,RecyclerView 被包装成一行 2 个单元格,要访问第二行,我必须在 RecyclerView 内滚动.

After closing my keyboard, the RecyclerView gets wrapped into one row of 2 cells and to access the second row, I have to scroll inside the RecyclerView.

我尝试使用 LinearLayout,同样的错误.

I tried with a LinearLayout, same bug.

我尝试了在 StackOverFlow 上找到的一些修复:

I tried few fixes found on StackOverFlow :

  • 在 Manifest 中将键盘设置为 adjustPan
  • 将高度设置为 match_parent 到我的单元格和布局

那些都没有用.

以下是一些错误的屏幕:

Here are some screens of the bugs:

  • 在打开键盘之前:
  • 关闭键盘后:知道如何解决这个问题吗?

最好的问候

更新 1:

按照要求,这里有一些代码示例可以重现问题:

As asked, here are some code samples to reproduce the problem :

适配器设置:

binding.actionButtonsContainer.setLayoutColumnsCount(actionsList.size)
val adapter = IncidentActionButtonsListAdapter(actionsList, this)
binding.actionButtonsContainer.setAdapter(adapter)
binding.actionButtonsContainer.visibility = View.VISIBLE

我的适配器:

import android.graphics.Rect
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class IncidentActionButtonsListAdapter(
        private val actionsList: List<IncidentAction>,
        private val incidentActionButtonViewClickListener: IncidentActionButtonViewClickListener? = null
): RecyclerView.Adapter<IncidentActionButtonsListAdapter.IncidentActionButtonsListViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IncidentActionButtonsListViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_incident_action_button_item, parent, false)

        return IncidentActionButtonsListViewHolder(view)
    }

    override fun onBindViewHolder(holder: IncidentActionButtonsListViewHolder, position: Int) {
        actionsList[position].let { action ->
            holder.tvIncidentActionTitle.text = holder.tvIncidentActionTitle.context.getString(action.text)

            holder.itemView.setOnClickListener {
                val incidentActionResult = IncidentActionResult(
                        code = action.id
                )

                incidentActionButtonViewClickListener?.onIncidentActionButtonViewClicked(incidentActionResult)
            }
        }
    }

    inner class IncidentActionButtonsListViewHolder(view: View): RecyclerView.ViewHolder(view) {
        val container: LinearLayout = view.findViewById(R.id.container)
        val tvIncidentActionTitle: TextView = view.findViewById(R.id.tvIncidentActionTitle)
    }

    override fun getItemCount(): Int = actionsList.size

}

interface IncidentActionButtonViewClickListener {
    fun onIncidentActionButtonViewClicked(incidentActionResult: IncidentActionResult)
}

class IncidentActionButtonsItemDecorator (private val padding: Int) : RecyclerView.ItemDecoration() {
    override fun getItemOffsets(
            outRect: Rect,
            view: View,
            parent: RecyclerView,
            state: RecyclerView.State
    )
    {
        super.getItemOffsets(outRect, view, parent, state)
        outRect.top = padding
        outRect.bottom = padding
        outRect.left = padding
        outRect.right = padding
    }
}

RecyclerView 代码:

The RecyclerView code :

class IncidentActionButtonView(
        context: Context,
        attrs: AttributeSet
): LinearLayout(context, attrs) {

    var binding: LayoutIncidentActionListBinding = LayoutIncidentActionListBinding.inflate(LayoutInflater.from(context), this, true)

    init {
        val spacing = (context.resources.displayMetrics.density * 4).toInt() // converting dp to pixels
        binding.list.addItemDecoration(IncidentActionButtonsItemDecorator(spacing)) // setting space between items in RecyclerView
    }

    fun setLayoutColumnsCount(numberOfActions: Int) {
        var numberOfColumns = numberOfActions
        val orientation = resources.configuration.orientation

        // if phone is in landscape orientation we can accept up to 3 cols
        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            if (numberOfColumns > 3) {
                numberOfColumns = 3
            }
        } else { // else in portrait we can accept up to 2 cols
            if (numberOfColumns > 2) {
                numberOfColumns = 2
            }
        }

        val layoutManager = GridLayoutManager(context, numberOfColumns)
        binding.list.layoutManager = layoutManager
    }

    fun setAdapter(adapter: IncidentActionButtonsListAdapter) {
        binding.list.adapter = adapter
        binding.list.visibility = View.VISIBLE
    }
}

RecyclerView 布局:

The RecyclerView Layout :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/actionButtonsContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/incident_list_background"
    app:layout_constraintTop_toBottomOf="@id/tvTitle"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

单元格布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@drawable/incident_action_button_background"
    android:orientation="horizontal"
    android:paddingLeft="@dimen/padding_small"
    android:paddingRight="@dimen/padding_small"
    android:paddingTop="@dimen/padding_extra_small"
    android:paddingBottom="@dimen/padding_extra_small">

    <TextView
        style="@style/Theme.PortailAchat.Title1"
        android:id="@+id/tvIncidentActionTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        android:text="@string/incident_await_new_delivery"
        android:textAllCaps="true"
        android:textAlignment="center"
        android:layout_gravity="center"/>
</LinearLayout>

推荐答案

在manifest文件的activity标签内添加这行代码:

add this line of code inside the activity tag in manifest file:

android:windowSoftInputMode="adjustPan"

这篇关于键盘关闭后 RecyclerView 高度被包裹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆