OnCheckChanged ট্রিগার না করে চেকবক্স মান পরিবর্তন করুন


147

আমি setOnCheckedChangeListenerআমার জন্য বাস্তবায়ন করেছিcheckbox

আমি কল করতে পারে এমন কোন উপায় আছে?

checkbox.setChecked(false);

ট্রিগার ছাড়া onCheckedChanged


কেন কেবল একটি সাধারণ সত্য / মিথ্যা পতাকা ব্যবহার করবেন না? এটি এই সমস্যাটি সম্পর্কে সরলতম উপায় এবং এটি কেবলমাত্র তিন লাইন অতিরিক্ত কোডের মতো লাগে। আমার উত্তর নীচে দেখুন।
রুচির বড়োনিয়া

উত্তর:


279

না, আপনি এটি করতে পারবেন না। 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;            
    }
}

6
আপনি কীভাবে পাওয়ার প্রস্তাব করবেন mListener? Checkboxএর জন্য কোনও OnCheckChangeListener
গেটর নেই

20
ঠিক আছে, কারণ সমাধানটি বুঝতে পারছেন না বলেই ডাউনভোট করার দরকার নেই। ইন্টারফেসের mListenerএকটি বাস্তবায়ন OnCheckChangedListener, যা প্রোগ্রামার তৈরি করেছিল। আমার উত্তর যে বোঝা প্রোগ্রামার একটি রেফারেন্স বজায় তাদের নিজস্ব বাস্তবায়ন - mListener
শেড

আপনি যদি পুনরাবৃত্তভাবে সেটচেকড () পদ্ধতিটি ব্যবহার করতে চান তবে শ্রোতাদের পরিবর্তন করা কি অকার্যকর হবে?
রেন

4
@ রেন, শ্রোতাদের পরিবর্তন করা কেবলমাত্র CheckBoxবস্তুর মধ্যে একটি সম্পত্তি নির্ধারণের সাথে জড়িত । আমি এটি অকার্যকর বলব না।
শেড

দস্তাবেজটি "চেক করা রেডিও বোতামটি পরিবর্তিত হলে ডাকা হয় the নির্বাচনটি সাফ হয়ে গেলে, চেক ইনড -1 হয়"। এটি সত্যিই বিভ্রান্তিমূলক, এটি হয় হয় চেকডও দিয়ে যাওয়া উচিত।
এএএভিভিভি

69

OnCheckedChangeListener এর ভিতরে এই কোডটি যুক্ত করুন:

if(!compoundButton.isPressed()) {
            return;
}

এটি আমাদের আবহাওয়ার চেকবক্সের অবস্থাটি প্রোগ্রামিকভাবে বা ব্যবহারকারীর ক্রিয়াকলাপ দ্বারা পরিবর্তিত হয়েছিল তা সনাক্ত করতে সহায়তা করবে to


11
এটি সমাধান হিসাবে চিহ্নিত করা উচিত, কবজির মতো কাজ করে!
আশ্বিন বালানী

5
সচেতন থাকা! এটি অ্যাক্সেসযোগ্যতা মোড ব্রেক! আইপ্রেসড () সত্য হয় না যখন ভয়েস সহকারী মোড থেকে ডাবল ট্যাপ দ্বারা ট্রিগার করা হয়।
এম

21

এটি অর্জনের আর একটি সম্ভাব্য উপায় হ'ল একটি কাস্টম চেকবক্স ব্যবহার করা, যা আপনি শ্রোতাকে ডেকে আনা বা না চান তা চয়ন করতে দেয়:

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

11

আপনি কেবল setonclickListener ব্যবহার করুন, এটি দুর্দান্ত কাজ করবে এবং এটি খুব সহজ পদ্ধতি, ধন্যবাদ :)


35
যখন ব্যবহারকারী স্যুইচটি স্লাইড করে তখন অনক্লিক () কল করা হয় না।
জেমস

2
প্রকৃতপক্ষে, ব্যবহারকারী যখন টগল টেনে নিয়ে যায় তখন এটি করার কোনও হ্যান্ডলার ছাড়াই আপনাকে ছেড়ে যায়।
ভিক্টর জি

তাহলে আপনি কীভাবে চেকড মান পাবেন সত্য বা মিথ্যা?
অভি

6

@ শ্যাড উত্তরের সাথে কোটলিনের এক্সটেনশনগুলি ব্যবহার করুন:

fun CompoundButton.setCustomChecked(value: Boolean,listener: CompoundButton.OnCheckedChangeListener) {
     setOnCheckedChangeListener(null)
     isChecked = value
     setOnCheckedChangeListener(listener)
}

6

