जब स्नैकबार ने खुद को खारिज कर दिया है तो मुझे कैसे सूचित किया जा सकता है?


82

मैं com.android.support:design:22.2.0लाइब्रेरी से स्नैकबार का उपयोग कर रहा हूं । मैं इसे हटाने के लिए पूर्ववत कर रहा हूँ। अपने जीवन को आसान बनाने के लिए, मैं यूआई बनाने जा रहा हूं जैसे कि चीजें वास्तव में डेटा स्रोत से हटा दी जाती हैं, और अगर स्नैक बार में पूर्ववत बटन दबाया नहीं जाता है, तो वास्तव में डेटा स्रोत से डिलीट करें। इसलिए, मैं जानना चाहता हूं कि स्नैकबार अब दिखाई नहीं देता है, इसलिए आइटम को हटाना सुरक्षित है।

मैं स्नैकबार पर getView () कॉल कर सकता हूं, लेकिन मुझे यकीन नहीं है कि मुझे किस श्रोता का उपयोग करना चाहिए। मैंने कोशिश की, setOnSystemUiVisibilityChangeListener()लेकिन यह काम नहीं किया, मेरा मानना ​​है कि यह केवल सिस्टम स्टेटस बार के लिए है।

इसके अतिरिक्त, स्नैकबार को बढ़ाया नहीं जा सकता, क्योंकि इसमें एक निजी कंस्ट्रक्टर है।


1
यह फीचर सपोर्ट डिज़ाइन लाइब्रेरी
टायलर Pfaff

जवाबों:


179

Google डिज़ाइन लाइब्रेरी 23 संस्करण में स्नैकबार कॉलबैक का समर्थन करती है। स्नैकबार डॉक्स और कॉलबैक डॉक्स देखें । जब स्नैकबार खारिज हो जाता है (तब और जब दिखाया जाता है) तब भी आपको सूचित किया जाएगा और अगर यह इस प्रकार है:

snackbar.addCallback(new Snackbar.Callback() {

    @Override
    public void onDismissed(Snackbar snackbar, int event) {
      //see Snackbar.Callback docs for event details
      ...  
    }

    @Override
    public void onShown(Snackbar snackbar) {
       ...
    }
  });

13
setCallback () अब हटा दिया गया है। AddCallback () का उपयोग करें
jds17

41
snackbar.addCallback(new Snackbar.Callback() {

    @Override
    public void onDismissed(Snackbar snackbar, int event) {
        if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) {
            // Snackbar closed on its own
        }
    }

    @Override
    public void onShown(Snackbar snackbar) {
        ...
    }
});

4
इस घटना का उल्लेख करते हुए अच्छा लगा, क्योंकि एक्शनटेड को क्लिक करने पर ऑनडिज्मेड भी कहा जाता है
अमरो इलास्वर

2
अधिकांश मामलों के लिए संभवतः if (event != Snackbar.Callback.DISMISS_EVENT_ACTION)इसके बजाय जांच करना सबसे अच्छा है अन्यथा आपका बर्खास्त तर्क तर्क नहीं चलेगा यदि उपयोगकर्ता मैन्युअल रूप से खारिज करता है या स्नैकबार को लगातार दूसरे स्नैकबार द्वारा खारिज कर दिया जाता है।
श्यामल

इस पंक्ति के लिए धन्यवादevent == Snackbar.Callback.DISMISS_EVENT_TIMEOUT
प्रतीक बुटानी

18

कोटलिन में Snackbar.addCallback

val snackBar = Snackbar
                .make(view, "Text Snackbar", Snackbar.LENGTH_LONG)
                .addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
                    override fun onShown(transientBottomBar: Snackbar?) {
                        super.onShown(transientBottomBar)
                    }

                    override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                        super.onDismissed(transientBottomBar, event)
                    }
                })

        val snackBarView = snackBar.view
        snackBarView.setBackgroundColor(Color.RED)
        snackBar.show()

16

हाल ही में मैं इस मामले पर खुद लड़खड़ा गया जब स्क्रॉल करने और स्नैकबैक दिखाने के लिए, बहुत से पहले गायब होने से पहले भी दिखाए गए थे। मुझे यह जानने का एक तरीका खोजना था कि क्या ऐप को स्नैकबार को रखा जाना चाहिए था।

