带有 GridLayoutManager 的 Recycler View 不滚动

Recycler View with GridLayoutManager not scrolling

该应用程序包含两个按钮,一个用于 ListView,另一个用于 GridView,因此我创建了 ItemViews 和一个适配器。我已经创建了在 ListView 和 GridView 之间切换的方法。除了 GridView 之外,一切都运行良好,它似乎被卡住了。列表视图垂直滚动但最多只有 6 个项目,列表包含 9 个。我希望 GridView 以与列表视图滚动相同的方式滚动直到结束。我同时花了 2 个小时来搜索解决方案,但 none 有效。我试过了,ScrollView,NestedScrollView,还是无法解决

网格视图 = 带有 GridLayoutManager 的 RecyclerView

截图如下:

这个最多可以隐藏 6 个项目并隐藏 9 个项目中的 3 个

这个不滚动(仅 GridView)

代码如下:

activity_main.xml

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/frameLayout_imageContainer"
        android:layout_width="match_parent"
        android:layout_height="180dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/iv_house"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            app:srcCompat="@drawable/house" />

    </FrameLayout>

    <LinearLayout
        android:id="@+id/linearLayout_btnContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="8dp"
        android:gravity="end"
        android:orientation="horizontal"
        app:layout_constraintTop_toBottomOf="@id/frameLayout_imageContainer">

        <ImageButton
            android:id="@+id/btnListView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/btn_gradient_purple"
            android:padding="8dp"
            android:tint="@color/colorWhite"
            app:srcCompat="@drawable/ic_list" />

        <ImageButton
            android:id="@+id/btnGridView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:background="@drawable/btn_gradient_purple"
            android:padding="8dp"
            android:tint="@color/colorWhite"
            app:srcCompat="@drawable/ic_grid" />

    </LinearLayout>


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_room"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp"
        app:layout_constraintTop_toBottomOf="@+id/linearLayout_btnContainer">

    </androidx.recyclerview.widget.RecyclerView>


</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private lateinit var mRoomList: ArrayList<Room>

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

        val roomTypeBedroom = RoomType("Bedroom", R.drawable.ic_bedroom)
        val roomTypeKitchen = RoomType("Kitchen", R.drawable.ic_kitchen)
        val roomTypeBathroom = RoomType("Bathroom", R.drawable.ic_bathroom)
        val roomTypeLiving = RoomType("Living", R.drawable.ic_living)
        val roomTypeDining = RoomType("Dining", R.drawable.ic_dinning)
        val roomTypeEmpty = RoomType("Empty", R.drawable.ic_empty)

        mRoomList = arrayListOf(
                Room("Bedroom 1", R.drawable.bedroom_1, 1, roomTypeBedroom),
                Room("Bedroom 2", R.drawable.bedroom_2, 2, roomTypeBedroom),
                Room("Bedroom 3", R.drawable.bedroom_3, 3, roomTypeBedroom),
                Room("Kitchen", R.drawable.kitchen, 4, roomTypeKitchen),
                Room("Bathroom", R.drawable.bathroom, 5, roomTypeBathroom),
                Room("Living Room", R.drawable.living, 6, roomTypeLiving),
                Room("Dining Room", R.drawable.sitting_area, 7, roomTypeDining),
                Room("Empty Room 1", R.drawable.empty_1, 8, roomTypeEmpty),
                Room("Empty Room 2", R.drawable.empty_2, 9, roomTypeEmpty)

        )

        showRoomsAs(ViewType.GRID)


        btnGridView.setOnClickListener {
            showRoomsAs(ViewType.GRID)
        }

        btnListView.setOnClickListener {
            showRoomsAs(ViewType.LIST)
        }

    }

    private fun showRoomsAs(viewType: ViewType) {

        val roomAdapter = RoomAdapter(
                this,
                mRoomList,
                viewType,
                frameLayout_imageContainer
        )


        if (viewType == ViewType.GRID) {
            rv_room.layoutManager = GridLayoutManager(this, 3)
            btnGridView.visibility = View.GONE
            btnListView.visibility = View.VISIBLE
        } else {
            rv_room.layoutManager = LinearLayoutManager(this)
            btnGridView.visibility = View.VISIBLE
            btnListView.visibility = View.GONE
        }

        rv_room.adapter = roomAdapter
    }


}

RoomAdapter.k

import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class RoomAdapter(
        private val context: Context,
        private val rooms: ArrayList<Room>,
        private val type: ViewType,
        private val imageContainer: FrameLayout)
    : RecyclerView.Adapter<RoomAdapter.RoomViewHolder>() {


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RoomViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        var view: View? = null
        if (type == ViewType.GRID)
            view = inflater.inflate(R.layout.rv_item_grid, parent, false)
        else if (type == ViewType.LIST)
            view = inflater.inflate(R.layout.rv_item_list, parent, false)

        return RoomViewHolder(view!!)
    }

    override fun getItemCount(): Int {
        return rooms.size
    }

    override fun onBindViewHolder(holder: RoomViewHolder, position: Int) {
        val room = rooms[position]
        holder.icon.setBackgroundResource(room.type.icon)
        holder.name.text = room.name
        holder.type.text = room.type.type
        holder.status.text = room.isRoomOnOrOff()
    }

    inner class RoomViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
        override fun onClick(p0: View?) {
            val room = rooms[adapterPosition]
            if (room.associatedImageView == null) {
                val imageView = ImageView(context)

                imageView.layoutParams = ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT
                )

                imageView.setImageResource(room.image)

                room.associatedImageView = imageView
                imageContainer.addView(imageView)

            }

            if (room.isOn) {

                room.associatedImageView?.visibility = View.GONE
                room.isOn = false
            } else {
                room.associatedImageView?.visibility = View.VISIBLE
                room.isOn = true
            }

            notifyDataSetChanged()

        }

        val icon: ImageView
        val name: TextView
        val type: TextView
        val status: TextView

        init {
            itemView.setOnClickListener(this)

            icon = itemView.findViewById(R.id.rv_item_icon) as ImageView
            name = itemView.findViewById(R.id.rv_room_name) as TextView
            type = itemView.findViewById(R.id.rv_room_type) as TextView
            status = itemView.findViewById(R.id.rv_status) as TextView
        }

    }
}

我们将不胜感激任何形式的快速帮助

ConstraintLayout 有时会很棘手。您的 recyclerView 可能距离应用程序的视口只有几英寸远。您可以在 recyclerView

上尝试以下属性

选项 1:使用大填充

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_room"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="250dp"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:paddingBottom ="20dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="parent">

</androidx.recyclerview.widget.RecyclerView>

选项 2:使用 app:layout_constraintBottom_toBottomOf

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_room"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingTop="250dp"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:paddingBottom ="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/linearLayout_btnContainer">

</androidx.recyclerview.widget.RecyclerView>

在第二个选项中添加 app:layout_constraintBottom_toBottomOf="parent" 强制 recyclerView 的底部粘在 constraintLayout 的底部而不溢出