Using findViewById() inside a for loop for multiple checkboxes - android

If I have too many checkboxes ( more than 50 ) , is there a way i could use the mapping of the checkboxes , inside for loop ? and how will i assign the int inside the findViewById(int).
Something like this : - (array of checkboxes)
for(int i=0 ; i<=99; i++)
checks[i] = (CheckBox)findViewById(what-about-this-int-id);

You can look up resource id's dynamically too using getResources().getIdentifier(..):
https://stackoverflow.com/a/14058142/1715829

If you have a container element where all those checkboxes reside then you can simply get all its checkbox children by casting it to ViewGroup
ViewGroup container = (ViewGroup)findViewById(R.id.container);
for (int i = 0; i < container.getChildCount(); i++){
CheckBox cb = (CheckBox)container.getChildAt(i);
// attach listener etc
}

I know you might have found your solution but just in case others couldn't find a proper one, i'll post mine here.
Let's say you labelled your "findViewById" like this:
<CheckBox
android:id="#+id/checkbox0"
android:layout_width="0dp"
android:layout_weight="1"
android:padding="5dip"/>
<CheckBox
android:id="#+id/checkbox1"
android:layout_width="0dp"
android:layout_weight="1"
android:padding="5dip"/>
.
.
.
<CheckBox
android:id="#+id/checkbox50"
android:layout_width="0dp"
android:layout_weight="1"
android:padding="5dip"/>
You can do something like this to "findViewById" using a few lines instead of
writing 50 "findViewById" lines:
CheckBox[] cb = new CheckBox[51];
for (int i = 0; i < 51; i++) {
String idCheckBox = "checkbox"+i;
cb[i] = (CheckBox) findViewById(YourActivity.this.getResources().getIdentifier(idCheckBox, "id", getPackageName()));
}
where "YourActivity.this" refers to the context.

1) What for are there 50+ checkboxes?
If you have a list with checkboxes you should use ViewHolder to store info about each row.
2) Try to avoid findViewById each time when you need an item.
findViewById is an expensive operation so you should cache you items (for this very purposes ViewHolder was created).

Related

Inserting n elements from xml layout to LinkedList (Android)

I have n CheckBox elements in my XML layout for a user registration page. My XML is as follows:
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 1"/>
<CheckBox
android:id="#+id/checkBox2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 2" />
How can I add those elements to a LinkedList of type CheckBox in my java code? Ideally, I'd like to use a for-loop to find all elements containing ID "checkbox."
Thanks for any assistance.
You could traverse through the parent view (let's say it's called resultView).
List<CheckBox> boxes = new ArrayList<>();
for (int i = 0; i < resultView.getChildCount(); i++) {
if (resultView.getChildAt(i) instanceof CheckBox) {
// this is a check box for sure
boxes.add((CheckBox) resultView.getChildAt(i));
}
if (resultView.getChildAt(i).toString().contains("checkbox")) {
// this might be a checkbox, and may cause ClassCastException
boxes.add((CheckBox) resultView.getChildAt(i));
}
}
If your CheckBoxes are in the same parent view, you can try to loop for it's children like :
List<CheckBox> list = new LinkedList<>();
RelativeLayout layout = (RelativeLayout)findViewById(R.id.layout);
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
//Some condition to get the view you want
//and make sure it's a CheckBox (maybe by tag?)
list.add((CheckBox)child);
}

Get getCheckedItemPositions() and getCheckedItemIds() always returns null