যে কেউ এটিকে হোঁচট খায়, তার পক্ষে সহজ উপায় হ'ল চেকবক্সে একটি ট্যাগ ব্যবহার করা এবং তার শ্রোতার উপর সেই ট্যাগটি পরীক্ষা করা (কোড কোটলিনে রয়েছে):

checkBox.tag = false
checkBox.setOnCheckedChangeListener{ buttonView, isChecked -> 
    if(checkBox.tag != true) {
        //Do some stuff
    } else {
        checkBox.tag = false
    }

তারপরে অ্যাক্সেস করার সময় যখন আপনি মান পরিবর্তনটি উপেক্ষা করতে চান তখন আইসচেকডকে সত্য সেট করার আগে কেবল ট্যাগটিকে সত্য করে রাখুন:

checkBox.tag = true
checkBox.isChecked = true

আপনি যদি বোধগম্যতা নিয়ে উদ্বিগ্ন হন তবে বিকল্প সেটট্যাগ পদ্ধতিটি ব্যবহার করে একটি কীতে ট্যাগটি কোনও কীতে ম্যাপ করতে পারেন। তবে এটি যদি একটি ক্লাসে থাকে তবে কয়েকটি মন্তব্য স্ট্রিং ঘটছে তা ব্যাখ্যা করার জন্য যথেষ্ট পরিমাণে হবে।


4

আপনি এই 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


3

চেক রেডিও বোতামের আগে পরিবর্তনজনিত তালিকায় নাল সেট করুন। চেক রেডিও বোতামের পরে আপনি শ্রোতাদের আবার সেট করতে পারেন।

radioGroup.setOnCheckedChangeListener(null);
radioGroup.check(R.id.radioButton);
radioGroup.setOnCheckedChangeListener(new 

RadioGroup.OnCheckedChangeListener() {
   @Override
   public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {

   }
});

1
কাজটি করে এবং এটি এখানে অন্যান্য সমাধানের চেয়ে দ্রুত এবং সহজতর উপায়।
PayToPwn

3

আমার ব্যাখ্যা যা আমি মনে করি সবচেয়ে সহজ
হতে পারে সহায়ক হতে পারে)

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

2

এটি আমি ব্যবহার করা একটি সহজ সমাধান:
একটি কাস্টম শ্রোতার সংজ্ঞা দিন:

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

2

এই সম্পর্কে কিভাবে। ভিউতে ট্যাগ ব্যবহার করার চেষ্টা করুন

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
            }

        }
    });

2

আমি একটি ব্যবহার করেছি 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
    }
}

1

আমি উপরের সমস্ত উত্তর খুব জটিল খুঁজে পেয়েছি। একটি সাধারণ বুলিয়ান দিয়ে কেন কেবল নিজের পতাকা তৈরি করবেন না?

বুলিয়ান সহ কেবল একটি সাধারণ পতাকা ব্যবস্থা ব্যবহার করুন। তৈরি করুন 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আবার সেট করলাম যাতে আমাদের কোডটি চালিয়ে যায়। আশাকরি এটা সাহায্য করবে!


1

এটি আপনার জন্য কাজ করা উচিত চেষ্টা করুন! আপনি ফায়ারবেস দিয়ে এটি ব্যবহার করতে পারেন!

ফায়ারবেস ডেটা পেতে! এটা ব্যবহার কর!

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

1

প্রতিবার পরিবর্তিত চেক করার সময় আমি শ্রোতাদের পাস করতে চাইনি, বা 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)যদি এখনও শ্রোতার প্রয়োজন হয় তবে আপনি তাকে অপসারণের জন্য কল করতে পারেন


0

আমার ধারণা প্রতিবিম্বটি ব্যবহার করা একমাত্র উপায়। এটার মতো কিছু:

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

ডেভস ফিল্ডের নাম পরিবর্তন না করা বা উদাহরণস্বরূপ, শ্রেণিবিন্যাসের "isChecked" পদ্ধতিটি টান পর্যন্ত কাজ করতে পারে ... বা অন্য রিফ্যাক্টরিং করতে পারে ... কমপক্ষে এমন কিছু যুক্ত করুনif(Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN){ /* do reflection */}
এয়ারাকোড

এটিপি ভাঙতে এবং ইন্টার্নালগুলি খনন করতে উত্সাহিত করা একটি ভুল ধারণা। বাস্তবায়নের যে কোনও পরিবর্তন অ্যাপ্লিকেশনকে ব্যর্থ করে দেবে।
mspanc

0

আমার সমাধান @ ক্রিস উত্তরের ভিত্তিতে জাভাতে লেখা:

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 টি চেকবাক্স এবং সর্বদা একটি চেক করা হবে (একটি অবশ্যই যদিও অবশ্যই চেক করা উচিত)। চেকড চ্যাঞ্জড শ্রোতাদের সত্যিকারের ব্লকগুলিতে ট্যাগ সেট করা।


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

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.