How to save a button across a configuration change? - android

In my Activity, I have a field that is a button. It's value is always the currently selected button in a LinearLayout that is created dynamically in the activity. I want this field to always point to the button that is currently selected, however, if I select a button and then change the configuration, the field no longer points to the selected button. What can I do so that I can save this value across a configuration change?
Here's my code:
Activity.java
public class Activity extends AppCompatActivity {
Button myButton;
LinearLayout myLayout;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
for (int i = 0; i < 2; i++) {
LinearLayout row = new LinearLayout(this);
LayoutParams rowParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1f);
row.setLayoutParams(rowParams);
for (int j = 0; j < 2; j++) {
final Button button = new Button(this);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setMyButton(button);
}
});
}
row.addView(button);
}
myLayout.addView(row);
}
public void setMyButton(Button button) {
myButton = button;
}
}
I have looked into using some savedInstanceState methods but none of them have one for a Button, only integers and booleans.
What can I do so that I can retain the value of myButton when the configuration changes?

You can use onSaveInstanceState() as long as you have some way to identify the button you want to save; you don't have to save the button itself.
Normally, you'd use the button's id for this purpose, but since you're dynamically creating the buttons at runtime (instead of putting them in your XML layout) I recommend using the button's tag instead.
Save the button's tag in onSaveInstanceState(), and then when you're creating the buttons, if you create a button with that same tag, save it as myButton.
onSaveInstanceState():
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("myButtonTag", myButton != null ? (String) myButton.getTag() : null);
}
At the top of onCreate():
String myButtonTag = null;
if (savedInstanceState != null) {
myButtonTag = savedInstanceState.getString("myButtonTag");
}
Inside your inner for loop:
final Button button = new Button(this);
String tag = i + "," + j;
button.setTag(tag);
if (tag.equals(myButtonTag)) {
myButton = button;
}

Related

Changing the Color of the Dynamically loaded Buttons onclick

Android: I have created dynamic buttons based on my arraylist size,Lets consider 10 buttons. When a button is clicked, the color of the button will change to grey. When another one is clicked, the color of the previous button should be reset to the default color.
boolean iscolor = true;
final LinearLayout linearLayout = view.findViewById(R.id.total_count);
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
for (int j =1;j<=datalist.size()/2;j++) {
final Button btn = new Button(getContext());
final int id_ = j;
btn.setText("" + j);
btn.setTextColor(Color.WHITE);
btn.setMaxWidth(5);
btn.setId(id_);
btn.setPadding(8, 8, 8, 8);
btn.setBackgroundColor(getContext().getResources().getColor(R.color.DarkBlue));
linearLayout.addView(btn, params);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!iscolor ) {
btn.setBackgroundColor(getResources().getColor(R.color.DarkBlue));
iscolor =true;
}
else
{
btn.setBackgroundColor(getResources().getColor(R.color.gray));
iscolor = false;
}
}});
How to restore the color of the previous clicked Button in Android.
Try this :
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/* you need to have already stored buttons in a data structure, something like : List<Button> btns; */
for(Button b : btns){
if(b.getId() == v.getId(){ b.setBackgroundColor(getResources().getColor(R.color.gray)); } else{ b.setBackgroundColor(getResources().getColor(R.color.yourdefaultcolor)); } //no need for isColor variable
}});
linearLayout.addView(btn, params);

Use a button to add other buttons, editText etc.

