屏幕旋转后如何重新创建LinearLayout中的视图?
问题分析与解决方案
咱们直接说核心问题:你的代码里有几个明显的bug,导致屏幕旋转后视图没被正确重建——虽然数据大概率保存下来了,但视图恢复的逻辑根本没执行,再加上Parcelable实现不完整,也可能影响了数据恢复。
1. 视图恢复的循环条件完全错误
你在onCreate里恢复视图的循环写反了,根本不会执行:
if(mListCollection == null){ int count = 0; }else{ int count = mListCollection.size(); // 这里i初始等于count,i<count永远不成立,循环一次都不会跑! for(int i = count; i<count; i++) { TextView tv = new TextView(getApplicationContext()); tv.setText("saved Voc List " + (i + 1)); ll.addView(tv); Button btn = new Button(getApplicationContext()); btn.setText("Start saved Voc List " + (i + 1)); } }
修复方法:把循环改成从0开始遍历mListCollection的所有元素,同时补上漏加按钮的代码:
if(mListCollection != null){ int count = mListCollection.size(); // 从0开始,遍历到集合末尾 for(int i = 0; i < count; i++) { // 用Activity上下文代替Application上下文,避免样式/内存问题 TextView tv = new TextView(LoadActivity.this); tv.setText("saved Voc List " + (i + 1)); ll.addView(tv); Button btn = new Button(LoadActivity.this); btn.setText("Start saved Voc List " + (i + 1)); ll.addView(btn); // 你原来的代码漏了这一步! } }
2. VocCollection的Parcelable实现不完整
你贴的VocCollection代码只写了一半,这样根本无法正确序列化/反序列化数据,mListCollection可能在恢复时为空或数据损坏。
完整的Parcelable实现(前提是VocCard已正确实现Parcelable):
package com.dede123.smartcards.vocdata; import android.os.Parcel; import android.os.Parcelable; import com.dede123.smartcards.VocCard; import java.util.ArrayList; public class VocCollection extends ArrayList<ArrayList<VocCard>> implements Parcelable { // 必须保留空构造函数 public VocCollection() { super(); } protected VocCollection(Parcel in) { // 先读取集合大小,再逐个读取子列表 int size = in.readInt(); for (int i = 0; i < size; i++) { ArrayList<VocCard> subList = in.readArrayList(VocCard.class.getClassLoader()); this.add(subList); } } public static final Creator<VocCollection> CREATOR = new Creator<VocCollection>() { @Override public VocCollection createFromParcel(Parcel in) { return new VocCollection(in); } @Override public VocCollection[] newArray(int size) { return new VocCollection[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // 先写入集合大小,再逐个写入子列表 dest.writeInt(this.size()); for (ArrayList<VocCard> subList : this) { dest.writeList(subList); } } }
3. 优化数据保存/恢复的写法
你原来用putParcelableArrayList保存VocCollection,但其实VocCollection本身就是Parcelable对象,直接用putParcelable/getParcelable更准确:
修改onSaveInstanceState:
@Override public void onSaveInstanceState(Bundle savedInstanceState) { // 直接保存VocCollection对象 savedInstanceState.putParcelable(STATE_COLLECTION, mListCollection); super.onSaveInstanceState(savedInstanceState); }
修改onCreate里的恢复逻辑:
if (savedInstanceState != null) { mListCollection = savedInstanceState.getParcelable(STATE_COLLECTION); }
onRestoreInstanceState同步修改:
@Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mListCollection = savedInstanceState.getParcelable(STATE_COLLECTION); }
4. 不要用Application上下文创建视图
你创建TextView和Button时用了getApplicationContext(),这会导致视图样式与Activity不一致,甚至引发内存泄漏。统一改成LoadActivity.this作为上下文。
最后检查点
- 确保
VocCard类也正确实现了Parcelable接口,否则VocCollection的序列化会失败。 - 点击创建按钮时,确认新创建的
btn已经添加到ll中(你原来的代码漏了这一步)。
按照这些修改后,屏幕旋转后应该能正确恢复所有动态创建的视图了。
内容的提问来源于stack exchange,提问作者Schelmuffsky
相关产品推荐
相关产品推荐

