I created nine Button view in the main.xml and named it to Button1, Button2... Button9.. Then in my code I created an ArrayList of Button and its obvious that this array of buttons will hold my Button in the main.xml and in my current knowledge that to get the Button in my main.xml I need to use the findViewById method and basically I need to loop the array to get the button
ArrayList<Button> buttons;
int MAXBTN = 9;
for( int i = 0; i < BTN; i++ )
{
// Code here to use the findViewById method to get the button
}
And my problem is that I need to pass R.id.Button1 .. R.id.Button3 to the findViewById method, but I need to loop this. Is there anyway I can pass a counter in the findViewById while loop?
Please advise.
You can try this.
ArrayList<Button> buttons;
int MAXBTN = 9;
for( int i = 0; i < BTN; i++ )
{
String buttonID = "Button" + i+1 ;
int resID = getResources().getIdentifier(buttonID, "id", "packageName");
buttons.get(i) = ((Button) findViewById(resID));
}
I think there is already a same question asked for this check this
Its always better to search first before asking
Related
I have an 5 buttons and I need to explicitly create each editText. I found a solution by using for loop we can group the buttons. like below.
private Button[] btn = new Button[4];
private int[] btn_id = {R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3};
for(int i = 0; i < btn.length; i++){
btn[i] = (Button) findViewById(btn_id[i]);
btn[i].setBackgroundColor(Color.rgb(207, 207, 207));
btn[i].setOnClickListener(this);
}
Here I need to use the same button only. How can I use the above code for the different button names?
private Button btn1,button2,bt3,b4;
How can I achieve the for loop for the above button declaration. I tried to add the all the button in to an arrayList bu that doesn't work. Any suggestions.
You can try this way, Hope this help you!
for(int i = 0; i < btn.length; i++){
int btnId= mContxt.getResources().getIdentifier("btn_"+i, "id", getPackageName());
Button btn = (Button)findViewById(buttonId);
btn.setBackgroundColor(Color.rgb(207, 207, 207));
btn.setOnClickListener(this);
}
After the for-loop you have this array filled with Buttons,
private Button[] btn = new Button[4];
Then you can just do this, after the for-loop
private Button btn1 = btn[0];
private Button btn2 = btn[1];
private Button btn3 = btn[2];
private Button btn4 = btn[3];
You can do this in a better way, but I hope this will give you a small indication on how to do it.
I created array of buttons in a loop. It seems to work, but if I add OnClickListener to each button, I get a NullPointerException. How do I fix that?
This is my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
fieldModel=new Field();
buttons=new Button[10][10];
for(int i=0; i<10; i++) {
for (int j = 0; j < 10; j++) {
String buttonID = "button" + i + j;
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[i][j] = ((Button) findViewById(resID));
buttons[i][j].setOnClickListener(new View.OnClickListener() { // <-- I get the exception here...
#Override
public void onClick(View v) {
"some action"
}
});
In R.layout.main_layout, are there 100 buttons named 'button00' to 'button99'? if any one is missing, it will result in a null pointer at the line you have marked.
It would also be worth looking at using a GridView, or a RecyclerView with GridLayoutManager, instead of adding the buttons manually - if it would suit your app.
You get the exception because the id isn't contained by the activity layout. You have to add them first in the layout file if you want to match the Button object through findViewById or, if you have them already, make sure the Id you use in findViewById (resId) is correct.
I have ten buttons in my xml layout i want to exchange the position of the 10 buttons randomly. I tried two methods to achieve it.
Method 1: I changed the background resource of the button but only the image changed. Not the button position on the layout. Here is my workings for method 1.
objects = new ArrayList<Integer>();
objects.add(R.drawable.num_one);
objects.add(R.drawable.num_eight);
objects.add(R.drawable.num_six);
objects.add(R.drawable.num_five);
objects.add(R.drawable.num_nine);
objects.add(R.drawable.num_four);
objects.add(R.drawable.num_two);
objects.add(R.drawable.num_three);
objects.add(R.drawable.num_zero);
objects.add(R.drawable.num_seven);
// Shuffle the collection
Collections.shuffle(objects);
List<Button> buttons = new ArrayList<Button>();
buttons.add((Button)findViewById(R.id.name));
buttons.add((Button)findViewById(R.id.boutton_eight));
buttons.add((Button)findViewById(R.id.boutton_six));
buttons.add((Button)findViewById(R.id.boutton_five));
buttons.add((Button)findViewById(R.id.time));
buttons.add((Button)findViewById(R.id.boutton_four));
buttons.add((Button)findViewById(R.id.boutton_two));
buttons.add((Button)findViewById(R.id.search_box));
buttons.add((Button)findViewById(R.id.boutton_zero));
buttons.add((Button)findViewById(R.id.boutton_seven));
for (int i = 0; i < objects.size(); i++) {
buttons.get(i).setBackgroundResource(objects.get(i));
}
In Method two: I shuffled the button directly but as the widget are already set in the xml layout. AddView () give an error message that the view is already set. Here is my working for the second solution.
ll = (LinearLayout)findViewById(R.id.llShuffleBox);
//create another two linear layouts which will host 5 buttons horizontally
top_compte = (LinearLayout)findViewById(R.id.top_compte);
bottom_calculator= (LinearLayout)findViewById(R.id.bottom_calculator);
buttons.add((Button)findViewById(R.id.name));
buttons.add((Button)findViewById(R.id.boutton_eight));
buttons.add((Button)findViewById(R.id.boutton_six));
buttons.add((Button)findViewById(R.id.boutton_five));
buttons.add((Button)findViewById(R.id.time));
buttons.add((Button)findViewById(R.id.boutton_four));
buttons.add((Button)findViewById(R.id.boutton_two));
buttons.add((Button)findViewById(R.id.search_box));
buttons.add((Button)findViewById(R.id.boutton_zero));
buttons.add((Button)findViewById(R.id.boutton_seven));
Collections.shuffle(buttons);
for (int i=0;i<5;i++) {
top_compte.addView(buttons.get(i));
}
//add remaining 5 to second layout
for (int i=5;i<10;i++){
bottom_calculator.addView(buttons.get(i));
}
// ll.addView(top_compte);
ll.addView(bottom_calculator);
My question is how can i exchanged the position of the buttons on my layout. Note button 0 to 4 is in a horizontal linear layout and below it is the second horizontal linear layout containing button 5 to 9. Also ll is the Main LinearLayout that contain the two horizontal layout.
You can try creating the Buttons dynamically(in code). So, you'll have a LinearLayout(vertical) and two LinearLayouts(horizontal) within it. Keep your xml file as:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llShuffleBox"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/top_compte"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
<LinearLayout
android:id="#+id/bottom_calculator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</LinearLayout>
Now, for the activity code:
ll = (LinearLayout)findViewById(R.id.llShuffleBox);
//create another two linear layouts which will host 5 buttons horizontally
top_compte = (LinearLayout)findViewById(R.id.top_compte);
bottom_calculator= (LinearLayout)findViewById(R.id.bottom_calculator);
// Create an ArrayList to hold the Button objects that we will create
ArrayList<Button> buttonList = new ArrayList<Button>();
// Create the Buttons, set their text as numeral value of the index variable
for (int i = 0; i < 10; i++) {
Button b = new Button(this);
b.setText("" + (i+1));
b.setGravity(Gravity.CENTER_HORIZONTAL);
buttonList.add(b);
}
// Shuffle
Collections.shuffle(buttonList);
for (int i = 0; i < 10; i++) {
// Add the first five Buttons to top_compte
// Add the last five Buttons to bottom_calculator
if (i < 5) {
top_compte.addView(buttonList.get(i));
} else {
bottom_calculator.addView(buttonList.get(i));
}
}
Edit 1:
Declare and initialize this global variable:
// Global variable
int id = 1;
Add the following method to your activity. It will generate an id that is not in use elsewhere in your view tree.
// Generates and returns a valid id that's not in use
public int generateUniqueId(){
View v = findViewById(id);
while (v != null){
v = findViewById(++id);
}
return id++;
}
Change the code to set ids to buttons:
ll = (LinearLayout)findViewById(R.id.llShuffleBox);
//create another two linear layouts which will host 5 buttons horizontally
top_compte = (LinearLayout)findViewById(R.id.top_compte);
bottom_calculator= (LinearLayout)findViewById(R.id.bottom_calculator);
// Create an ArrayList to hold the Button objects that we will create
ArrayList<Button> buttonList = new ArrayList<Button>();
// Create the Buttons, set their text as numeral value of the index variable
for (int i = 0; i < 10; i++) {
Button b = new Button(this);
b.setText("" + (i+1));
b.setGravity(Gravity.CENTER_HORIZONTAL);
b.setId(generateUniqueId()); // Set an id to Button
buttonList.add(b);
}
// Shuffle
Collections.shuffle(buttonList);
for (int i = 0; i < 10; i++) {
// Add the first five Buttons to top_compte
// Add the last five Buttons to bottom_calculator
if (i < 5) {
top_compte.addView(buttonList.get(i));
} else {
bottom_calculator.addView(buttonList.get(i));
}
}
You can retrieve the ids using the getId() method. If you do not want to use the generateUniqueId() method, you can try replacing the line b.setId(generateUniqueId()); with b.setId(i + 1);. This will set the button ids from 1 to 10. But, it can be problematic if some view in your view hierarchy has the same id as any other.
Edit 2:
Here is how you can set the OnClickListeners to the Buttons you create dynamically:
for (int i = 0; i < 10; i++) {
final Button b = new Button(this);
b.setText("" + (i+1));
b.setGravity(Gravity.CENTER_HORIZONTAL);
b.setId(i + 1);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dealWithButtonClick(b);
}
});
bList.add(b);
}
And here is one possible implementation of dealWithButtonClick(Button) method. You can change it to suit your needs:
public void dealWithButtonClick(Button b) {
switch(b.getId()) {
case 1:
b.setBackground(getResources().getDrawable(R.drawable.some_drawable_1));
break;
case 2:
b.setBackground(getResources().getDrawable(R.drawable.some_drawable_2));
break;
........
........
........
case 10:
b.setBackground(getResources().getDrawable(R.drawable.some_drawable_10));
break;
default:
b.setBackground(getResources().getDrawable(R.drawable.some_drawable_for_when_no_cases_were_matched));
break; }
}
I had a same problem (shuffle buttons) and i come up with an easy solution
I just used an array of integer numbers of buttons ids and simple shufle. In my case was that enough. It's simple and u get the same result.
Integer[] a = { 0x7f090049, 0x7f09004b, 0x7f09004c, 0x7f090048};
Collections.shuffle(Arrays.asList(a));
button1 = (Button)findViewById(a[0]);
button2 = (Button)findViewById(a[1]);
button3 = (Button)findViewById(a[2]);
button4 = (Button)findViewById(a[3]);
I hope this will help.
Regards !!
(srry for my broken english)
I'm trying to make my life a heck of a lot easier by cycling through buttons in my xml (because I have a ton of buttons). Why isn't this working?
Button bf[];
public static final int[] Buttons = { R.id.b1, R.id.b2, R.id.b3, R.id.b4,
R.id.b5, R.id.b6, R.id.b7, R.id.b8, R.id.b9, R.id.bBack,
R.id.bClearAll, R.id.bClear };
I have a static final int that holds some of my buttons, which is list in the header.
Within my onCreate method I set up my buttons:
for (int i = 1; i < 10; i++) {
bf[i] = (Button) findViewById(Buttons[i - 1]);
bf[i].setOnClickListener(this);
}
Nice and easy right? but then when I try to reference them in the switch and case (within my implemented onClickListener method, I'm having problems:
for (int i = 1; i < 10; i++) {
case Buttons[i-1]:
Toast.makeText(this, bf[i].getText(), Toast.LENGTH_SHORT).show();
break;
}
This doesn't work, so then I just tried a single reference:
switch (v.getId()) {
case Buttons[0]:
Toast.makeText(this, bf[1].getText(), Toast.LENGTH_SHORT).show();
break;
which doesn't work either?!?! Help please?
v is your View in the onClickListener, right?
Why don't you use:
Button b = (Button) v;
Toast.makeText(this, b.getText(), Toast.LENGTH_SHORT).show();
Some other points:
You did not post the complete code but I guess you can change your Buttons array to private.
Probably you don't even need bf[]
Edit: Also I'd suggest to use this for-loop to cycle through all of your buttons to make it more flexible:
for (int i : Buttons) {
Button b = findViewById(i);
b.setOnClickListener(myClickListener);
}
I have a question that is driving me crazy.
I have a large number of buttons (10, more or less) on my screen, inside a TableRow.
I need to access them, and I had planned to perform through a loop.
Access to one, is very easy, adding this:
boton7 = (Button) findViewById (R.id.Btn7)
My question is, if you can dynamically set the id string (R.id.Btn7) to put in a can get the buttons for, and for example, change the color .... something like this:
for (int i = 0; i <10; i + +) {
Button eachBoton= (Button) findViewById (R.id.Btn + i);
eachBoton. setBackgroundColor (Color.Red);
}
That, of course, does not work .... my question is if anyone knows how exactly the chain can be mounted
R.id.Btn + i
to work.
Thanks a lot.
You can use Resources#getIdentifier() to get a resource identifier for the given resource name:
int resourceId = getResources().getIdentifier(
"Btn"+i,
"id",
this.getContext().getPackageName());
Button button = (Button) findViewById(resourceId);
Alternately you can prepare an array with all the ids you need and access elements of that array. This is more efficient:
private final int[] btns = {R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4, ...}
...
Button button = (Button) findViewById(btns[i]);
Give an identifier to your layout ("layout" in the example below) and then iterate over all the touchable children by using getTouchables. If it's a button, change the color.
View layout = findViewById(R.id.layout)
ArrayList<View> touchables = layout.getTouchables();
for (View b : touchables) {
if (b instanceof Button) {
b.setBackgroundColor(Color.Red);
}
}