मेरे पास है setOnCheckedChangeListener
अपने लिए लागू किया हैcheckbox
क्या कोई रास्ता है जिससे मैं फोन कर सकता हूं
checkbox.setChecked(false);
ट्रिगर किए बिना onCheckedChanged
मेरे पास है setOnCheckedChangeListener
अपने लिए लागू किया हैcheckbox
क्या कोई रास्ता है जिससे मैं फोन कर सकता हूं
checkbox.setChecked(false);
ट्रिगर किए बिना onCheckedChanged
जवाबों:
नहीं, आप ऐसा नहीं कर सकते। onCheckedChanged
विधि से सीधे कहा जाता है setChecked
। आप निम्न कार्य कर सकते हैं:
mCheck.setOnCheckedChangeListener (null);
mCheck.setChecked (false);
mCheck.setOnCheckedChangeListener (mListener);
चेकबॉक्स का स्रोत और उसका कार्यान्वयन देखें setChecked
:
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;
}
}
mListener
? Checkbox
इसके लिए एक OnCheckChangeListener
mListener
का एक कार्यान्वयन है OnCheckChangedListener
, जो प्रोग्रामर द्वारा बनाया गया था। मेरे उत्तर का तात्पर्य है कि प्रोग्रामर ने अपने स्वयं के कार्यान्वयन के संदर्भ को बनाए रखा - mListener
।
CheckBox
ऑब्जेक्ट में केवल एक संपत्ति की स्थापना शामिल है । मैं यह नहीं कहूंगा कि यह अक्षम है।
इस कोड को OnCheckedChangeListener के अंदर जोड़ें:
if(!compoundButton.isPressed()) {
return;
}
यह हमें मौसम चेकबॉक्स स्थिति का पता लगाने में मदद करेगा जो प्रोग्रामेटिक रूप से या उपयोगकर्ता कार्रवाई द्वारा बदल दिया गया था।
इसे प्राप्त करने का एक और संभावित तरीका एक कस्टम चेकबॉक्स का उपयोग करके है, जो आपको यह चुनने देगा कि आप श्रोता को बुलाना चाहते हैं या नहीं:
public class CheckBox extends AppCompatCheckBox {
private OnCheckedChangeListener mListener;
public CheckBox(final Context context) {
super(context);
}
public CheckBox(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public CheckBox(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setOnCheckedChangeListener(final OnCheckedChangeListener listener) {
mListener = listener;
super.setOnCheckedChangeListener(listener);
}
public void setChecked(final boolean checked, final boolean alsoNotify) {
if (!alsoNotify) {
super.setOnCheckedChangeListener(null);
super.setChecked(checked);
super.setOnCheckedChangeListener(mListener);
return;
}
super.setChecked(checked);
}
public void toggle(boolean alsoNotify) {
if (!alsoNotify) {
super.setOnCheckedChangeListener(null);
super.toggle();
super.setOnCheckedChangeListener(mListener);
}
super.toggle();
}
}
कोटलिन संस्करण, यदि आप पसंद करते हैं:
class CheckBox @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : AppCompatCheckBox(context, attrs, defStyleAttr) {
private var listener: CompoundButton.OnCheckedChangeListener? = null
override fun setOnCheckedChangeListener(listener: CompoundButton.OnCheckedChangeListener?) {
this.listener = listener
super.setOnCheckedChangeListener(listener)
}
fun setChecked(checked: Boolean, alsoNotify: Boolean) {
if (!alsoNotify) {
super.setOnCheckedChangeListener(null)
super.setChecked(checked)
super.setOnCheckedChangeListener(listener)
return
}
super.setChecked(checked)
}
fun toggle(alsoNotify: Boolean) {
if (!alsoNotify) {
super.setOnCheckedChangeListener(null)
super.toggle()
super.setOnCheckedChangeListener(listener)
}
super.toggle()
}
}
नमूना उपयोग:
checkBox.setChecked(true,false);
आप बस setonclickListener का उपयोग करते हैं, यह ठीक काम करेगा और यह बहुत सरल विधि है, धन्यवाद :)
किसी के लिए भी जो इस तरह से ठोकर खाता है, ऐसा करने का एक सरल तरीका सिर्फ चेकबॉक्स पर टैग का उपयोग करना है और फिर उस टैग को उसके श्रोता (कोड कोटलीन में है) पर जांचना है:
checkBox.tag = false
checkBox.setOnCheckedChangeListener{ buttonView, isChecked ->
if(checkBox.tag != true) {
//Do some stuff
} else {
checkBox.tag = false
}
तब जब आप मूल्य को अनदेखा करना चाहते हैं तो एक्सेस करने से पहले टैग को सही पर सेट करें
checkBox.tag = true
checkBox.isChecked = true
आप वैकल्पिक सेटटैग पद्धति का उपयोग करके टैग को एक कुंजी पर मैप कर सकते हैं, जिसे समझने के लिए यदि आप चिंतित थे, तो एक कुंजी की आवश्यकता होती है। लेकिन अगर यह सब एक ही वर्ग के लिए होता है तो कुछ कमेंट स्ट्रिंग्स, व्हाट्सएप को समझने के लिए पर्याप्त होंगे।
आप अपने चेकबॉक्स के रूप में इस SafeCheckBox वर्ग का उपयोग कर सकते हैं:
public class SafeCheckBox extends AppCompatCheckBox implements CompoundButton.OnCheckedChangeListener {
private OnSafeCheckedListener onSafeCheckedListener;
private int mIgnoreListener = CALL_LISTENER;
public static final int IGNORE = 0;
public static final int CALL_LISTENER = 1;
@Retention(RetentionPolicy.SOURCE)
@IntDef({IGNORE, CALL_LISTENER})
public @interface ListenerMode {
}
public SafeCheckBox(Context context) {
super(context);
init(context);
}
public SafeCheckBox(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SafeCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
/**
* @param checkState change state of the checkbox to
* @param mIgnoreListener true to ignore the listener else listener will be notified
*/
public void setSafeCheck(boolean checkState, @ListenerMode int mIgnoreListener) {
if (isChecked() == checkState) return; //already in the same state no need to fire listener.
if (onSafeCheckedListener != null) { // this to avoid a bug if the user listens for the event after using this method and in that case he will miss first check
this.mIgnoreListener = mIgnoreListener;
} else {
this.mIgnoreListener = CALL_LISTENER;
}
setChecked(checkState);
}
private void init(Context context) {
setOnCheckedChangeListener(this);
}
public OnSafeCheckedListener getOnSafeCheckedListener() {
return onSafeCheckedListener;
}
public void setOnSafeCheckedListener(OnSafeCheckedListener onSafeCheckedListener) {
this.onSafeCheckedListener = onSafeCheckedListener;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (onSafeCheckedListener != null)
onSafeCheckedListener.onAlwaysCalledListener(buttonView, isChecked);// this has to be called before onCheckedChange
if (onSafeCheckedListener != null && (mIgnoreListener == CALL_LISTENER)) {
onSafeCheckedListener.onCheckedChanged(buttonView, isChecked);
}
mIgnoreListener = CALL_LISTENER;
}
/**
* Listener that will be called when you want it to be called.
* On checked change listeners are called even when the setElementChecked is called from code. :(
*/
public interface OnSafeCheckedListener extends OnCheckedChangeListener {
void onAlwaysCalledListener(CompoundButton buttonView, boolean isChecked);
}
}
तब आप कॉल कर सकते हैं: -
setSafeCheck(true,ListenerMode.IGNORE);// OnCheckedChange listener will not be notified
चेक रेडियो बटन से पहले चेंजलिस्ट को नल सेट करें। चेक रेडियो बटन के बाद आप श्रोता को फिर से सेट कर सकते हैं।
radioGroup.setOnCheckedChangeListener(null);
radioGroup.check(R.id.radioButton);
radioGroup.setOnCheckedChangeListener(new
RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
}
});
मेरी व्याख्या जो मुझे लगता है कि सबसे आसान
हो सकता है सहायक हो)
public class ProgrammableSwitchCompat extends SwitchCompat {
public boolean isCheckedProgrammatically = false;
public ProgrammableSwitchCompat(final Context context) {
super(context);
}
public ProgrammableSwitchCompat(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public ProgrammableSwitchCompat(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setChecked(boolean checked) {
isCheckedProgrammatically = false;
super.setChecked(checked);
}
public void setCheckedProgrammatically(boolean checked) {
isCheckedProgrammatically = true;
super.setChecked(checked);
}
}
इसका इस्तेमाल करें
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean on) {
if (((ProgrammableSwitchCompat) compoundButton).isCheckedProgrammatically) {
return;
}
//...
((ProgrammableSwitchCompat) compoundButton).setCheckedProgrammatically(true);
//...
((ProgrammableSwitchCompat) compoundButton).setCheckedProgrammatically(false);
//...
}
उपयोग ट्रिगर हो जाएगा setChecked(boolean)
फ़ंक्शन
जो सभी है
KOTLIN
class MyCheckBox @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.switchStyle
) : AppCompatCheckBox(context, attrs, defStyleAttr) {
var programmatically = false
override fun setChecked(checked: Boolean) {
programmatically = false
super.setChecked(checked)
}
fun setCheckedProgrammatically(checked: Boolean) {
programmatically = true
super.setChecked(checked)
}
}
यह एक सरल समाधान है जिसका मैंने उपयोग किया:
एक कस्टम श्रोता को परिभाषित करें:
class CompoundButtonListener implements CompoundButton.OnCheckedChangeListener {
boolean enabled = false;
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
}
void enable() {
enabled = true;
}
void disable() {
enabled = false;
}
boolean isEnabled() {
return enabled;
}
}
प्रारंभ:
CompoundButtonListener checkBoxListener = new CompoundButtonListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
if (isEnabled()) {
// Your code goes here
}
}
};
myCheckBox.setOnCheckedChangeListener(checkBoxListener);
उपयोग:
checkBoxListener.disable();
// Some logic based on which you will modify CheckBox state
// Example: myCheckBox.setChecked(true)
checkBoxListener.enable();
इस बारे में कैसा है। देखें में टैग का उपयोग करने का प्रयास करें
mCheck.setTag("ignore");
mCheck.setChecked(true);
mCheck.setTag(null);
तथा
switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean selected) {
//If switch has a tag, ignore below
if(compoundButton.getTag() != null)
return;
if (selected) {
// do something
} else {
// do something else
}
}
});
ReentrantLock
जब भी मैं सेटिंग कर रहा हूं, मैंने उसका उपयोग किया , और उसे लॉक किया isChecked
:
// lock when isChecked is being set programmatically
val isBeingProgrammaticallySet = ReentrantLock()
// set isChecked programmatically
isBeingProgrammaticallySet.withLock()
{
checkbox.isChecked = true
}
// do something only when preference is modified by user
checkbox.setOnCheckedChangeListener()
{
_,isChecked ->
if (isBeingProgrammaticallySet.isHeldByCurrentThread.not())
{
// do it
}
}
मुझे उपरोक्त सभी उत्तर रास्ते बहुत जटिल लगे। सिर्फ एक साधारण बूलियन के साथ अपना झंडा क्यों नहीं बनाया?
बस बूलियन के साथ एक सरल ध्वज प्रणाली का उपयोग करें। बनाएँ boolean noListener
। जब भी आप किसी भी कोड को चलाए बिना अपना स्विच ऑन / ऑफ करना चाहते हैं (इस उदाहरण में, जैसा कि दर्शाया गया है runListenerCode()
, बस noListener=true
कॉल करने से पहले सेट करेंswitch.setChecked(false/true)
switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean selected) {
if (!noListener) { //If we want to run our code like usual
runListenerCode();
} else { //If we simply want the switch to turn off
noListener = false;
}
});
सरल झंडे का उपयोग करते हुए बहुत सरल समाधान। अंत में, हम noListener=false
एक बार फिर सेट करते हैं ताकि हमारा कोड काम करना जारी रखे। उम्मीद है की यह मदद करेगा!
यह एक आप के लिए काम करना चाहिए कोशिश करो! आप इसे फायरबेस के साथ भी उपयोग कर सकते हैं!
फायरबेस डाटा पाने के लिए! इसे इस्तेमाल करो!
databaseReference.child(user.getPhoneNumber()).child("Reqs").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
SharedPreferences prefs = mContext.getSharedPreferences("uinfo", MODE_PRIVATE);
String pno = prefs.getString("username", "No name defined");
if(dataSnapshot.child(pno).getValue(String.class).equals("acc")){
holder.acc.setChecked(true);
}else{
holder.acc.setChecked(false);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w("dfs", "loadPost:onCancelled", databaseError.toException());
// ...
}
});
उसके बाद जब यूजर कुछ करेगा!
holder.acc.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
if(buttonView.isPressed()) {
//your code
}
}
else {
if(buttonView.isPressed()) {
//your code
}
}
}
});
मैं वास्तव में श्रोता को पारित करने के लिए नहीं होना चाहता था, हर बार जब हम सेट चेक करते हैं, और न ही उपयोग करते हुए enabled
यह निर्धारित करने के तरीके के रूप में रहे हैं कि क्या हमें मूल्य सेट करना चाहिए (उस स्थिति में क्या होता है जब हमारे पास मूल्य सेट करते समय स्विच पहले से ही अक्षम है ?)
इसके बजाय मैं एक आईडी और आपके द्वारा कॉल की जा सकने वाली एक्सटेंशन विधियों के साथ टैग का उपयोग कर रहा हूं:
fun CompoundButton.setOnCheckedWithoutCallingChangeListener(
listener: (view: CompoundButton, checked: Boolean) -> Unit
) {
setOnCheckedChangeListener { view, checked ->
if (view.getTag(R.id.compound_button_checked_changed_listener_disabled) != true) {
listener(view, checked)
}
}
this.setTag(R.id.compound_button_enabled_checked_change_supported, true)
}
fun CompoundButton.setCheckedWithoutCallingListener(checked: Boolean) {
check(this.getTag(R.id.compound_button_enabled_checked_change_supported) == true) {
"Must set listener using `setOnCheckedWithoutCallingChangeListener` to call this method"
}
setTag(R.id.compound_button_checked_changed_listener_disabled, true)
isChecked = checked
setTag(R.id.compound_button_checked_changed_listener_disabled, false)
}
अब आप कॉल कर सकते हैं setCheckedWithoutCallingListener(bool)
और यह सही श्रोता उपयोग को लागू करेगा।
setChecked(bool)
यदि आपको अभी भी ज़रूरत है तो आप श्रोता को आग लगाने के लिए कॉल कर सकते हैं
मुझे लगता है कि प्रतिबिंब का उपयोग करना एकमात्र तरीका है। कुछ इस तरह:
CheckBox cb = (CheckBox) findViewById(R.id.checkBox1);
try {
Field field = CompoundButton.class.getDeclaredField("mChecked");
field.setAccessible(true);
field.set(cb, cb.isChecked());
cb.refreshDrawableState();
cb.invalidate();
} catch (Exception e) {
e.printStackTrace();
}
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN){ /* do reflection */}
@ समाधान पर आधारित जावा में लिखा गया मेरा समाधान:
chkParent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(buttonView.getTag() != null){
buttonView.setTag(null);
return;
}
if(isChecked){
chkChild.setTag(true);
chkChild.setChecked(false);
}
else{
chkParent.setChecked(true);
}
}
});
chkChild.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(buttonView.getTag() != null){
buttonView.setTag(null);
return;
}
if(isChecked){
chkParent.setTag(true);
chkParent.setChecked(false);
}
else{
chkChild.setChecked(true);
}
}
});
2 चेकबॉक्स और हमेशा एक चेक किया जाएगा (हालांकि शुरू में चेक किया जाना चाहिए)। टैग को सच्चे ब्लॉक पर सेट करना
public void setCheckedChangeListenerSwitch() {
switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean selected) {
if (selected) {
// do something
} else {
// do something else
}
}
});
}
// Update state & reset listener (so onCheckedNot called)
public void updateSwitchState(boolean state){
switch.setOnCheckedChangeListener(null);
switch.setChecked(state);
setCheckedChangeListenerSwitch();
}