[英]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.