我有一个嵌套的recyclerview,看起来应该像中的样子。
我根据this helpful site实现了它。
问题是,有时我的用户有数百个项目,在这种情况下,打开活动要花费半分钟。
我在后端有一个会议室数据库,带有两个带有外键(用户和项目)的链接表,我选择所有用户以获取用户/项目列表,其中项目是用户表中的列表。
class userWithItems:(id:Int,name:String,...,List)
然后用适配器中的项目列表创建内部回收站视图。
最好制作一个列表UserItems(userid:Int,username:String,... itemid:Int,itemList)并将它们分组为外部rv。
或者是否有可能摆脱嵌套的rv,仅用一个recyclerview-list进行设计?
还是有另一种解决方案,即使用户有很多物品也可以使嵌套的recyclerview工作?
适配器的代码:
// Code in Activity: (oncreate)
val recyclerView = findViewById<RecyclerView>(R.id.rv_users)
val adapter = UserAdapter(this)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this)
mainViewModel = ViewModelProviders.of(this, PassIntViewModelFactory(this.application, online_id)).get(MainViewModel::class.java!!)
mainViewModel.userList.observe(this, Observer {
it?.let {
adapter.setUserList(it)
}
})
数据类UsersWithItems(
val id:Int, val username: String, val address, // fields from user table
val items: List<Items> // list of items for current user
)
数据类项目( val id:Int,val itemtext:字符串,val itemlocation:字符串,val image:字符串// ... )
// UserAdapter(外部)
class UserAdapter内部构造函数( 上下文:上下文 ):RecyclerView.Adapter(){
private val inflater: LayoutInflater = LayoutInflater.from(context)
private var userList = emptyList<UsersWithItems>()
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val username: TextView = itemView.findViewById(R.id.user_name)
val num_pos: TextView = itemView.findViewById(R.id.user_num_pos)
val address: TextView = itemView.findViewById(R.id.user_addr)
val rv:RecyclerView = itemView.findViewById(R.id.rv_user_items)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val myItemView = inflater.inflate(R.layout.rv_row_user, parent, false)
return MyViewHolder(myItemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val current = userList[position]
holder.username.text="${current.user?.username}"
holder.num_pos.text="${current.items?.size}"
holder.address.text = "${current.user?.address}"
val adapter = UserItemAdapter(holder.rv.context)
adapter.setItems(current.items!!)
holder.rv.adapter = adapter
holder.rv.layoutManager = LinearLayoutManager(holder.rv.context,LinearLayout.VERTICAL,false)
}
internal fun setUserList(userList: List<UsersWithItems>){
this.userList=userList
notifyDataSetChanged()
}
override fun getItemCount() = userList.size
}
class UserItemAdapter内部构造函数( 上下文:上下文 ):RecyclerView.Adapter(){
private val inflater: LayoutInflater = LayoutInflater.from(context)
private var itemList = emptyList<Items>()
inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val itemtext: TextView = itemView.findViewById(R.id.item_text)
val itemlocation:TextView = itemView.findViewById(R.id.item_location)
val image: ImageView = itemView.findViewById(R.id.item_image)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val myItemView = inflater.inflate(R.layout.rv_row_user_items, parent, false)
return MyViewHolder(myItemView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val current = itemList[position]
holder.itemtext.text="${current.itemtext}"
holder.itemlocation.text = current.itemlocation
if (current.image.length>0) {
val image = Base64.decode(current.image, 0)
val bitmap = BitmapFactory.decodeByteArray(image, 0, image.size)
holder.image.setImageBitmap(bitmap)
}
}
internal fun setItems(items: List<Items>){
this.itemList=items
notifyDataSetChanged()
}
override fun getItemCount() = itemList.size
}
答案 0 :(得分:0)
E。 Reuter我已经经历过这种情况,问题是使用嵌套的Recycler View方法是非常正确的。您的代码似乎不错。但是您要用来查询数据库的查询。我认为您应该在后台或其他威胁中使用查询,并在获得查询时显示结果,而不是从OnCreate或主线程中查询。因为一次性获得这么多项目可能会导致活动滞后并降低性能。如果您还没有尝试,请告诉我。怎么了。谢谢...
我正在编辑我的答案。您可以做的另一件事是,如果您有超过一定数量的物品,那么您不应该首先使用分页之类的方法一次加载一定数量的物品,以免出现这种情况。
我在这里附加代码以查询每次加载一定数量的数据。...
SApp.database!!.resultDao().loadAllUsersByPage(5, 10)
@Query("SELECT * FROM Result LIMIT :limit OFFSET :offset")
fun loadAllUsersByPage(limit: Int, offset: Int): List<Result>
答案 1 :(得分:0)
非常感谢您的回答。我认为分页确实是一种好方法。但是我无法直接添加页面,因为我是从这样的roomdatabase获取数据的:
@Query(SELECT * FROM users)
fun getData(): LiveData<List<userWithItems>>
由于用户和项目之间的关系,实际项目是按房间添加的,我将不得不更改此行为。
我会尝试类似的东西
@Query(SELECT * FROM users)
fun getUserData(): LiveData<List<Users>>
,然后尝试在外部recyclerview中添加LiveData观察器,以在使用分页的单独查询中获取项目。
答案 2 :(得分:0)
我解决了这个问题。当我想到分页时,我想到的问题可能是内部recyclerview的高度为wrap_content,因此需要构建所有项目并使rv无效。当我将内部rv的高度设为250dp时,它甚至可以处理2000个项目。
因此,现在我只需要找出一种始终为内部rv找到最佳高度并解决滚动问题的方法,但是原来的问题就解决了。
特别感谢Aman B!