मुझे व्यक्तिगत रूप से यह समाधान मिला।

यह सच है कि स्नैकबार अपने आप में राज्य / दृश्यता के लिए किसी भी प्रकार के श्रोता की पेशकश नहीं करता है, लेकिन आप अभी भी स्नैकबार से व्यू ऑब्जेक्ट प्राप्त कर सकते हैं (getView ();)। व्यू ऑब्जेक्ट से आपको श्रोताओं को जोड़ने के लिए कई तरह के तरीकों का उपयोग करने का मौका मिलता है।

इसे लागू करने के लिए आपको आम "ऑल-इन-वन-लाइन" टोस्ट / स्नैकबार उपयोग से बाहर जाना होगा, क्योंकि श्रोताओं को जोड़ने से शून्य वापस आ जाता है

मैंने अपनी आवश्यकताओं को पूरा करने के लिए व्यक्तिगत रूप से OnAttachStateChangeListener पाया।

यदि यह आपके लिए उपयोगी हो सकता है तो मेरे कोड के साथ एक स्निपर को छोड़ना।

Snackbar snack = Snackbar.make(getView(), "My Placeholder Text", Snackbar.LENGTH_LONG);

snack.getView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
    @Override
        public void onViewAttachedToWindow(View v) {
            canDisplaySnackbar = false;
        }

    @Override
    public void onViewDetachedFromWindow(View v) {

        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
                canDisplaySnackbar = true;

                }
        }, 1000);
    }
});
snack.show();

कृपया ध्यान दें कि यह केवल मेरी ही समस्या के लिए मेरा कार्यान्वयन है, पोस्टडेलिड रननेबल के साथ हैंडलर भी आपके मामले में फिट नहीं हो सकता है। यह सिर्फ उस कार्यान्वयन का एक सामान्य विचार देना था जिसे मैंने एक स्निपेट का उपयोग करने का सुझाव दिया था जो पहले से ही मेरे पास है।


4
and_dev's andswer अब बेहतर उत्तर है।
इस्लाम ए। हसन

12

एक स्नैकबार दिखाए जाने या खारिज किए जाने पर अधिसूचित होने के लिए, आप सेटकैल्बैक (कॉलबैक) के माध्यम से स्नैकबार.कॉलबैक प्रदान कर सकते हैं।


setCallBack अब हटा दिया गया है, इसके बजाय addCallBack का उपयोग करें
mjn42

5

onDismissed को तब भी कहा जाता है जब क्रिया पाठ को उस कारण के लिए क्लिक किया जाता है, जैसे एक शर्त रखने की आवश्यकता होती है

event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT

और अब नया कोड नीचे जैसा दिख रहा है।

final Snackbar snackBar = Snackbar.make(findViewById(R.id.root_layout), result, Snackbar.LENGTH_LONG);

snackbar.addCallback(new Snackbar.Callback() {

@Override
public void onDismissed(Snackbar snackbar, int event) {
 if (event == Snackbar.Callback.DISMISS_EVENT_TIMEOUT) {
        // Snackbar closed on its own
    }  
}

@Override
public void onShown(Snackbar snackbar) {
...
}
});
snackBar.show();

कोड केवल उत्तर को प्रोत्साहित करते हैं क्योंकि वे भविष्य के पाठकों के लिए अधिक जानकारी प्रदान नहीं करते हैं जो आपने लिखा है, कृपया कुछ स्पष्टीकरण प्रदान करें
WhatsThePoint

अधिकांश मामलों के लिए संभवतः if (event != Snackbar.Callback.DISMISS_EVENT_ACTION)इसके बजाय जांच करना सबसे अच्छा है अन्यथा आपका बर्खास्त तर्क तर्क नहीं चलेगा यदि उपयोगकर्ता मैन्युअल रूप से खारिज करता है या स्नैकबार को लगातार दूसरे स्नैकबार द्वारा खारिज कर दिया जाता है।
श्यामल


3

स्नैकबार प्रदर्शित होने के बाद, अधिसूचना प्राप्त करने का कोई तरीका नहीं है।

