No access to the view from within switch android - android

I used a very similar piece of code as below to setOnClickListener on a button and the view was passed through.
((Switch) convertView.findViewById(R.id.push_switch)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(rowItem.getPush().equals("N")){
((Switch) convertView.findViewById(R.id.push_switch)).toggle();
rowItem.setPush("Y");
}
else if(rowItem.getPush().equals("Y")){
((Switch) convertView.findViewById(R.id.push_switch)).toggle();
rowItem.setPush("N");
}
}
});
Within the code above, there view isn't passed through so how can I access it to change where I have put convertView.
A side query that isn't crucial to the question is why the first line of this was cast to (Switch) when that didn't happen on a button. Just intrigued on that one!
Thanks :)

As #Mike M commented, compoundButton is the Switch. The callback method onCheckedChanged is passing you a reference to the CompoundButton which triggered the callback...in this case, your Switch.
You can do this:
compoundButton.toggle();

Related

Android layout state condition

I have a check box in my view and an EditText.
I would like to enable my editText only when CheckBox is checked directly with layout condition :
android:enabled="#{checkBox.isChecked}"
but i have a compilation error. How can i do this ?
Thank's
You should set your edittext to enabled false. And in your checkBox listener do something like this:
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
{
if(compoundButton.isChecked){
editText.setFocusable(true);
editText.setFocusableInTouchMode(true);
editText.setCursorVisible(true);
editText.setEnabled(true);
}else{
editText.setFocusable(false);
editText.setFocusableInTouchMode(false);
editText.setCursorVisible(false);
editText.setEnabled(false);
}
}
});
The xml loads at compile time, in life cycle onCreate() method calls.
After that only user has vsisbility to the layout.
You are providing a null to the condition beacuse the checkbox is not even initialised while you try to find its state.
Write the code to find the checkbox state and assign it to the editext or textbox in the onResume method.
https://developer.android.com/guide/components/activities/activity-lifecycle.html
check this for better understanding...

Identify when default Android Checkbox animation ends

When clicking on a Checkbox, a default Android material design animation is triggered (from blank to a "V" mark, and from "V" mark to a blank).
I want to identify when the animation ends.
According to documentation, this should be possible in one of two ways -
When the checkbox is checked or unchecked (setOnCheckedChangeListener()), obtain the current Animation object (getAnimation()) and register a listener on it (setAnimationListener()). Unfortunately, this doesn't work - the Animation object, at this point in time, is null.
Subclass the Checkbox object and implement its onAnimationEnd() method. Unfortunately, this doesn't work as well - the method is never called.
What am I missing? What is a good way to identify when such a default animation ends? I assume the relevant events can be registered on some other view in the activity, but I can't figure out which.
Here is a relevant code snippet for the first approach (animation is always null) -
CheckBox checkBox = (CheckBox)findViewById(R.id.checkbox1);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
Animation animation = compoundButton.getAnimation();
Log.d("Checkbox", "Animation is " + animation);
}
});
I was somewhat successful setting the following OnCheckedChangeListener on the Checkbox.
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Drawable drawable = buttonView.getButtonDrawable().getCurrent();
if (drawable instanceof AnimatedVectorDrawable) {
AnimatedVectorDrawable animatedDrawable = (AnimatedVectorDrawable) drawable;
animatedDrawable.registerAnimationCallback(new Animatable2.AnimationCallback() {
#Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
// your action goes here
}
});
} else {
// and maybe here as well as a fallback
}
}
Quite often (maybe 50% of the time) the onAnimationEnd callback is triggered twice. I don’t understand why, though.

how to skip switch.setOnCheckedChangeListener when status is not updated by user

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);

Checkbox default value & OnCheckedChangeListener

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);
}
}

Android: ToggleButton Listener

I have this code here
ToggleButton toggleAlarm = (ToggleButton) d.findViewById(R.id.toggle_alarm);
toggleAlarm.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked)
{
Log.d("alarmCheck","ALARM SET TO TRUE");
sched.setAlarm(true);
}
else
{
Log.d("alarmCheck","ALARM SET TO FALSE");
sched.setAlarm(false);
}
}
});
I have to keep track if its ON or OFF. But when I logged something to logcat where it is on or off, it won't do a thing. I don't know, what is wrong, because on my other code same, syntax but it works I just copy paste it and change only the ToggleButton variable.
EDIT
I have observed, with the help of cdr. Powell of course, that when you put this code block, the one that I have posted, inside another anonymous listener, say listener for a save button, the checkOnChangedListener is broken, it doesn't function well inside another anonymous listener, but the one thing that I don't understand is that, there is also a outer listener in my code, it is like a button to display a dialog box and inside that dialog box, there is an add button that opens another dialog box which has that toggle button and another button for save or add which closes that dialog and returns to the previous dialog which will then display the newly added record, so anyone of you have an idea why is it broken when i put it inside a listener for a save button but works fine in a outer listener.
try this, May be the problem is with import
toggleAlarm.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked)
{
Log.d("alarmCheck","ALARM SET TO TRUE");
sched.setAlarm(true);
}
else
{
Log.d("alarmCheck","ALARM SET TO FALSE");
sched.setAlarm(false);
}
}
});
Try toggleAlarm.isChecked() too see if the button is checked or not.
In case toggleAlarm.isChecked() does not work for you you could always.
boolean _isChecked = false;
((ToggleButton) d.findViewById(R.id.toggle_alarm)).setOnClickListener(new OnOnClickListener() {
public void onClick(View arg0) {
_isChecked = !isChecked;
if(_isChecked()) {
Log.d("alarmCheck","ALARM SET TO TRUE");
sched.setAlarm(true);
}
else {
Log.d("alarmCheck","ALARM SET TO FALSE");
sched.setAlarm(false);
}
}
});
So i have observed, with the help of cdr. powell of course, that when u put this code block, the one that i have posted, inside another anonymous listener, say listener for a save button, the checkOnChangedListener is broken, it doesn't function well inside another anonymous listener, but the one thing that i don't understand is that, there is also a outer listener in my code, its like a button to display a dialog box and inside that dialog box, there is an add button that opens another dialog box which has that toggle button and another button for save or add which closes that dialog and returns to the previous dialog which will then display the newly added record, so anyone of you have an idea why is it broken when i put it inside a listener for a save button but works fine in a outer listener.

Categories

Resources