Save state of Activity that contains Buttons when you press back button android
I have an activity where the user can choose how many button should be created. If the user types 5 in an EditText that is in an AlertDialog Builder, 5 buttons are created programmatically.
If I go back, the created Buttons are gone. How can I save the 5 buttons in the Activity?
This is my code that creates Buttons dynamically:
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();
I know that I have to override the OnBackPress
Method but I don't know what code I should use to save the state.
android android-savedstate
add a comment |
I have an activity where the user can choose how many button should be created. If the user types 5 in an EditText that is in an AlertDialog Builder, 5 buttons are created programmatically.
If I go back, the created Buttons are gone. How can I save the 5 buttons in the Activity?
This is my code that creates Buttons dynamically:
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();
I know that I have to override the OnBackPress
Method but I don't know what code I should use to save the state.
android android-savedstate
show your layout ?
– Sushil Kumar
Nov 21 '18 at 13:48
@SushilKumar the layout just contains a LinearLayout. nothing else. I don't see why that should be important to mention?
– Blnpwr
Nov 21 '18 at 13:49
for making logic accordingly. If it have something then you have to useboolean flag
– Sushil Kumar
Nov 21 '18 at 13:57
add a comment |
I have an activity where the user can choose how many button should be created. If the user types 5 in an EditText that is in an AlertDialog Builder, 5 buttons are created programmatically.
If I go back, the created Buttons are gone. How can I save the 5 buttons in the Activity?
This is my code that creates Buttons dynamically:
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();
I know that I have to override the OnBackPress
Method but I don't know what code I should use to save the state.
android android-savedstate
I have an activity where the user can choose how many button should be created. If the user types 5 in an EditText that is in an AlertDialog Builder, 5 buttons are created programmatically.
If I go back, the created Buttons are gone. How can I save the 5 buttons in the Activity?
This is my code that creates Buttons dynamically:
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();
I know that I have to override the OnBackPress
Method but I don't know what code I should use to save the state.
android android-savedstate
android android-savedstate
edited Nov 21 '18 at 13:42
kit
1,1063816
1,1063816
asked Nov 21 '18 at 13:24
BlnpwrBlnpwr
5391826
5391826
show your layout ?
– Sushil Kumar
Nov 21 '18 at 13:48
@SushilKumar the layout just contains a LinearLayout. nothing else. I don't see why that should be important to mention?
– Blnpwr
Nov 21 '18 at 13:49
for making logic accordingly. If it have something then you have to useboolean flag
– Sushil Kumar
Nov 21 '18 at 13:57
add a comment |
show your layout ?
– Sushil Kumar
Nov 21 '18 at 13:48
@SushilKumar the layout just contains a LinearLayout. nothing else. I don't see why that should be important to mention?
– Blnpwr
Nov 21 '18 at 13:49
for making logic accordingly. If it have something then you have to useboolean flag
– Sushil Kumar
Nov 21 '18 at 13:57
show your layout ?
– Sushil Kumar
Nov 21 '18 at 13:48
show your layout ?
– Sushil Kumar
Nov 21 '18 at 13:48
@SushilKumar the layout just contains a LinearLayout. nothing else. I don't see why that should be important to mention?
– Blnpwr
Nov 21 '18 at 13:49
@SushilKumar the layout just contains a LinearLayout. nothing else. I don't see why that should be important to mention?
– Blnpwr
Nov 21 '18 at 13:49
for making logic accordingly. If it have something then you have to use
boolean flag
– Sushil Kumar
Nov 21 '18 at 13:57
for making logic accordingly. If it have something then you have to use
boolean flag
– Sushil Kumar
Nov 21 '18 at 13:57
add a comment |
1 Answer
1
active
oldest
votes
You will save your buttons states using the default way which is implementing onSaveInstanceState()
.
You will create a class that will save the state of your buttons. That class would implement Parcelable,
in order to pass it as an ArrayList<Parcelable>
to the Bundle
parameter in onSaveInstanceState()
.
Here is the source of this answer.
Edit:
I believe this is the main idea behind the implementation, it's simple, yet I am missing something about the button creation and the buttons are weirdly created after rotating. By weirdly I mean that the background was not the default and the font is larger which it should not be because I am setting the same size (am I, right?).
To prove that some state is kept you can see it from the text of the button and also from the background color if you press the button.
The main activity:
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);
}
}
}
The layout:
<?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>
The weird part:
When activity is first created
Click a button
After rotatation (some state is preserve, text, color, someone could help here)
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 '18 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 '18 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 '18 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 '18 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 '18 at 14:16
|
show 5 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413044%2fsave-state-of-activity-that-contains-buttons-when-you-press-back-button-android%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You will save your buttons states using the default way which is implementing onSaveInstanceState()
.
You will create a class that will save the state of your buttons. That class would implement Parcelable,
in order to pass it as an ArrayList<Parcelable>
to the Bundle
parameter in onSaveInstanceState()
.
Here is the source of this answer.
Edit:
I believe this is the main idea behind the implementation, it's simple, yet I am missing something about the button creation and the buttons are weirdly created after rotating. By weirdly I mean that the background was not the default and the font is larger which it should not be because I am setting the same size (am I, right?).
To prove that some state is kept you can see it from the text of the button and also from the background color if you press the button.
The main activity:
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);
}
}
}
The layout:
<?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>
The weird part:
When activity is first created
Click a button
After rotatation (some state is preserve, text, color, someone could help here)
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 '18 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 '18 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 '18 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 '18 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 '18 at 14:16
|
show 5 more comments
You will save your buttons states using the default way which is implementing onSaveInstanceState()
.
You will create a class that will save the state of your buttons. That class would implement Parcelable,
in order to pass it as an ArrayList<Parcelable>
to the Bundle
parameter in onSaveInstanceState()
.
Here is the source of this answer.
Edit:
I believe this is the main idea behind the implementation, it's simple, yet I am missing something about the button creation and the buttons are weirdly created after rotating. By weirdly I mean that the background was not the default and the font is larger which it should not be because I am setting the same size (am I, right?).
To prove that some state is kept you can see it from the text of the button and also from the background color if you press the button.
The main activity:
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);
}
}
}
The layout:
<?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>
The weird part:
When activity is first created
Click a button
After rotatation (some state is preserve, text, color, someone could help here)
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 '18 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 '18 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 '18 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 '18 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 '18 at 14:16
|
show 5 more comments
You will save your buttons states using the default way which is implementing onSaveInstanceState()
.
You will create a class that will save the state of your buttons. That class would implement Parcelable,
in order to pass it as an ArrayList<Parcelable>
to the Bundle
parameter in onSaveInstanceState()
.
Here is the source of this answer.
Edit:
I believe this is the main idea behind the implementation, it's simple, yet I am missing something about the button creation and the buttons are weirdly created after rotating. By weirdly I mean that the background was not the default and the font is larger which it should not be because I am setting the same size (am I, right?).
To prove that some state is kept you can see it from the text of the button and also from the background color if you press the button.
The main activity:
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);
}
}
}
The layout:
<?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>
The weird part:
When activity is first created
Click a button
After rotatation (some state is preserve, text, color, someone could help here)
You will save your buttons states using the default way which is implementing onSaveInstanceState()
.
You will create a class that will save the state of your buttons. That class would implement Parcelable,
in order to pass it as an ArrayList<Parcelable>
to the Bundle
parameter in onSaveInstanceState()
.
Here is the source of this answer.
Edit:
I believe this is the main idea behind the implementation, it's simple, yet I am missing something about the button creation and the buttons are weirdly created after rotating. By weirdly I mean that the background was not the default and the font is larger which it should not be because I am setting the same size (am I, right?).
To prove that some state is kept you can see it from the text of the button and also from the background color if you press the button.
The main activity:
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);
}
}
}
The layout:
<?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>
The weird part:
When activity is first created
Click a button
After rotatation (some state is preserve, text, color, someone could help here)
edited Nov 21 '18 at 16:19
answered Nov 21 '18 at 14:01
SkemelioSkemelio
693515
693515
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 '18 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 '18 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 '18 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 '18 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 '18 at 14:16
|
show 5 more comments
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 '18 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 '18 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 '18 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 '18 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 '18 at 14:16
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 '18 at 14:03
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 '18 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 '18 at 14:12
Did not help me unfortunately.
– Blnpwr
Nov 21 '18 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 '18 at 14:15
Really? Let me check it out as well.
– Skemelio
Nov 21 '18 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 '18 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 '18 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 '18 at 14:16
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 '18 at 14:16
|
show 5 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53413044%2fsave-state-of-activity-that-contains-buttons-when-you-press-back-button-android%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
show your layout ?
– Sushil Kumar
Nov 21 '18 at 13:48
@SushilKumar the layout just contains a LinearLayout. nothing else. I don't see why that should be important to mention?
– Blnpwr
Nov 21 '18 at 13:49
for making logic accordingly. If it have something then you have to use
boolean flag
– Sushil Kumar
Nov 21 '18 at 13:57