I have 45 check boxes that you can check. What I want to do is if you try to select more than 6 check boxes it will automatically disable all the buttons, however, if you tap the even one of the checked checkbox ,it will make all the checkbox checkable. This sounds simple ,but I cannot implements this method. I would be grateful if the pros here can help a noob like me. Here is the sample code.
checkbox[i].setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) { buttonView.setTextColor(Color.GREEN);
buttonClicked.add(buttonView.getText().toString());
buttonView.setTextSize(18);
count+=1;
if(count>=6){
for(int i = 0; i< 43;i++){
checkbox[i].setEnabled(false);
stopped = checkbox[i].isChecked();
if(stopped==true){
for(int a = 0; a < checkbox.length;a++){
checkbox[a].setEnabled(true);
}
}
}
}
}
if (!isChecked) {buttonView.setTextColor(Color.BLACK);
buttonClicked.remove(buttonView.getText().toString());
buttonView.setTextSize(15);
count-=1;
Your issue here is your reaction to finding a checked checkbox. We need to look at removing the internal loop under if(stopped==true)(Note 2).
You simply need
if(stopped){
checkbox[i].setEnabled(true);
}
Then in your if(!isChecked)(Note 3) you add your loop back in to reenable all the checkboxes so it will look like
if(!isChecked){
//your existing code
for(int i=0;i<checkbox.length;i++){
checkbox[i].setEnabled(true);
}
}
Note 1: I would advise that you swap your hardcoded "43"to checkbox.length just to keep things cleaner.
Note 2: You don't need to put ==true, it's already a boolean so this can just be if(stopped)
Note 3: This is what "else" was designed for. if(...){} if(!...){} is synonymous with if(...){}else{}.
Note 4: To void unnecessary looping (always good practice) we should maybe add another check here before the for loop to ensure that there were 6 boxes active.
if(count>=6){
for(int i=0;i<checkbox.length;i++){
checkbox[i].setEnabled(true);
}
}
count--;
Note 5: x+=1; can be replaced by x++; and similarly for x-=1; x--;(as said in the comments to your question)
Related
New to Android,
I am creating a question Answer App. So I want to get the value of checkBoxes.
I know how to get value of radio button present in Radio Group.
But I want to know is it good practice to keep checkBixes in RadioGroup and how to get the Checkboxes value?
What do you mean by getting CheckBox value? You can get the state (checked or not checked) and you can also get the text label for the CheckBox itself (getText()).
As for keeping them in a RadioGroup, it will depend largely on your use case (when grouped, the user might expect that only one CheckBox at the time can be checked). If you were to implement RadioGroup, you will have to implement a listener and then determine which CheckBox was checked. For that you can look at the accepted answer on this closely related question here.
Here is how you can get the Text of the CheckBox that was checked/unchecked:
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
CheckBox checkBox = (CheckBox)findViewById(checkedId);
//here you can check if it was checked or not, including the text
String text = checkBox.getText().toString();
boolean isChecked = checkBox.isChecked();
}
I hope this sheds some light.
Unfortunately as you would expect to utilize radioGroup's getCheckedRadioButtonId() for radio buttons, there is no such thing for check boxes. There are many ways to do this but I think the simplest and cleanest way would be the following:
For CheckBoxes
// Define one listener to use it for all of your CheckBoxes:
CompoundButton.OnCheckedChangeListener listener = new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// You can also use the buttonView.isChecked() instead of isChecked parameter too : if(ButtonView.isChecked)..
if(isChecked) {
// Do stuff with this checkBox for example:
String stringToShow = buttonView.getText();
}
}
};
// Reference your CheckBoxes to your xml layout:
CheckBox checkBox1 = findViewById(R.id.checkBox1);
CheckBox checkBox2 = findViewById(R.id.checkBox2);
// and many more check boxes..
/* Set the above listener to your Check boxes so they would
notify your above piece of code in case their checked status
changed:*/
checkBox1.setOnCheckedChangeListener(listener);
checkBox2.setOnCheckedChangeListener(listener);
// and many more check boxes..
As the title says, I want to check if more than 5 check box is checked in android. What I want to do is to check 5 checkbox and if I enter more or less than 5 checkbox it will show a alert . How will I do this ? I beleive that the pros here can help a noob like me. A example will be helpful for me to learn.
for(int i = 0; i< checkbox.length;i++){
checkbox[i] = (CheckBox)findViewById(ids[i]);
checkbox[i].setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) { buttonView.setTextColor(Color.BLACK);
buttonClicked.add(buttonView.getText().toString());
}
if (!isChecked) {buttonView.setTextColor(Color.GREEN);
buttonClicked.remove(buttonView.getText().toString());
}
}
});
Set a counter that increases by 1 each time a checkbox is checked, and decreases by 1 each time a checkbox is unchecked. If the counter is > 5 then there are more than 5 checkboxes checked and you can display your alert.
I had listview with images and checkboxes wher i have to restrict the user to check 5 checkboxes and disable or make invisible other checkboxes in the list view and whenever user uncheck's one of the five checkboxes that was previous checked should make checkbox enabled or visible again.
you can do this by counter variable as you have to check for all the check box status using iterator also or you can put in click event of checkbox to check whether it reached to limit or not if it reached already after checked the 5th one then disable the another checkbox and when it less then then enable it reset of checkbox
If you are just looking to prevent the user from selecting more than 5 - meaning they have to manually uncheck items - just use a counter variable like pratik suggested. If you want to automatically uncheck the oldest thing the user checked, I would use a queue of the selected indexes. then you can pop the oldest thing off, uncheck it, and add the new index to the queue. you could do all of this in an onItemClickListener or onItemSelectedListener
You can use onCheckedChangeListener.
Add a private integer:
private int checkedCounter;
Initialize it:
checkedCounter = 0;
Set listener:
yourCheckbox = (CheckBox) findViewById(R.id.itsId);
yourCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if (checkedCounter == 5 && isChecked)
{
yourCheckbox.setChecked(false);
}
else if checkedCounter == 5 && !isChecked)
{
checkedCounter--;
}
else if (checkedCounter < 5)
{
(isChecked ? checkedCounter++ : checkedCounter--);
}
}
});
I can't run this code right now so check the conditions.
Actually it can be done also in another way: When 5 boxes are checked you can use setEnabled(false) method on others.
i have created check boxes using loop and i want to validate it. Like i just want to check only 3 from the check boxes , when i press on the 4th one it should show an alert and uncheck it.
And i am able to get the alert when i press the 4the one but it is not unchecking.
anybody faced such issue and how did you solve it ?
int i;
for (i = 0; i < 20; i++) {
CheckBox ch = new CheckBox(this);
ch.setTag(Integer.valueOf(i));
ch.setText("CheckBox " + i);
ch.setChecked(false);
ch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
numChecked++;
} else {
numChecked--;
}
if (numChecked == 4) {
buttonView.setChecked(false);
numChecked--;
// fourth one selected, show your dialog
}
}
});
}
You will also need a global variable call numChecked:
int numChecked = 0;
You will also need to add a .addView(ch) in the loop's end to add the CheckBoxes to your layout.
I'm facing an odd behavior while trying to clear the choices (the selection) of items in my ListView. The code works pretty good, with functions that allow (once in CHOICE_MODE_MULTIPLE) to select single items by tapping, select all, select none and invert the current selection. Since the ListView is supposed to work in both modes (_NONE and _MULTIPLE) I have this menu item that switches between those modes allowing the user to "open" an item or select several items at once for batch operations.
The issue I'm facing shows up ONLY while changing choice mode from CHOICE_MODE_MULTIPLE back to CHOICE_MODE_NONE. What I'm trying to do is to not only revert back to CHOICE_MODE_NONE, but also clear any choices. The odd thing is that while all functions work reliably, when I call the "select non" function just before changing back to CHOICE_MODE_NONE, all items stay checked, no matter where or when I call the "select none" function inside my code.
The function that handles the selection changes is the following:
private void changeItemSelection(int selection) {
NotesAdapter adapter = (NotesAdapter)listView.getAdapter();
if (selection == SELECT_ALL) {
for(int iCount = 0; iCount < adapter.getCount(); iCount++) {
listView.setItemChecked(iCount, true);
}
}
else if (selection == SELECT_NONE) {
for(int iCount = 0; iCount < adapter.getCount(); iCount++) {
listView.setItemChecked(iCount, false);
}
}
else if (selection == SELECT_INVERT) {
for(int iCount = 0; iCount < adapter.getCount(); iCount++) {
listView.setItemChecked(iCount, !listView.isItemChecked(iCount));
}
}
adapter.notifyDataSetChanged();
checkedItemCountInvalid = true; // Invalidate checked indices cache
}
This is what happens when the user taps the menu item that switches selection modes:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_multisel:
toggleSelectionMode();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void toggleSelectionMode() {
if (listView.getChoiceMode() == ListView.CHOICE_MODE_NONE) {
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
else {
listView.setChoiceMode(ListView.CHOICE_MODE_NONE);
}
changeItemSelection(SELECT_NONE);
}
No matter where I put "changeItemSelection(SELECT_NONE)" in the above code block, it simply doesn't work. But when I remove the "listView.setChoiceMode(ListView.CHOICE_MODE_NONE)" it magically starts to work as expected.
It's driving me crazy...
I really would appreciate any insights on this.
Thanks for reading!
EDIT:
What I mean by "not working" is that the selection remains unchanged. Thus, if item1 and item3 where selected, calling select none doesn't uncheck them, but only when I call the function in the part of code mentioned above. Calling select none without trying to change choice mode works perfectly fine.
I experience the same problem. It seems that there already is related question having an answer that states that it is a bug in Android.
I suppose this should be a comment, not answer. But I just do not have enough reputation to comment here.
I don't know if you've solved this yet, so maybe this answer is too late.
I think if you try using clearChoices() before you set the choice mode back to none (and then call your method to clear the checks) it will work as you desire.
private void toggleSelectionMode() {
if (listView.getChoiceMode() == ListView.CHOICE_MODE_NONE) {
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
}
else {
listview.clearChoices();
listView.setChoiceMode(ListView.CHOICE_MODE_NONE);
}
changeItemSelection(SELECT_NONE);
}