问题
The app contains two buttons, one for ListView and other for GridView, so I created to ItemViews and one adapter. I have created method, to switch between ListView and GridView. Every thing is working fine, except the GridView, which seems like it is jammed. List View is scrolling vertically but only upto 6 items, the list contains 9. I want the GridView to scroll in same fashion as List View scrolls until end. I have spent 2 simultaneous hours for searching solution, but none has worked. I have tried, ScrollView, NestedScrollView, but still unable to solve.
Grid View = RecyclerView with GridLayoutManager
Here is screenshot:
This one works fine upto 6 item and hide 3 out of 9
This one don't scroll (only GridView)
Here is Code:
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
}
}
}
any kind of quick help will be appreciated
回答1:
ConstraintLayout
can be tricky sometimes. Your recyclerView
might be sitting inches away from app's view port. You can try the below attributes on your recyclerView
Option 1 : use of large padding
<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>
Option 2: Use of 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>
Adding app:layout_constraintBottom_toBottomOf="parent"
in second option forces the bottom of the recyclerView stick to the bottom of constraintLayout
and not overflow
来源:https://stackoverflow.com/questions/57421970/recycler-view-with-gridlayoutmanager-not-scrolling