I have a listview in an android app with checkboxes and I'm trying to get a list of the items that are checked. I have tried both setting the checked state in the getView() method with setChecked(true) and by checking it manually by tapping on the item. I've tried two different methods for getting the checked items and both return null. What am I doing wrong?
Greg
//Called from a menu
//First attempt - checked is always null
//I also set setChoiceMode = CHOICE_MODE_MULTIPLE before setting adapter
//and set no setChoiceMode
String ItemsChecked = null;
ListView listview = (ListView) findViewById(R.id.ListLists);
SparseBooleanArray checked = listview.getCheckedItemPositions();
for (int i = 0; i < checked.size(); i++) {
if (checked.get(i)) {
ItemsChecked += Integer.toString(i) + ",";
}
}
//I then tried this and checked[] is empty
//I also set setChoiceMode = CHOICE_MODE_NONE before setting adapter
long checked[] = listview.getCheckedItemIds();
for (int i = 0; i < checked.length; i++) {
ItemsChecked += "" + checked[i] + ",";
}
//Layout for the ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="4dp"
android:src="#drawable/ic_listit" >
</ImageView>
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
<TextView
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#+id/label"
android:textSize="22sp" >
</TextView>
</LinearLayout>
I am not sure you have provided enough information to solve the problem. But here are some troubleshooting steps that may help point you in the right direction:
1) Instead of getting an array based on the number of checked items in the listView, see if you can pull the array of items in the entire list, or at least the first 100 if the list is very large. Then output the index number of each item in a string like you had in your first attempt. You could also try and output whether the current item is checked or not.
this will tell you if you have a populated list to pull from. If you don't, well there's your problem.
2) I would also check to make sure that your listView's name is also correct. I would assume the compiler would catch this but you never know.
3) Finally, I can't see where or how the list is populated. It may be a good idea to check and see the rest of the code to see if maybe something is happening somewhere else.
Sorry if this is not particularly helpful. If all of this checks out and the problem is not being created in one of those areas this link may help:
Android: list.getCheckedItemPositions() always returns null
Good Luck and I hope this helps a little.
Max,
Well, you pointed me in the right direction for a 'solution'. This may not be the proper way to do it, but given this is my my first android app, I am ready to move on after spending the entire morning trying to get a list of just those items that are checked with a built-in method. I modified code from the link you posted and came up with the code below. It seems to work.
I wonder if I will have problems with lists that don't show everything at once. My test only has two items in the list. If items are checked and then scrolled out of view, will this work. More testing needs to be done.
Thanks,
Greg
ListView listview = (ListView) findViewById(R.id.ListLists);
View v;
CheckBox ck;
TextView tv;
for (int i = 0; i < listview.getCount(); i++) {
v = listview.getChildAt(i);
ck = (CheckBox) v.findViewById(R.id.checkBox1);
tv = (TextView) v.findViewById(R.id.label);
if (ck.isChecked()) {
Toast.makeText(getApplicationContext(), tv.getText() + "Checked" , Toast.LENGTH_LONG)
.show();
}
else {
Toast.makeText(getApplicationContext(), tv.getText() + "Not checked" , Toast.LENGTH_LONG)
.show();
}
}

Get text of selected checkboxes android?

