[英]Saving the instance of Recycler view during orientation change
我有一个使用Arraylist
构建的RecyclerView
。 该Arraylist
由名为ListItem
的用户定义对象组成。
每个recyclerview
视图都有一个卡片视图。 每个CardView
保存每个ListItem
。 我已经从RecyclerView
删除了一个CardView
。
当我旋转屏幕时,会创建一个新活动,从而显示旧数据。 但我希望recyclerview
只保存updated list
并且应该retain
scrolled position
。
列表项类:
class ListItem(var title: String, var info: String, val imageResource: Int) {
}
主活动类:
class MainActivity : AppCompatActivity() {
private lateinit var mSportsData: ArrayList<ListItem>
private lateinit var mAdapter: MyAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val gridColumnCount = resources.getInteger(R.integer.grid_column_count)
recycler_view.layoutManager = GridLayoutManager(this,gridColumnCount)
mSportsData = ArrayList()
recycler_view.setHasFixedSize(true)
initializeData()
recycler_view.adapter = mAdapter
var swipeDirs = 0
if (gridColumnCount <= 1) {
swipeDirs = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
}
val helper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT or ItemTouchHelper.UP or ItemTouchHelper.DOWN,swipeDirs) {
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
val from = viewHolder.adapterPosition
val to = target.adapterPosition
Collections.swap(mSportsData,from,to)
mAdapter.notifyItemMoved(from,to)
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
mSportsData.removeAt(viewHolder.adapterPosition)
mAdapter.notifyItemRemoved(viewHolder.adapterPosition)
}
})
helper.attachToRecyclerView(recycler_view)
}
private fun initializeData() {
val sportsList : Array<String> = resources.getStringArray(R.array.sports_titles)
Log.d("Printing","$sportsList")
val sportsInfo : Array<String> = resources.getStringArray(R.array.sports_info)
val sportsImageResources : TypedArray = resources.obtainTypedArray(R.array.sports_images)
mSportsData.clear()
for (i in sportsList.indices-1) {
Log.d("Printing","${sportsList[i]},${sportsInfo[i]},${sportsImageResources.getResourceId(i,0)}")
mSportsData.add(ListItem(sportsList[i], sportsInfo[i], sportsImageResources.getResourceId(i, 0)))
}
sportsImageResources.recycle()
mAdapter = MyAdapter(mSportsData,this)
mAdapter.notifyDataSetChanged()
}
fun resetSports(view: View) {
initializeData()
}
}
MyAdapter 类:
class MyAdapter(var mSportsData: ArrayList<ListItem>, var context: Context) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.wordlist_item,parent,false))
}
override fun getItemCount() = mSportsData.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val listItem = mSportsData.get(position)
holder.bindTo(listItem)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
init {
itemView.setOnClickListener(this)
}
override fun onClick(view: View) {
val currentSport = mSportsData.get(adapterPosition)
val detailIntent = Intent(context, DetailActivity::class.java)
detailIntent.putExtra("title", currentSport.title)
detailIntent.putExtra("image_resource", currentSport.imageResource)
context.startActivity(detailIntent)
}
fun bindTo(currentSport : ListItem){
itemView.heading_textview.setText(currentSport.title)
itemView.description_textview.setText(currentSport.info)
Glide.with(context).load(currentSport.imageResource).into(itemView.image_view)
}
}
}
如果纵向和横向模式的布局相同,则可以限制在清单中重新启动活动。
将此添加到清单中的活动中。
<activity android:name=".activity.YourActivity"
android:label="@string/app_name"
android:configChanges="orientation|screenSize"/>
如果您不想限制屏幕方向更改,则可以使用OnSaveInstanceState
方法在方向更改时保存旧数据。 您通过此方法保存的任何数据都将在您的OnCreate
方法中接收到bundle
。 这是帮助链接。 所以在这里,当您拥有自己的类类型的ArrayList
,您还需要使用Serializable或Parcelable将您的 ArrayList 放入您的 Bundle 中。
除了这些将ArrayList
设为public static
始终是一个解决方案,但它在面向对象的 paratime 中不是一个好的解决方案。 在内存不足的情况下,它还可以为您提供NullPointerException
或数据丢失。
看起来像 initializeData 被调用了两次,因为 onCreate 在方向改变时再次被调用,你可以使用一些布尔值来检查数据是否已经被初始化然后跳过初始化
您正在做的是删除传递给 recyclerview 的值,但是当方向更改时,recyclerview 从活动重新加载,并且活动中的原始数据再次传递,并且没有任何变化,因此如果您想保存更改recyclerview 您必须更改活动中的原始数据,以便视图重新加载时数据是相同的。
我认为您在 oncreate 方法中初始化适配器,其中将重新创建整个适配器,并且在配置更改时也会新创建所有数据。 因为你在 oncreate 方法中初始化数据。 尝试全局维护列表,并在您在适配器中删除时也删除活动中列表中的项目。 或者尝试类似视图模型架构的东西
在项目中使用MVVM
模式。 它将管理方向状态。
MVVM RecyclerView 示例: https : //medium.com/@Varnit/android-data-binding-with-recycler-views-and-mvvm-a-clean-coding-approach-c5eaf3cf3d72
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.