I need to be able to add buttons to a layout using an "add" button. The problem is that I need each button to have an OnClickListener()/onClick method. I was thinking every time the "add" button is pressed then i would add a new button to an array but im not sure add the listener and implement an onClick method for each button I create.
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SmartChronometer chrono = (SmartChronometer) findViewById(R.id.chrono);
final Button start = (Button) findViewById(R.id.button2);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (chrono.isRunning())
chrono.pause();
else {
chrono.chronoStart();
}
}
});
}
I need to add chronomoter,button and listeners every time I click an "Add" button.
set all the clicklisteners as you wich!
call findViewById(R.id.btnSecond).setVisibility(View.GONE); on creat, then when clickin the first button
Button btnSecond;
...
public void onClick(View v) {
findViewById(R.id.btnSecond).setVisibility(View.VISIBLE);
if (btnSecond.getVisibility() == View.VISIBLE); {
findViewById(R.id.btnThird).setVisibility(View.VISIBLE);}
}
this way you can put all your information in the java file and all buttons in xml, but they will be hidden until click.
This is one way, other answer my come. Good Luck :)
implements OnClickListener
Button add = (Button) findViewById (R.id.addButton);
add.setOnClickListener (this);
List<Button> buttons = new ArrayList <Button>();
for (int i = 0; i < buttons.size (); i++){
buttons.get (i).setOnClickListener (this);
}
#Override
public void onClick (View v){
for (int i = 0; i < buttons.size (); i++){
if (v.getId () == buttons.get (i).getId ()){
// do stuff you want
}else if (v.getId() == R.id.addButton){
//add button
}
}
}
Hope this will work, didnt test it.

Change TextView Color pressing a button

I'm trying to create an activity entirely by java code. The goal here is to create an Activity that fills up itself by previous activity. It's a shop list activity.
The user add itens in the previous activity and when he ask to show the complete list the activity above will be generated.
The problem here is, I want to set red as the initial color of the textviews with the itens names, and when the user clicks on then, they change their color to green.
But when I click it the aplication force close with the message indexoutofbounds exception.
Could someone helps me?
public class Listdinamiccor extends Activity {
Bundle recebendoparametros;
int i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listdinamiccor);
Intent parametro = getIntent();
recebendoparametros = parametro.getExtras();
int j = recebendoparametros.getInt("i");
ScrollView sv = new ScrollView(this);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
sv.addView(ll);
final TextView[] tvarray = new TextView[j];
for (i = 0; i < tvarray.length; i++) {
String chave = "chave"+i;
final TextView tv = new TextView(this);
tvarray[i] = new TextView(this);
tvarray[i].setText(""+recebendoparametros.getString(chave));
tvarray[i].setTextColor(Color.RED);
tvarray[i].setOnClickListener(new View.OnClickListener() {
int click = 0;
#Override
public void onClick(View v) {
/*if (click == 0) {
tvarray[i].setTextColor(Color.GREEN);
}
else {
tvarray[i].setTextColor(Color.RED);
}*/
AlertDialog.Builder alert = new AlertDialog.Builder(Listdinamiccor.this);
alert.setTitle("dinamico");
alert.setMessage("eu sou muito dinamico");
}
});
ll.addView(tvarray[i]);
}
this.setContentView(sv);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.listdinamiccor, menu);
return true;
}
}
When your loop has completed executing, i is now set to tvarray.length -- your onClick handler doesn't "remember" the value of i, it simply does what you tell it to, which is to setTextColor on tvarray[i], and i is now out of bounds.
One way to solve it is to do this above your setOnClickListener line:
final TextView me = tvarray[i];
And then change your onClick method to call me.setTextColor instead of tvarray[i].setTextColor.
Also, I wouldn't recommend hanging onto the int i outside of your loop - I'm assuming you moved the member to the parent class so that your current code compiled, but in general you don't want to use for loop indexes outside of the for loop (this exception is one such reason).
Try casting your View v to a TextView inside your onclick listener instead of using the instance your creating in your array like this:
tvarray[i].setOnClickListener(new View.OnClickListener() {
int click = 0;
#Override
public void onClick(View v) {
if (click == 0) {
((TextView)v).setTextColor(Color.GREEN);
}
else {
((TextView)v).setTextColor(Color.RED);
}
AlertDialog.Builder alert = new AlertDialog.Builder(Listdinamiccor.this);
alert.setTitle("dinamico");
alert.setMessage("eu sou muito dinamico");
}
});

get OnClick() from programmatically added buttons?

