android.widget.Switch - ऑन / ऑफ इवेंट श्रोता?


229

मैं एक स्विच बटन लागू करना चाहूंगा, android.widget.Switch (एपीआई v.14 से उपलब्ध)।

<Switch
    android:id="@+id/switch1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Switch" />

लेकिन मुझे यकीन नहीं है कि बटन के लिए एक ईवेंट श्रोता कैसे जोड़ा जाए। क्या यह एक "ऑनक्लिक" श्रोता होना चाहिए? और मुझे कैसे पता चलेगा कि यह "चालू" है या नहीं?


6
XML के माध्यम से OnClick वास्तव में काम करता है - लेकिन केवल बटन पर "क्लिक" के लिए, "स्लाइड" के लिए नहीं।
m02ph3u5 12

जवाबों:


492

इनहेरिट CompoundButtonकी विशेषताओं को स्विच करें , इसलिए मैं OnCheckedChangeListener की सिफारिश करूंगा

mySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // do something, the isChecked will be
        // true if the switch is in the On position
    }
});

2
@ जोहान कोई मुसीबत नहीं। मैं आपके बारे में नहीं जानता, लेकिन मेरी इच्छा है कि वे इसका नाम OnCheckChangedListener रखे, OnItemSelectedListener के समान, चूंकि On- Noun - Verb -Listener एक स्थापित नामकरण संधि है।
सैम

2
लेकिन जब आप एक टुकड़े को उदाहरण के लिए रखते हैं, तो जब भी आप स्विच को ऑन पर सेट करते हैं, तो वह चीज हमेशा फायर हो जाती है।
klutch

1
अगर मैं विधि सेटचेक () विधि का उपयोग कर चालू या बंद करना चाहता हूँ, तो क्या बदल सकता है और चालू विधि को निष्पादित नहीं करना चाहता? लेकिन जब उपयोगकर्ता फिर से स्विच विधि पर टैप करता है onCheckedChanged निष्पादित हो जाता है ... क्या ऐसा करने का कोई तरीका है?
गहरा कुमार

2
बटन है OnCLick, स्विच नहीं है OnChange! अच्छी तरह से डिजाइन गूगल टीम!
वसीलिस

1
@KZoNE मैंने यहां क्या किया, राज्य को बदलने के लिए क्लिक श्रोता का उपयोग किया जाता है और स्विच को विधि (मेरे मामले में API कॉल) में पारित किया और फिर राज्य को बदलने के लिए setChecked () विधि का उपयोग किया (जैसे API कॉल में onFailure /EError) । उम्मीद है की वो मदद करदे।
गहरा कुमार

53

XML के माध्यम से अपने लेआउट में स्विच जोड़ने के लिए निम्नलिखित स्निपेट का उपयोग करें:

<Switch
     android:id="@+id/on_off_switch"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textOff="OFF"
     android:textOn="ON"/>

फिर अपनी गतिविधि के ऑनक्रिट विधि में, अपने स्विच का संदर्भ लें और इसके ऑनचेकचेंज लाइटर को सेट करें:

Switch onOffSwitch = (Switch)  findViewById(R.id.on_off_switch); 
onOffSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    Log.v("Switch State=", ""+isChecked);
}       

});

3
यह एक अधिक स्पष्ट उत्तर है जो आपको मिलान करने के लिए लेआउट और कोड देता है।
एशेसटॉएश

एकल श्रोता में कई स्विचकॉम कैसे प्रबंधित करें? कृपया इसके लिए उत्तर का सुझाव दें
आनंद सवजनी

22

कोटलिन का उपयोग करने वालों के लिए, आप एक स्विच के लिए श्रोता सेट कर सकते हैं (इस मामले में आईडी होने पर mySwitch) निम्नानुसार है:

    mySwitch.setOnCheckedChangeListener { _, isChecked ->
         // do whatever you need to do when the switch is toggled here
    }

isChecked यह सही है यदि स्विच को वर्तमान में (ON) चेक किया गया है, और अन्यथा गलत है।


19

अपने XML लेआउट को परिभाषित करें:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.neoecosystem.samplex.SwitchActivity">

    <Switch
        android:id="@+id/myswitch"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content" />

</RelativeLayout> 

फिर एक गतिविधि बनाएं

public class SwitchActivity extends ActionBarActivity implements CompoundButton.OnCheckedChangeListener {

    Switch mySwitch = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_switch);


        mySwitch = (Switch) findViewById(R.id.myswitch);
        mySwitch.setOnCheckedChangeListener(this);
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            // do something when check is selected
        } else {
            //do something when unchecked
        }
    }

    ****
}

======== नीचे एपीआई 14 के लिए लिए स्विचकॉम का उपयोग करें =========

एक्सएमएल

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.neoecosystem.samplex.SwitchActivity">

    <android.support.v7.widget.SwitchCompat
        android:id="@+id/myswitch"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content" />

