Reputation: 6114
This question is similar to this. However it did not solve my problem.
I have a ToggleButton
and when a user clicks, I do not want to change the state of the ToggleButton, as I am programatically changing the state from another Activity.
How do I override it?
Here is my Activity code:
<ToggleButton
android:id="@+id/alarm1"
android:background="@drawable/check"
android:layout_alignParentLeft="true"
android:layout_margin="8dp"
android:textOn=""
android:onClick="alarmSet1"
android:textOff=""
android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Here is the Java code:
public void alarmSet1(View view)
{
int a1=1;
int idTime = (int) System.currentTimeMillis();
Intent intent = new Intent(MainActivity.this, AddAlarm.class);
intent.putExtra("pendInt",idTime);
intent.putExtra("tts",a1);
startActivity(intent);
}
Upvotes: 1
Views: 2248
Reputation: 581
I am late to the party, but I had the exact same question and the given answer didn't fit my needs, so I made something myself.
What I wanted (correct me if this was not the original question):
Switch
, RadioButton
, CheckBox
or any other CompoundButton
, making sure the button itself doesn't toggle state, but instead calling a function which will eventually lead to the correct state being set programatically. (eg. using LiveData
) so the state of the button is always the same as the state of the data it toggles.What I made:
/**
* Use this if you want your compoundButton to do something when (un) checked,
* but not change it's state by itself.
*
* It will block the actual changing of the button, but instead run [onCheckedChanged]
* which should in turn eventually lead to setting `isChecked` to get proper setting of the switch
* after its action has been performed
* This might cause some trouble as it will trigger on programmatic sets outside of this listener.
* To get around that, use [setIsCheckedWithoutBypassedListener] if you don't want that to happen.
*/
fun CompoundButton.setInterceptedOnCheckedChangedListener(onCheckedChanged: CompoundButton.OnCheckedChangeListener){
compoundButtonListeners[this] = onCheckedChanged
setOnCheckedChangeListener { compoundButton, b ->
compoundButton.isChecked = !compoundButton.isChecked
onCheckedChanged.onCheckedChanged(compoundButton, b)
}
}
/**
* Set value without triggering the listener added in [setInterceptedOnCheckedChangedListener]
*/
fun CompoundButton.setIsCheckedWithoutBypassedListener(isChecked: Boolean){
compoundButtonListeners[this]?.let{ l ->
setOnCheckedChangeListener(null)
this.isChecked = isChecked
setOnCheckedChangeListener(l)
}
}
/**
* Holds the OnCheckedChangeListeners for the compoundbuttons, as they are private and cannot
* be retreived otherwise.
*/
private val compoundButtonListeners = WeakHashMap<CompoundButton, CompoundButton.OnCheckedChangeListener>()
If this ends up putting a lot of _, _ ->
's in your code, feel free to replace the CompoundButton.OnCheckedChangeListener
with a View.OnClickListener
.
Leaving this here in case somebody else has the same question as I had.
I am pretty sure using a WeakHashMap prevents a memory leak that would happen on recreating activity. If this is not the case, please educate me :)
Upvotes: 2
Reputation: 1051
It is simple: Create a CompoundButton.OnCheckedChangeListener and override onCheckedChanged like this:
private CompoundButton.OnCheckedChangeListener _toggleButtonListener = new CompoundButton.OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
compoundButton.setChecked(false);
// And now, do whatever you want.
}
};
Of course, you have to attach the listener to your button:
... somewhere in the onCreate() method:
ToggleButton toggleButton=findViewById(R.id.alarm1);
toggleButton.setOnCheckedChangeListener(_toggleButtonListener);
And thats it.
Keep coding, and let the code be with you!
Upvotes: 1