I am working on a data collection application that while in an active state locks the screen to prevent errant user interaction. I would like to "lock" the checkbox while in this state to prevent the user from checking or unchecking the box. While other buttons on the screen still "click" when in this state, (listener is active) their events are not executed when the boolean bLockedScreen == true. I'd like for my boolean flag (bLockedScreen) when true to disable the check box listener.
What is the best way to go about doing this? TIA
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
ckbxVerbose = (CheckBox) v.findViewById(R.id.ckbxVerbose);
return v;
}
public void verbose(){
if(ckbxVerbose.isChecked()){
//do something
}
Update: Resolved this by putting,
ckbxVerbose.setEnabled(false);
in the method that set the boolean flag to disable screen widgets. Will likely do this as well with the other buttons that are inactive while data is being collected. Thank you Prince Ali for your answer.
You can disable or enable the CheckBox by calling setEnabled and setting its value to false or true. Here is a minimal working example involving 2 CheckBoxes, if the first CheckBox is checked, then disable the second one, otherwise enable it:
ckbxVerbose.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
if ( isChecked ) {
ckbxVerbose2.setEnabled(false);
} else {
ckbxVerbose2.setEnabled(true);
}
}
}
);
Another example can be:
CharSequence str = txt.getText();
if ( str.equals("Checked") ) {
ckbxVerbose2.setEnabled(false);
} else {
ckbxVerbose2.setEnabled(true);
}
Related
So I'm working on a list of check boxes. I'm using the OnClickListener to catch the touch event. I've also tried the OnTouch listener and the OnCheckChanged listener. The issue I've come across is the fact that the check box IsChecked value is set to true before it reaches any of these event listeners. So if I were to do something like this:
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (checkBox.isChecked())
checkBox.setChecked(false);
}
});
It will always hit this if statement and immediately set the checkbox to unchecked because it's setting it as ischecked true before it reaches OnClickListener. The easiest way around this I've found is:
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkBox.setChecked(!checkBox.isChecked());
if (checkBox.isChecked()) {
checkBox.setChecked(false);
}
}
});
But this is what I would call hackish. The other option I see being to create a new checkbox class and override the preformClick method.
#Override
public boolean performClick() {
toggle();
final boolean handled = super.performClick();
if (!handled) {
// View only makes a sound effect if the onClickListener was
// called, so we'll need to make one here instead.
playSoundEffect(SoundEffectConstants.CLICK);
}
return handled;
}
But that seems like a lot more work than should need to go in to accomplishing this task.
So, essentially my question is: Is there a method where I can override and intercept the setting of the checkbox before it is actually changed?
The OnClickListener of the CheckBox always gets called after it changed its checked state (as you can see in the performClick() method you copied, the toggle() method changes the checked state, before calling super's performClick(), which will call the OnClickListener).
If you don't want to always change the checked state of the CheckBox, then you can override performClick() and leave out the toggle() method (or only call it if some condition is true).
But if you want to change the state every time a click happens, then the easiest way is to use the OnClickListener, and just negate your conditions (e.g. if you want to do something when the checkbox was empty, then you check if the checkbox's new state is not empty).
I have a checkbox. It is set to true or false depending on if a task is done or not (its a manual change). When the task is done I want the textview label to change frmo not done to done and vice versa. So I have the following code. When they click the checkbox the onCheckedChanged method does get fired off. It chooses sets the string depending on if it is true or false correctly. But then it just exits. I get no error in the logs or on the screen but when I step through the program after it sets the string in the onCheckedChanged method it just exits the getView method completely. I cant understand what is going wrong. Theres a small problem in the first couple lines that the logic for setting if the box is true or false is not entirely correct but thats fine I can fix that no problem. I just cant understand why I cant update the label after clickign the checkbox. Any help would be great.
final CheckBox statusView = (CheckBox)convertView.findViewById(R.id.statusCheckBox);
//statusView.setChecked(true);
if(toDoItem.getStatus().toString().compareTo(ToDoItem.Status.DONE.toString()) == 0)
statusView.setChecked(true);
else
statusView.setChecked(false);
// TODO - Must also set up an OnCheckedChangeListener,
// which is called when the user toggles the status checkbox
statusView
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Log.i(TAG,"Entered onCheckedChanged()");
if(isChecked)
statusLabelValue = "Done";
else
statusLabelValue = "Not Done";
}
});
TextView statusLabel = (TextView)convertView.findViewById(R.id.StatusLabel);
statusLabel.setText(statusLabelValue);
You will have to change the textview's text in the listener:
statusView
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Log.i(TAG,"Entered onCheckedChanged()");
if(isChecked)
statusLabelValue = "Done";
else
statusLabelValue = "Not Done";
((TextView)(convertView.findViewById(R.id.StatusLabel))).setText(statusLabelValue);
}
});
since i am trying the switch first time (new to android) i am not sure how to handle this issue. i have a switch on an activity and an attached setOnCheckedChangeListener() to it. when the activity's oncreate is called i make an async call to database and depending on the values received i set the status of the switch on/off. Now the problem is that however i am setting the switch state to just show whats its current status on db and no user has changed it yet, still the listner function is called. i know that the code is working correctly but with the state changed listner i need something else to confirm that the state has been changed by the user . i think onTouchEvent(MotionEvent event) can fill the purpose but do not know hot to use it in conjuction with switch.setOnCheckedChangeListener
does anyone know of any better solution to it or atleast can help me telling how to use ontouch even with listner...
sw_recording_switch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}}
thanks !!!
Indeed when calling Switch.setChecked(boolean); the OnCheckedChangeListener will be triggerd as well.
The way I overcame this problem was to use a flag and set it to false before I call setChecked()
This way the listener will still be called when you programmatically use setChecked() but the code inside won't execute, unless a user presses on the switch.
//prevent the code from listener to run, flag set to false before calling setChecked(true);
should_run = false;
toggle_facebook.setChecked(true);
....
private OnCheckedChangeListener onSwitchSlided = new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
switch(buttonView.getId())
{
case R.id.settings_toggle_facebook:
{
if(true == should_run)
{
//do stuff
}
should_run = true;
break;
}
case R.id.settings_toggle_twitter:
{
if(true == should_run)
{
//do stuff
}
should_run = true;
break;
}
}
}
};
Two ways to handle initialization code so handlers do not fire.
Design your handler to recognize that it is initialization. Below example use isResumed() to determine if the code is initializing. This works because onCreate is called before onResume.
#Override
public void onCheckedChanged(RadioGroup rg, int checkId) {
switch (rg.getId()) {
case R.id.rgMileKilometer:
switch (checkId) {
// process the speed radio group
case R.id.rdoMiles:
// Speed Radio Group check if the mph button is checked
isMile = true;
break;
case R.id.rdoKilometer:
isMile = false;
// Speed Radio Group check if the mph button is checked
break;
}
if (isResumed()) {
//do something the code is ready...
}
}
}
Add the listeners after you have done the initialization
CheckBox cb = (CheckBox) view
.findViewById(R.id.cbApplicationCacheTabs);
cb.setChecked(isApplicationCacheTabs);
cb.setOnCheckedChangeListener(this);
This is not so much of a problem but I am trying to find a correct way of doing this.
I have the following situation:
public class SettingsDialogFragment extends DialogFragment implements OnCheckedChangeListener {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.settings, container);
...
CheckBox lBox1 = (CheckBox)view.findViewById(R.id.checkBox1);
lBox1.setOnCheckedChangeListener(this);
lBox1.setChecked(true);
return view;
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
....
}
The "problem" I have is that by calling setChecked(true) the onCheckChanged will already fire. I guess that when I inflate the layout - the CheckBox is initialised with a false setting and me changing that to true indeed is a CheckedChanged event.
I could of course change the order and assign the listener after I set the initial value, but is there a way to inflate the layout whilst somehow passing the initial values for the various components? They are dynamic so I cannot fix the values to a particular value in the settings.xml
Cheers
The above suggestion is good, but this problem still exists in a checkable ListView. I solved it in this way: disable the listener, set check state, and then set listener again. Here is a helper function:
private void checkCheckBox(CheckBox checkBox, boolean checked) {
checkBox.setOnCheckedChangeListener(null);
checkBox.setChecked(checked);
checkBox.setOnCheckedChangeListener(this);
}
You've answered your own question, the setChecked(true) is causing the OnCheckedChangeListener to be called.
A simple fix would be to add android:checked="true" to your CheckBox XML declaration and omit the setChecked(true) call.
The code of the CheckBox looks something like this:
public void setChecked(boolean checked) {
if (mChecked != checked) {
mChecked = checked;
refreshDrawableState();
// Avoid infinite recursions if setChecked() is called from a listener
if (mBroadcasting) {
return;
}
mBroadcasting = true;
if (mOnCheckedChangeListener != null) {
mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
}
if (mOnCheckedChangeWidgetListener != null) {
mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
}
mBroadcasting = false;
}
}
So basically you cannot use the method without firing events, unless you remove or disable the event handler before (or set them afterwards only).
If you just want to set initial values, then your first suggestion is probably the best: just register the listeners after you have initialized everything.
The solution is the OnTouchListener. By default you don't set the OnCheckedChangeListener. What you have to do is the following:
**declared in the class object declaration**:
OnCheckedChangeListener onCheckedChangeListener = new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
**have fun**
}
};
**used to the point you would have set the OnCheckedChangeListener**
anyView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
anyUsableView.setOnCheckedChangeListener(onCheckedChangeListener);
return false;
}
});
The return false to the OnTouchListener is very important, otherwise the view will not work anymore.
Tip: this solution can be used with any kind of listener that is good for it (I am using it with a Switch widget)
I guess the solution could be a setChecked() function which detaches the listener before setting the checked value.
public void setCheckedNoEvent(boolean checked) {
if (onCheckedChangeListener == null) {
switcher.setChecked(checked);
} else {
switcher.setOnCheckedChangeListener(null);
switcher.setChecked(checked);
switcher.setOnCheckedChangeListener(OnCheckedChangeListener);
}
}
What would be the correct way of receiving and sending an event when a check box gets enabled or disabled?
In C# I could just easily double click and all the code would be done for me. But in android it appears to be a bit more obscure. I thought of using the touch event handlers but then if the user has a keyboard it won't detect the change since it's not touch. I figure android should have a native event for check box state change.
CheckBox repeatChkBx = ( CheckBox ) findViewById( R.id.repeat_checkbox );
repeatChkBx.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if ( isChecked )
{
// perform logic
}
}
});
Since CheckBox (eventually) extends View, you can use a standard OnClickListener to detect when the CheckBox is actually tapped by the user (as opposed to the ListView updates):
CheckBox repeatChkBx = ( CheckBox ) findViewById( R.id.repeat_checkbox );
repeatChkBx.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ( ((CheckBox)v).isChecked() ) {
// perform logic
}
}
});
In Kotlin:
checkBoxView.setOnCheckedChangeListener { _, isChecked ->
print("checked: $isChecked")
}
Try this
CheckBox checkbox=(CheckBox)findViewById(R.id.checkbox);
checkbox.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (checkbox.isChecked())
{
//Perform action when you touch on checkbox and it change to selected state
}
else
{
//Perform action when you touch on checkbox and it change to unselected state
}
}
});