</RelativeLayout>

गतिविधि

public class SwitchActivity extends ActionBarActivity implements CompoundButton.OnCheckedChangeListener {

    SwitchCompat mySwitch = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_switch);


        mySwitch = (SwitchCompat) findViewById(R.id.myswitch);
        mySwitch.setOnCheckedChangeListener(this);
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            // do something when checked is selected
        } else {
            //do something when unchecked
        }
    }
   *****
}

2
बटन देखना मत भूलना। देखिए ()
जैकसन एफ

5

स्विच विजेट के लिए लेआउट कुछ इस तरह है।

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <Switch
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:gravity="right"
        android:text="All"
        android:textStyle="bold"
        android:textColor="@color/black"
        android:textSize="20dp"
        android:id="@+id/list_toggle" />
</LinearLayout>

गतिविधि वर्ग में, आप दो तरीकों से कोड कर सकते हैं। आप उपयोग कर सकते हैं कोड पर निर्भर करता है।

पहला रास्ता

public class ActivityClass extends Activity implements CompoundButton.OnCheckedChangeListener {
Switch list_toggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.return_vehicle);

    list_toggle=(Switch)findViewById(R.id.list_toggle);
    list_toggle.setOnCheckedChangeListener(this);
    }
}

public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
    if(isChecked) {
        list_toggle.setText("Only Today's");  //To change the text near to switch
        Log.d("You are :", "Checked");
    }
    else {
        list_toggle.setText("All List");   //To change the text near to switch
        Log.d("You are :", " Not Checked");
    }
}

दूसरा तरीका

public class ActivityClass extends Activity {
Switch list_toggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.return_vehicle);

    list_toggle=(Switch)findViewById(R.id.list_toggle);
    list_toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
       @Override
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
          if(isChecked) {
             list_toggle.setText("Only Today's");  //To change the text near to switch
             Log.d("You are :", "Checked");
          }
          else {
             list_toggle.setText("All List");  //To change the text near to switch
             Log.d("You are :", " Not Checked");
          }
       }       
     });
   }
}

2

स्विच चेक किए गए चेंज इवेंट के लिए आप डेटाबाइंडिंग और व्यूमॉडल का उपयोग कर सकते हैं

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
                name="viewModel"
                type="com.example.ui.ViewModel" />
    </data>
    <Switch
            android:id="@+id/on_off_switch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onCheckedChanged="@{(button, on) -> viewModel.onCheckedChange(on)}"
     />


1
android.widget.Switch पर onCheckedChanged attirbute नहीं है। आपको त्रुटि मिलेगी: AAPT: त्रुटि: विशेषता Android: onCheckedChanged नहीं मिला।
बेचा गया

1

दो तरीके हैं,

  1. Xml ऑनक्लिक दृश्य का उपयोग करके नीचे XML में स्विच जोड़ें:

    <Switch
    android:id="@+id/switch1"
    android:onClick="toggle"/>

YourActivity Class में (उदा। MainActivity.java के लिए)

    Switch toggle; //outside oncreate
    toggle =(Switch) findViewById(R.id.switch1); // inside oncreate

    public void toggle(View view) //outside oncreate
    {
        if( toggle.isChecked() ){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                start.setBackgroundColor(getColor(R.color.gold));
                stop.setBackgroundColor(getColor(R.color.white));
            }
        }
        else
        {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                stop.setBackgroundColor(getColor(R.color.gold));
                start.setBackgroundColor(getColor(R.color.white));
            }
        }
    }
  1. क्लिक श्रोता पर उपयोग करना

नीचे के रूप में XML में स्विच जोड़ें:

YourActivity Class में (उदा। MainActivity.java के लिए)

    Switch toggle; // outside oncreate
    toggle =(Switch) findViewById(R.id.switch1);  // inside oncreate


    toggle.setOnClickListener(new View.OnClickListener() {   // inside oncreate
        @Override
        public void onClick(View view) {

            if( toggle.isChecked() ){
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    start.setBackgroundColor(getColor(R.color.gold));
                }
            }
            else
            {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    stop.setBackgroundColor(getColor(R.color.gold));
                }
            }

        }

    });

0

एक SwitchCompatऔर Kotlin का उपयोग करके मेरा समाधान । मेरी स्थिति में, मुझे केवल तभी परिवर्तन पर प्रतिक्रिया करने की आवश्यकता है जब उपयोगकर्ता ने UI के माध्यम से इसे ट्रिगर किया। वास्तव में, एक करने के लिए अपने स्विच प्रतिक्रिया LiveDataहै, और इस दोनों बनाया setOnClickListenerऔर setOnCheckedChangeListenerव्यर्थ। setOnClickListenerवास्तव में उपयोगकर्ता इंटरैक्शन के लिए सही ढंग से प्रतिक्रिया करता है, लेकिन अगर उपयोगकर्ता स्विच में अंगूठे को दबाता है तो यह ट्रिगर नहीं होता है।setOnCheckedChangeListenerदूसरे छोर पर भी ट्रिगर होता है, अगर स्विच को प्रोग्रामेटिक रूप से टॉगल किया जाता है (उदाहरण के लिए एक पर्यवेक्षक द्वारा)। अब मेरे मामले में स्विच दो अंशों पर मौजूद था, और इसलिए onRestoreInstanceState कुछ मामलों में सही मूल्य को अधिलेखित करने वाले पुराने मान के साथ स्विच को ट्रिगर करेगा।

