Xamarin跨Activity导航后编程创建的动态布局丢失如何解决
问题原因
Activity导航离开再返回时会重新走生命周期初始化视图,你仅在交互时动态添加的View没有对应的持久化状态存储,视图重建时只会加载XML里的固定布局,之前动态添加的内容就会丢失。
解决步骤
- 定义数据源存储动态项配置
不要直接只添加View,先把每个动态行的配置存到全局列表,方便后续重绘时读取:
// 全局变量,存储所有动态行的配置 private List<DynamicLineConfig> _dynamicLines = new List<DynamicLineConfig>(); // 自定义配置类,可根据业务需求扩展字段,比如存储行内输入框内容、选择状态等 public class DynamicLineConfig { public int LineId { get; set; } // 可自行添加其他需要保存的字段 }
- 修改动态添加逻辑,操作时同步更新数据源
private void AddNewDynamicLine() { // 先更新数据源 var newLineConfig = new DynamicLineConfig() { LineId = 500 + _dynamicLines.Count // 避免ID重复 }; _dynamicLines.Add(newLineConfig); // 再创建View添加到布局 var layout = new LinearLayout(this); layout.Orientation = Orientation.Horizontal; layout.Id = newLineConfig.LineId; Button btnRemove = new Button(this); btnRemove.Text = "-"; btnRemove.TextAlignment = TextAlignment.Center; // 删除按钮点击逻辑,同步更新数据源和布局 btnRemove.Click += (s,e) => { _dynamicLines.Remove(newLineConfig); dynamicL.RemoveView(layout); }; layout.AddView(btnRemove); dynamicL.AddView(layout); }
- 在OnResume生命周期中重绘所有动态View
每次页面回到前台时,根据存储的数据源重新渲染所有动态内容,避免丢失:
protected override void OnResume() { base.OnResume(); // 先清空已有动态View,避免重复添加 dynamicL.RemoveAllViews(); // 遍历数据源重绘所有动态行 foreach(var lineConfig in _dynamicLines) { var layout = new LinearLayout(this); layout.Orientation = Orientation.Horizontal; layout.Id = lineConfig.LineId; Button btnRemove = new Button(this); btnRemove.Text = "-"; btnRemove.TextAlignment = TextAlignment.Center; btnRemove.Click += (s,e) => { _dynamicLines.Remove(lineConfig); dynamicL.RemoveView(layout); }; layout.AddView(btnRemove); // 有其他控件的话,也根据lineConfig存储的状态恢复内容 dynamicL.AddView(layout); } }
可选优化
如果需要在页面旋转、应用后台被系统回收后也保留动态布局,可以把_dynamicLines列表序列化后存到OnSaveInstanceState的Bundle中,在OnCreate时从Bundle读取恢复数据源即可。
内容的提问来源于stack exchange,提问作者sulabh
相关产品推荐
相关产品推荐

