【问题标题】:Save state of Activity that contains Buttons when you press back button android按下后退按钮时保存包含按钮的 Activity 状态 android
【发布时间】:2018-11-21 13:24:38
【问题描述】:

我有一个活动,用户可以在其中选择应该创建多少个按钮。如果用户在 AlertDialog Builder 中的 EditText 中键入 5,则以编程方式创建 5 个按钮。 如果我回去,创建的按钮就消失了。如何保存 Activity 中的 5 个按钮?

这是我动态创建按钮的代码:

AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("How many Buttons?");
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_NUMBER);
input.setRawInputType(Configuration.KEYBOARD_12KEY);

alert.setView(input);
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
   public void onClick(DialogInterface dialog, int whichButton) {
      String persons = input.getText().toString();
      try {
         personsnumber = Integer.parseInt(persons);
      } catch (NumberFormatException nfe) {}
      Button[] buttons = new Button[personsnumber];
      for (int l = 0; l < personsnumber; l++) {
         buttons[l] = new Button(HandleTableClick.this);
         buttons[l].setTextSize(20);
         buttons[l].setLayoutParams(lp);
         buttons[l].setId(l);
         buttons[l].setText("Person" + (l + 1) + "bblabla");

         // myLayout.addView(pairs[l]);
         myLayout.addView(buttons[l]);
      }
   }
});
alert.show();

我知道我必须重写 OnBackPress 方法,但我不知道应该使用什么代码来保存状态。

【问题讨论】:

  • 显示你的布局?
  • @SushilKumar 布局只包含一个线性布局。没有其他的。我不明白为什么要提到这一点很重要?
  • 用于相应地制定逻辑。如果它有什么,那么你必须使用boolean flag

标签: android android-savedstate


【解决方案1】:

您将使用实现onSaveInstanceState() 的默认方式保存按钮状态。

您将创建一个保存按钮状态的类。该类将实现Parcelable,,以便将其作为ArrayList&lt;Parcelable&gt; 传递给onSaveInstanceState() 中的Bundle 参数。

Here is the source of this answer.

编辑:

我相信这是实现背后的主要思想,它很简单,但是我缺少有关按钮创建的一些内容,并且按钮在旋转后奇怪地创建了。奇怪的是,我的意思是背景不是默认值,而且字体更大,这是不应该的,因为我设置了相同的大小(是吗,对吗?)。

为了证明某些状态被保留,您可以从按钮的文本中看到它,如果您按下按钮,也可以从背景颜色中看到它。

主要活动:

public class MainActivity extends AppCompatActivity {

    private static final String EXTRA_BUTTONS = "extra button list";
    private static final int BUTTONS_COUNT = 5;
    private ArrayList<Button> createdButtons = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout root = findViewById(R.id.root);

        if (savedInstanceState == null) {
            createButtonsForTheFirstTime(root);
        } else {
            createButtonsFromState(savedInstanceState, root);
        }

    }


    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        ArrayList<ButtonViewState> states = new ArrayList<>();
        for (int i = 0; i < BUTTONS_COUNT; i++) {
            states.add(ButtonViewState.create(createdButtons.get(i)));
        }
        outState.putParcelableArrayList(EXTRA_BUTTONS, states);
    }

    private void createButtonsForTheFirstTime(LinearLayout root) {
        for (int i = 0; i < BUTTONS_COUNT; i++) {
            Button button = createButton(i);
            // Save the button so we can retrieve them when we want to save their state
            createdButtons.add(button);
            // I added the listener which changes the color onClick to prove that state remains
            button.setOnClickListener((view) -> view.setBackgroundColor(Color.GREEN));
            root.addView(button);
        }
    }

    private void createButtonsFromState(Bundle savedInstanceState, LinearLayout root) {
        ArrayList<ButtonViewState> states = savedInstanceState.getParcelableArrayList(EXTRA_BUTTONS);
        for (ButtonViewState state : states) {
            Button button = createButtonFrom(state);
            button.setOnClickListener((view) -> view.setBackgroundColor(Color.GREEN));
            root.addView(button);
            createdButtons.add(button);
        }
    }

    @NonNull
    private Button createButton(int id) {
        Button button = new Button(this);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        button.setLayoutParams(params);
        button.setText("Button " + id);
        button.setId(id);
        button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 25);
        return button;
    }

    private Button createButtonFrom(ButtonViewState state) {
        Button button = new Button(this);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
        button.setLayoutParams(params);
        button.setTextSize(TypedValue.COMPLEX_UNIT_SP,state.textSize);
        button.setText(state.text);
        button.setBackgroundColor(state.backgroundColor);
        return button;
    }

    static class ButtonViewState implements Parcelable {

        String text;
        int width, height, id;
        float textSize;
        int backgroundColor;

        private ButtonViewState(Button button) {
            text = button.getText().toString();
            width = button.getLayoutParams().width;
            height = button.getLayoutParams().height;
            textSize = button.getTextSize();
            id = button.getId();
            initializeBackgroundColor(button);
        }

        protected ButtonViewState(Parcel in) {
            text = in.readString();
            width = in.readInt();
            height = in.readInt();
            id = in.readInt();
            textSize = in.readFloat();
            backgroundColor = in.readInt();
        }

        public static final Creator<ButtonViewState> CREATOR = new Creator<ButtonViewState>() {
            @Override
            public ButtonViewState createFromParcel(Parcel in) {
                return new ButtonViewState(in);
            }

            @Override
            public ButtonViewState[] newArray(int size) {
                return new ButtonViewState[size];
            }
        };

        private void initializeBackgroundColor(Button button) {
            try {
                ColorDrawable drawable = (ColorDrawable) button.getBackground();
                backgroundColor = drawable.getColor();
            } catch (ClassCastException e) {
                Log.e("MainActivity", "Background of button is not a color");
            }
        }

        static ButtonViewState create(Button button) {
            return new ButtonViewState(button);
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel parcel, int i) {
            parcel.writeString(text);
            parcel.writeInt(width);
            parcel.writeInt(height);
            parcel.writeInt(id);
            parcel.writeFloat(textSize);
            parcel.writeInt(backgroundColor);
        }
    }

}

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="32sp" />


</LinearLayout>

奇怪的部分:

首次创建活动时

点击一个按钮

旋转后(某些状态是保留、文本、颜色,这里有人可以帮忙)

【讨论】:

  • 很遗憾没有帮到我。
  • 真的吗?让我也去看看。
  • 因为没有说明如何创建这个类。
  • 我会尝试这样做,如果可行,我会将代码添加到这个答案中。
  • 非常感谢您的帮助。
猜你喜欢
  • 2012-08-23
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多