Save state of Activity that contains Buttons when you press back button android
up vote
0
down vote
favorite
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 |
up vote
0
down vote
favorite
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 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 at 13:49
for making logic accordingly. If it have something then you have to useboolean flag
– Sushil Kumar
Nov 21 at 13:57
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
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 at 13:42
kit
992316
992316
asked Nov 21 at 13:24
Blnpwr
5141625
5141625
show your layout ?
– Sushil Kumar
Nov 21 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 at 13:49
for making logic accordingly. If it have something then you have to useboolean flag
– Sushil Kumar
Nov 21 at 13:57
add a comment |
show your layout ?
– Sushil Kumar
Nov 21 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 at 13:49
for making logic accordingly. If it have something then you have to useboolean flag
– Sushil Kumar
Nov 21 at 13:57
show your layout ?
– Sushil Kumar
Nov 21 at 13:48
show your layout ?
– Sushil Kumar
Nov 21 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 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 at 13:49
for making logic accordingly. If it have something then you have to use
boolean flag
– Sushil Kumar
Nov 21 at 13:57
for making logic accordingly. If it have something then you have to use
boolean flag
– Sushil Kumar
Nov 21 at 13:57
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
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 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 at 14:16
|
show 5 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
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 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 at 14:16
|
show 5 more comments
up vote
1
down vote
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 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 at 14:16
|
show 5 more comments
up vote
1
down vote
up vote
1
down vote
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 at 16:19
answered Nov 21 at 14:01
Skemelio
47712
47712
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 at 14:16
|
show 5 more comments
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 at 14:16
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 at 14:03
Ok, thank you, I will have a look at it.
– Blnpwr
Nov 21 at 14:03
Did not help me unfortunately.
– Blnpwr
Nov 21 at 14:12
Did not help me unfortunately.
– Blnpwr
Nov 21 at 14:12
Really? Let me check it out as well.
– Skemelio
Nov 21 at 14:15
Really? Let me check it out as well.
– Skemelio
Nov 21 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 at 14:15
Because it is not explained HOW to create this class.
– Blnpwr
Nov 21 at 14:15
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 at 14:16
I will try to do this and if it works I will add the code to this answer.
– Skemelio
Nov 21 at 14:16
|
show 5 more comments
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 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 at 13:49
for making logic accordingly. If it have something then you have to use
boolean flag
– Sushil Kumar
Nov 21 at 13:57