i have added some button in a layout:
LinearLayout row = (LinearLayout)findViewById(R.id.KeysList);
keys=db.getKeys(console);
my_button=new Button[keys.size()];
for (bt=0;bt<keys.size();bt++){
my_button[bt]=new Button(this);
my_button[bt].setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.FILL_PARENT));
my_button[bt].setText(keys.get(bt));
my_button[bt].setId(bt);
row.addView(my_button[bt]);
my_button[bt].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (my_button[bt].getId() == ((Button) v).getId()){
Toast.makeText(getBaseContext(), keys.get(bt), 0).show();
}
}
});
}
I want to know which button is clicked and how to get text of the clicked button?And I think using bt here dose not seem to work!
This code is running. I hope it help you :)
final ArrayList<String> Keys = new ArrayList<String>();
for(int i = 0; i < 10; i ++){
Keys.add("Keys is : " + String.valueOf(i));
}
LinearLayout Row = (LinearLayout)findViewById(R.id.KeysList);
final Button[] my_button = new Button[Keys.size()];
for (int bt = 0; bt < Keys.size(); bt ++){
final int Index = bt;
my_button[Index] = new Button(this);
my_button[Index].setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
my_button[Index].setText(Keys.get(Index));
my_button[Index].setId(Index);
my_button[bt].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (my_button[Index].getId() == ((Button) v).getId()){
Toast.makeText(getBaseContext(), Keys.get(Index), 0).show();
}
}
});
Row.addView(my_button[Index]);
}
ExampleProject id : Your project
You should probably use View#setTag to set some arbitrary data you'd like associate with the Button. Then you can just instantiate only one OnClickListener that then uses getTag and acts on that data in whatever way you need.
Another way is to have your Activity listen to all button clicks and then you just filter respective to the ID. You should not get the text of the button and use that at all. You should use your own type of identifier, ideally the idea should be enough. Or perhaps you use setTag as #qberticus described.
Consider This example :
public class MainActivity extends Activity implements View.OnClickListener
{
LinearLayout linearLayout;
Button [] button;
View.OnClickListener listener;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linearLayout=(LinearLayout)findViewById(R.id.parent_lay);
String[] array={"U123","U124","U125"};
int length=array.length;
System.out.println("11111111111111111111111111");
button=new Button[length];
for(int i=0;i<length;i++)
{
button[i]=new Button(getApplicationContext());
button[i].setId(i);
button[i].setText("User" + i);
button[i].setOnClickListener(this);
linearLayout.addView(button[i]);
}
}
#Override
public void onClick(View view)
{
view.getId();
Button button=(Button)findViewById(view.getId());
button.setText("Changed");
}
}
This works fine :)

Dynamic Buttons and OnClickListener

Say I have buttons that are created dynamically:
for(int j = 0; j < spirits.length;
j++){
Button imgBtn = new Button(v.getContext());
imgBtn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
imgBtn.setMinimumWidth(100);
imgBtn.setMinimumHeight(100);
imgBtn.setId(j+1);
imgBtn.setTag(spirits[j]);
imgBtn.setText(spirits[j]);
imgBtn.setOnClickListener(new SpiritsClickListener());
cabinet_layout.addView(imgBtn);
}
I want to change the text of the button every time it's pressed (On - Off)
How can I reference the buttons within the OnClickListener class?
in your onClickListener, you have a function called onClick(View v){} where v is the View that was clicked. You may use v to get details about the button, including its ID. You can also take this view, and if you know it is a button, cast it to a button.
Button clicked = (Button)v;
You can then use it in your javacode just as you would normally use a button.
Why don't you just call new OnClickListener() inside that loop like this
for(int j = 0; j < spirits.length;j++){
Button imgBtn = new Button(v.getContext());
imgBtn.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
imgBtn.setMinimumWidth(100);
imgBtn.setMinimumHeight(100);
imgBtn.setId(j+1);
imgBtn.setTag(spirits[j]);
imgBtn.setText(spirits[j]);
imgBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//do what you need to do here
}
});
cabinet_layout.addView(imgBtn);
}
Create an OnClickListener for dynamically created buttons as:
// Create Listener for Button
private OnClickListener SpiritsClickListener = new OnClickListener()
{
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
Button btn = (Button) view;
String btnText = btn.getText();
if(btnText.equalsIgnoreCase("On")){
btn.setText("Off");
}else{
btn.setText("On");
}
}
};
add this Listener to dynamically created buttons as:
imgBtn.setOnClickListener(SpiritsClickListener);

Categories

Resources