You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

屏幕旋转后如何重新创建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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:15:55