इसलिए, मैंने स्विचकॉमैट के कोड को देखा, और क्लिक और ड्रैग को भेद करने में सफलतापूर्वक इसका व्यवहार करने में सक्षम था और कस्टम टचलिस्टर बनाने के लिए इसका उपयोग किया जो कि इसे करना चाहिए। ये रहा:

/**
 * This function calls the lambda function passed with the right value of isChecked
 * when the switch is tapped with single click isChecked is relative to the current position so we pass !isChecked
 * when the switch is dragged instead, the position of the thumb centre where the user leaves the
 * thumb is compared to the middle of the switch, and we assume that left means false, right means true
 * (there is no rtl or vertical switch management)
 * The behaviour is extrapolated from the SwitchCompat source code
 */
class SwitchCompatTouchListener(private val v: SwitchCompat, private val lambda: (Boolean)->Unit) :  View.OnTouchListener {
    companion object {
        private const val TOUCH_MODE_IDLE = 0
        private const val TOUCH_MODE_DOWN = 1
        private const val TOUCH_MODE_DRAGGING = 2
    }

    private val vc = ViewConfiguration.get(v.context)
    private val mScaledTouchSlop = vc.scaledTouchSlop
    private var mTouchMode = 0
    private var mTouchX = 0f
    private var mTouchY = 0f

    /**
     * @return true if (x, y) is within the target area of the switch thumb
     * x,y and rect are in view coordinates, 0,0 is top left of the view
     */
    private fun hitThumb(x: Float, y: Float): Boolean {
        val rect = v.thumbDrawable.bounds
        return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
    }

    override fun onTouch(view: View, event: MotionEvent): Boolean {
        if (view == v) {
            when (MotionEventCompat.getActionMasked(event)) {
                MotionEvent.ACTION_DOWN -> {
                    val x = event.x
                    val y = event.y
                    if (v.isEnabled && hitThumb(x, y)) {
                        mTouchMode = TOUCH_MODE_DOWN;
                        mTouchX = x;
                        mTouchY = y;
                    }
                }
                MotionEvent.ACTION_MOVE -> {
                    val x = event.x
                    val y = event.y
                    if (mTouchMode == TOUCH_MODE_DOWN &&
                        (abs(x - mTouchX) > mScaledTouchSlop || abs(y - mTouchY) > mScaledTouchSlop)
                    )
                        mTouchMode = TOUCH_MODE_DRAGGING;
                }
                MotionEvent.ACTION_UP,
                MotionEvent.ACTION_CANCEL -> {
                    if (mTouchMode == TOUCH_MODE_DRAGGING) {
                        val r = v.thumbDrawable.bounds
                        if (r.left + r.right < v.width) lambda(false)
                        else lambda(true)
                    } else lambda(!v.isChecked)
                    mTouchMode = TOUCH_MODE_IDLE;
                }
            }
        }
        return v.onTouchEvent(event)
    }
}

इसे कैसे उपयोग करे:

वास्तविक स्पर्श श्रोता जो निष्पादित करने के लिए कोड के साथ एक लैम्ब्डा स्वीकार करता है:

myswitch.setOnTouchListener(
    SwitchCompatTouchListener(myswitch) {
        // here goes all the code for your callback, in my case
        // i called a service which, when successful, in turn would 
        // update my liveData 
        viewModel.sendCommandToMyService(it) 
    }
)

पूर्णता के लिए, यह है कि राज्य के लिए पर्यवेक्षक switchstate(यदि आपके पास है) ऐसा दिखता है:

switchstate.observe(this, Observer {
    myswitch.isChecked = it
})

एंड्रॉइड टीम को वास्तव में इसे ठीक करना चाहिए ... मैंने जो भी किया था वह मेरे लाइवडेटा पर्यवेक्षक में है, मैं ऑनचेक की अपंजीकृत करता हूं, मेरी कार्रवाई करता हूं, फिर इसे वापस सेट करता हूं। यह केवल इसलिए काम करता है क्योंकि UI परिवर्तन 1 थ्रेड (मुख्य थ्रेड) पर होता है।
जेरेमी जौ

0

कोटलिन में:

        switch_button.setOnCheckedChangeListener { buttonView, isChecked ->
        if (isChecked) {
            // The switch enabled
            text_view.text = "Switch on"

        } else {
            // The switch disabled
            text_view.text = "Switch off"

        }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.