首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >保存动态添加的LinearLayouts而不使用savedInstanceState?

保存动态添加的LinearLayouts而不使用savedInstanceState?
EN

Stack Overflow用户
提问于 2013-09-12 06:54:50
回答 1查看 2.2K关注 0票数 1

我有一个布局,在这个布局中,我按下一个按钮就动态地添加了自定义视图。这些布局扩展了LinearLayout,每个布局都带有自己独特的Action对象。

但是,当用户导航或旋转屏幕时,如果再次调用onCreate,视图将消失。我想将这些自定义ActionHolder视图保存在那里。为了增加问题,ActionHolder对象包含敏感信息。Action对象自己存储一个实时计时器(即使应用程序关闭,它也应该继续滴答作响)以及其他信息。

根据下面的答复,我做了以下工作,但没有结果。以下是我到目前为止所拥有的:

代码语言:javascript
复制
public class ActionHolder extends LinearLayout implements Serializable {

   /**
    * 
    */
   private static final long serialVersionUID = 2271402255369440088L;
   private Action action;
   private String timer;
   public static final int ACTION_TITLE = 0, ACTION_TIMER = 1,
         PAUSEANDPLAY_BTN = 2, FINISH_BTN = 3;



   public ActionHolder(Context context) {
      super(context);
   }



   public ActionHolder(Context context, AttributeSet attr) {
      super(context, attr);
   }



   public ActionHolder(Context context, AttributeSet attr, int defStyle) {
      super(context, attr, defStyle);
   }



   public void initiate(Action input) {
      // int hashedID = input.getActionName().hashCode();
      // if (hashedID < 0)
      // hashedID *= -1;
      // this.setId(hashedID);
      this.setOrientation(LinearLayout.VERTICAL);
      this.setLayoutParams(new LinearLayout.LayoutParams(
            LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
      action = input;
      LayoutInflater inflater = LayoutInflater.from(getContext());
      View view = inflater.inflate(R.layout.action_holder_layout, this, true);

      TextView actionTitle = (TextView) view
            .findViewById(com.tonimiko.mochi_bean.R.id.action_holder_title);
      actionTitle.setText(action.getActionName());
      actionTitle.setId(ActionHolder.ACTION_TITLE);

      TextView actionTimer = (TextView) view
            .findViewById(R.id.action_holder_timer);
      actionTimer.setId(ActionHolder.ACTION_TIMER);

      Button pauseBtn = (Button) view
            .findViewById(com.tonimiko.mochi_bean.R.id.pause_and_play_timer_btn);
      pauseBtn.setId(ActionHolder.PAUSEANDPLAY_BTN);

      Button finishBtn = (Button) view
            .findViewById(com.tonimiko.mochi_bean.R.id.finish_activity_button);
      finishBtn.setId(ActionHolder.FINISH_BTN);

      action.setActivityStartTime();
   }



   public Action finishAction() {
      action.setActivityStopTime();
      return action;
   }



   @Override
   protected void onLayout(boolean changed, int l, int t, int r, int b) {
      super.onLayout(changed, l, t, r, b);
   }



   public String toString() {
      return "Action stored: " + action.getActionName();
   }



   @Override
   public boolean equals(Object other) {
      ActionHolder otherObj = (ActionHolder) other;
      if (this.action.getActionName().toUpperCase()
            .equals(otherObj.action.getActionName().toUpperCase()))
         return true;
      return false;
   }



   @Override
   public int hashCode() {
      return action.getActionName().hashCode();
   }



   @Override
   protected Parcelable onSaveInstanceState() {
      Parcelable superState = super.onSaveInstanceState();
      Bundle data = new Bundle();
      data.putString("Timer", timer);
      data.putSerializable("Action", action);
      Log.e("debug", "View onSaveInstanceState called!"); // TODO
      Parcelable test = new ActionHolderSavedState(superState, data);
      if(test==null)
         Log.e("debug", "NULL PARCELABLE"); // TODO
      return new ActionHolderSavedState(superState, data);
   }



   @Override
   protected void onRestoreInstanceState(Parcelable state) {
      Log.e("debug", "View onRestore called!");
      if (state instanceof ActionHolderSavedState) {
         final ActionHolderSavedState savedState = (ActionHolderSavedState) state;
         this.action = savedState.getAction();
         this.timer = savedState.getTimer();
         // this.initiate(action);
         super.onRestoreInstanceState(savedState.getSuperState());
         Log.e("debug", "View onRestoreInstanceState finished"); // TODO
      }
   }

   static class ActionHolderSavedState extends BaseSavedState {

      private Action storedAction;
      private String storedTimer;



      public ActionHolderSavedState(Parcelable superState, Bundle data) {
         super(superState);
         storedTimer = data.getString("Timer");
         storedAction = (Action) data.getSerializable("Action");
      }



      private ActionHolderSavedState(Parcel in) {
         super(in);
         storedTimer = in.readString();
         storedAction = in.readParcelable(ActionHolder.class.getClassLoader());
      }



      public Action getAction() {
         return storedAction;
      }



      public String getTimer() {
         return storedTimer;
      }



      @Override
      public void writeToParcel(final Parcel out, final int flags) {
         super.writeToParcel(out, flags);
         out.writeString(storedTimer);
         out.writeSerializable(storedAction);
      }

      // required field that makes Parcelables from a Parcel
      public static final Parcelable.Creator<ActionHolderSavedState> CREATOR = new Parcelable.Creator<ActionHolderSavedState>() {

         public ActionHolderSavedState createFromParcel(final Parcel in) {
            return new ActionHolderSavedState(in);
         }



         public ActionHolderSavedState[] newArray(int size) {
            return new ActionHolderSavedState[size];
         }
      };
   }
}

我做错什么了吗?我已经花了将近4天在这件事上。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-12 08:27:22

我的情况非常类似于您的情况,自定义视图将动态添加到屏幕上,并且需要在操作系统杀死活动并在稍后重新创建时保存状态。

我正在自定义视图上重写onSaveInstanceState。它需要返回一个Parcelable对象。关键是创建一个扩展BaseSavedState并将数据存储到该Parcelable中的自定义类。它看起来有点像这样:

@重写受保护的Parcelable onSaveInstanceState() { final = super.onSaveInstanceState();返回新的ContainerLayoutSavedState (状态、数据);}@onRestoreInstanceState(最终Parcelable状态){ if ( ContainerLayoutSavedState savedState = ( ContainerLayoutSavedState) state;this.data = savedState.getData();this.data}}公共静态类ContainerLayoutSavedState扩展BaseSavedState {私有字符串数据;ContainerLayoutSavedState(final Parcelable superState,final String data) { super(superState);//在此构造函数中,您将想要保存到Parcelable对象的任何东西注入。在这个精心设计的例子中,我们只是保存一个名为数据的字符串。this.data = data;}私有ContainerLayoutSavedState(最终包in) { super(in);data = in.readString();} public String getData()返回数据;}@覆盖公共无效writeToParcel(最终包出,最终int标志){ super.writeToParcel(out,标志);out.writeString(数据);} // required字段,该字段使来自包的Parcelable公共静态最终Parcelable.Creator创建者=新Parcelable.Creator() {@覆盖公共ContainerLayoutSavedState createFromParcel(最终包in) {返回新的ContainerLayoutSavedState(in);}@覆盖公共ContainerLayoutSavedState[] newArray(最终整数大小){返回新的ContainerLayoutSavedStatesize;};}}

另外,不要忘记将ID设置为动态添加的视图,因此当您返回视图树时,它们会重新添加到视图树中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18757381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档