इस धागे में स्नैकबार डिस्प्ले की अवधि के लिए टाइमर के आधार पर वर्कअराउंड पर चर्चा की गई है। समर्थन लाइब्रेरी में स्नैकबार में OnDismissListener () शामिल नहीं है?

इस वर्कअराउंड के साथ विचार करने के लिए एक मुद्दा यह संभव है कि स्नैकबार की अवधि फिर से शुरू हो जाए। Snackbar के लिए सामग्री डिजाइन विनिर्देशन का कहना है कि अगर एक असंबंधित संवाद या पॉपअप प्रदर्शित किया जाता है यह नहीं होगा।


1

वर्तमान में आप इसे प्राप्त नहीं कर सकते।

स्नैकबार मंद होने पर कोई श्रोता नहीं होता है।

ऐसा करने का सबसे आसान तरीका अस्थायी रूप से रिकॉर्ड को कहीं और (यहां तक ​​कि एक स्थानीय चर) को सहेजना है, फिर इसे फिर से डालें अगर वे पूर्ववत करें बटन को हिट करने के लिए।


1
    snackbar.addCallback(new Snackbar.Callback() {
        public void onShown(Snackbar snackbar) {
           //  on show  
        }
 public void onDismissed(Snackbar snackbar, int event) {
          //  on dismiss  
        }
      });

कृपया अपने कोड स्निपेट के साथ विवरण / विवरण प्रदान करें।
Janis F

1

मुझे तुम्हारी जैसी ही समस्या है। मेरा समाधान है ...

              final Snackbar povrati_obrisani_unos = Snackbar.make (coordinatorLayout, "Ponisti brisanje", Snackbar.LENGTH_INDEFINITE)
                    .addCallback (new Snackbar.Callback (){
                        @Override
                        public void onDismissed(Snackbar transientBottomBar, int event) {
                            super.onDismissed (transientBottomBar, event);
                            if(event==DISMISS_EVENT_SWIPE){//here we detect if snackbar is swipped away and not cliked (which is undo in my case)
                                Uri uriDelete = Uri.parse (obrisano.getImageuri ());
                                ContentResolver contentResolver = getContentResolver();
                                contentResolver.delete (uriDelete, null, null);
                                Toast.makeText (MainActivity.this,
                                        "Ocitavanje i slika su trajno obrisani", Toast.LENGTH_SHORT).show ();
                            }

यह सब है, स्नैकबार को कॉपी-पेस्ट नहीं करना चाहते हैं जो पूर्ववत है। स्पष्ट होना चाहते हैं क्योंकि मैं संभवतः यहाँ हो सकता है।

सादर नेनाद


0

के लिए धन्यवाद @SergeyMilakov में Kotlin है:

@SuppressLint("WrongConstant") // Suppress an error when set duration.
private fun showSnackbar() {
    val DURATION = 5000

    Snackbar.make(view!!, "Remove item?"), DURATION).apply {
        setAction("Undo") {
            // Your action when a button is clicked.
        }
        addCallback(object : BaseTransientBottomBar.BaseCallback<Snackbar>() {
            /* override fun onShown(transientBottomBar: Snackbar?) {
                super.onShown(transientBottomBar)
                Timber.d("*** onShown")
            }*/

            override fun onDismissed(transientBottomBar: Snackbar?, event: Int) {
                super.onDismissed(transientBottomBar, event)
                if (event != Snackbar.Callback.DISMISS_EVENT_ACTION) {
                    // Your action when the Snackbar is closed and the button was not clicked.
                }

            }
        })
        view.setBackgroundColor(ContextCompat.getColor(context, R.color.black))
        setActionTextColor(ContextCompat.getColor(context, R.color.yellow))
        show()
    }
}

ध्यान दें कि Snackbarदिखाता है, भले ही आप अन्य स्क्रीन पर जाएं (उदाहरण के लिए, पीछे)। इसलिए, यह जांचना न भूलें कि आप सही स्क्रीन पर एक्शन करते हैं या नहीं।

इसके अलावा Snackbarस्क्रीन रोटेशन के बाद पुनर्स्थापित नहीं करता है।

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