I have 5 checkboxes in my activity xml. I need to get the text of all the selected checkboxes.
One approach is to see if checkbox1 ischecked() and get the text.
if(checkbox1.isChecked())
{ String text=checkbox1.getText().toString();}
and so on.
This becomes quite a lengthy process.
Is there any other approach I can use?
A couple of basic suggestions:
You do not need to ==true operation above so a simple if(checkbox1.isChecked()) would suffice.
Store them all in an ArrayList so you can iterate as below:
List<CheckBox> items = new ArrayList<CheckBox>();
for (CheckBox item : items){
if(item.isChecked())
String text=item.getText().toString();
}
CheckBox[] nameString = new CheckBox[]{Array1, Array2, Array3, Array4, Array5, Array6, Array7, Array8};
for (int i=0; i<=7; i++)
{
if (nameString[i].isChecked())
{
Toast.makeText(getApplicationContext(), nameString[i].getText().toString(), Toast.LENGTH_SHORT).show();
}
}
Rather than looping through all your checkBoxes to find which one of them is checked, you could simply create a List of selected items at onCHeckedChanged() or onClick()
If(unChecked)==>Add to List==> if(Checked) ==> Remove from list
Kotlin sample code:
You can create an event and bind same event to all the check boxes, like
<CheckBox
android:id="#+id/chk1"
android:onClick="onCheckBoxClicked" ....
<CheckBox
android:id="#+id/chk2"
android:onClick="onCheckBoxClicked" ....
MainActivity:
fun onCheckBoxClicked(view:View){
view as CheckBox
if (view.isChecked){
var msg = view.text.toString()
Log.d("Checkbox", msg) //printing in log
}

Unable to set background resource on a Button

I have an application on which I apply some resources to buttons to modify their backgrounds.
All work well, but when my application goes to onResume after onPause, I'm not able to set the background anymore.
I have a set of 18 buttons, and when I am in onResume, i call:
for (int i = 0; i < max; i++) {
Button b = l.get(i);
b.setBackgroundResource(R.color.green);
}
In l i have the list of all buttons got from findViewById().
This works only for the last element of the for, but not for the others.
Any idea?
** Edit **
This is the code I use for populating the array
btn_1 = (Button)findViewById(R.id.btn_1);
btn_1.setOnClickListener(this);
l.add(btn_1);
this is repeated for all my buttons.
** Second edit **
public void onResume() {
btn_1 = (Button)findViewById(R.id.btn_1);
btn_1.setOnClickListener(this);
l = new ArrayList<Button>();
l.add(btn_1);
...
for (int i = 0; i < max; i++) {
Button b = l.get(i);
b.setBackgroundResource(R.color.green);
}
}
The same is done in onCreate().
try the d following.. this will works fine.
List<Button> mButtonList = new ArrayList<Button>();
onCreate() {
mButtonList.add((Button) findViewById(R.id.btn_1));
mButtonList.add((Button) findViewById(R.id.btn_2));
mButtonList.add((Button) findViewById(R.id.btn_3));
....
for(Button b : mButtonList) {
b.setOnClickListener(this);
}
}
onResume() {
for(Button b : mButtonList) {
b.setBackgroundResource(R.color.green);
}
}
Simple example:
Activity
public class StackOverFlowActivity extends Activity {
private ArrayList<Button> myArray = new ArrayList<Button>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myArray.add((Button)findViewById(R.id.btn_1));
myArray.add((Button)findViewById(R.id.btn_2));
myArray.add((Button)findViewById(R.id.btn_3));
myArray.add((Button)findViewById(R.id.btn_4));
myArray.add((Button)findViewById(R.id.btn_5));
}
#Override
protected void onResume() {
super.onResume();
for (Button b : myArray) {
b.setBackgroundColor(getResources().getColor(R.color.blue));
}
}
}
XML main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1" />
<Button
android:id="#+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2" />
<Button
android:id="#+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3" />
<Button
android:id="#+id/btn_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 4" />
<Button
android:id="#+id/btn_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 5" />
</LinearLayout>
My color in the Strings.xml
<color name="blue">#0099CC</color>
Use this instead:
for (int i = 0; i < max; i++) {
Button b = l.get(i);
b.setBackgroundColor(getResources().getColor(R.color.green));
}
If max is really big you might want to cache the getColor result before the loop.
EDIT:
According to the docs: setBackgroundResource is to be used with drawable ids only, and setBackgroundColor seems to be exactly what you need, so maybe another part of your code isn't working well, maybe the loop, the above line for setBackgroundColor works well on my app.
You've said:
": the ... code is the same for btn_1, just swap btn_1 with btn_2, btn_3 and so on. "
if so, than these lines are resetting your Array every time you try and add a new button.
l = new ArrayList<Button>();
l.add(btn_1);
P.S. you should avoid using a manual creation of buttons array - instead use some Parenting Layout such as LinearLayout and then fetch his button son's using getChildAt(i), It's much cleaner. Example:
// Register all the buttons in the layout to the OnClickListener
LinearLayout lin = (LinearLayout)findViewById(R.id.linear_buttons);
int childcount = lin.getChildCount();
for (int i=0; i < childcount; i++){
View v = lin.getChildAt(i);
v.setOnClickListener(this);
}
Try this --
for (int i = 0; i < l.getChildCount(); i++)
{
Button b = (Button) l.getChildAt(i);
b.setBackgroundResource(R.color.green);
}
try this. its working for me
for (int i = 0; i < count; i++) {
btn_title[i] = new Button(ActivityName.this);
btn_title[i].setText(menu.menu_title[i]);
btn_title[i].setId(i);
btn_title[i].setTextColor(Color.BLACK);
btn_title[i].setBackgroundColor(Color.parseColor(dataxml
.getMenucolor()));
btn_title[i]
.setTextSize(Integer.parseInt(dataxml.getFontsize()));
btn_title[i].setGravity(Gravity.CENTER_VERTICAL
| Gravity.CENTER_HORIZONTAL);
btn_title[i].setSingleLine();
btn_title[i].setEllipsize(TruncateAt.END);
btn_title[i].setOnClickListener(new ButtonListner());
}
hope this will help
why don't extend Button class, set its color, then use that new class?
It wont work obviously , let me explain why it has set last value of button .
you are using of one button reference (whatever u got from (Button)findViewById(R.id.btn_1) )
and untimely there is a one button reference and u just change its value using l.add(btn_1);
what you need to do is , do create a new button instance for each button and inflate it in proper view .
here is the small tick for that
for (int i==0 ; i < length; i++ ){
Button button = new Button(context);
collectionOfButton.add(button) ;
}
use that buttons collection using inflate if u try to integrate in some xml layout file .

Performing a Mark All for checkboxes in Android

I am working on an android project with many activities and classes.
In few of the Layouts, I have a facility in which a user can select mark all so that all the checkboxes get selected.
But, the issue I am facing is I know only the one way (which is too lengthy) to do this - By creating a markall layout for each of those existing layouts, pasting the original layout code in the markall layout code and then giving all checkboxes as checked.
This requires me to create xmls for all unmarkings also for each layout.
Please tell me a way in which I can create one xml for markall which has all checked checkboxes, and then call that layout on top of original layout when mark all is clicked.
Lets assume you have following Layout
<LinearLayout
android:id="#+id/checkbox_container"
...params>
<CheckBox ...params/>
<TextView ...params/>
<CheckBox ...params/>
<SomeView ...params/>
<CheckBox ...params/>
</LinearLayout>
get your checkBoxLayout like this inside Activity
LinearLayout container = (LinearLayout)findViewById(R.id.checkbox_container);
Iterate over the childs inside the container like this:
for (int i = 0; i < container.getChildCount(); i++){
View v = container.getChildAt(i);
if (v instanceof CheckBox){
CheckBox cb = (CheckBox)v;
// isChecked should be a boolean indicating if every Checkbox should be checked or not
cb.setChecked(isChecked)
}
}
CheckBox MarkAllCheckBox =
(CheckBox) findViewById( R.id.MarkAllCheckBox);
MarkAllCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if ( isChecked )
{
checkBox1.setChecked("true");
checkBox2.setChecked("true");
checkBox3.setChecked("true");
//so on
}
}
});

Categories

Resources