संवाद के बाहर क्लिक के साथ संवाद को कैसे खारिज करें?


156

मैंने अपने आवेदन के लिए एक कस्टम संवाद लागू किया है। मैं यह लागू करना चाहता हूं कि जब उपयोगकर्ता संवाद के बाहर क्लिक करता है, तो संवाद को खारिज कर दिया जाएगा। इसके लिए मुझे क्या करना होगा?

जवाबों:


356

dialog.setCanceledOnTouchOutside(true);यदि आप संवाद के बाहर स्पर्श करते हैं तो आप संवाद बंद कर सकते हैं ।

कुछ इस तरह,

  Dialog dialog = new Dialog(context)
  dialog.setCanceledOnTouchOutside(true);

या यदि आपका डायलॉग गैर-मॉडल में है,

1 - FLAG_NOT_TOUCH_MODALअपने डायलॉग की विंडो विशेषता के लिए झंडा सेट करें

Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);

2 - विंडो प्रॉपर्टीज में एक और झंडा जोड़ें, FLAG_WATCH_OUTSIDE_TOUCH- यह डायलॉग अपने दृश्य क्षेत्र के बाहर स्पर्श कार्यक्रम प्राप्त करने के लिए है।

3 - onTouchEvent()डायलॉग को ओवरराइड करें और एक्शन टाइप के लिए चेक करें। यदि क्रिया प्रकार ' MotionEvent.ACTION_OUTSIDE' का अर्थ है, तो उपयोगकर्ता संवाद क्षेत्र के बाहर बातचीत कर रहा है। तो इस मामले में, आप अपने संवाद को मंद कर सकते हैं या यह तय कर सकते हैं कि आप क्या प्रदर्शन करना चाहते हैं। सादा दृश्य?

public boolean onTouchEvent(MotionEvent event)  
{  

       if(event.getAction() == MotionEvent.ACTION_OUTSIDE){  
        System.out.println("TOuch outside the dialog ******************** ");  
               this.dismiss();  
       }  
       return false;  
}  

अधिक जानकारी के लिए टच पॉइंट्स के आधार पर कस्टम डायलॉग को कैसे खारिज करें? और अपने गैर-मोडल संवाद को कैसे खारिज करें, जब संवाद क्षेत्र के बाहर छुआ हो


9
यह महान काम करता है सिवाय इसके कि नीचे की गतिविधि स्पर्श घटना पर भी प्रतिक्रिया करती है। क्या इससे बचाव का कोई रास्ता है?
हॉवेटल

हाँ। window.setFlags (WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); इस समस्या का कारण बनता है। मैंने नीचे एक समाधान पोस्ट किया है :)
Unknownweirdo

क्या गैर-कस्टम संवाद का भी उपयोग करते हुए गतिविधि को कम करके 'ऑन-टच-आउट' घटनाओं को फैलाना संभव है?
jc

1
@ कैसे मैंने अपने समाधान में आपकी समस्या को हल किया है जिसे मैंने नीचे पोस्ट किया है जहां मुझे खिड़की पर किसी भी झंडे को स्थापित करने की आवश्यकता नहीं है।
रोमन नाज़रेविच 13

@MuhammedRefaat - कृपया इस थ्रेड समूह को देखें । Googleforum/# ​​.topic/android-developers/VhaiIMl6E_w । उन्होंने अच्छी तरह से इसका वर्णन किया।
user370305


16

आप onTouchEvent के इस कार्यान्वयन का उपयोग कर सकते हैं। यह स्पर्श घटना के तहत गतिविधि के नीचे प्रतिक्रिया करने से रोकता है (जैसा कि उल्लिखित हॉवेल)।

@Override
public boolean onTouchEvent ( MotionEvent event ) {
  // I only care if the event is an UP action
  if ( event.getAction () == MotionEvent.ACTION_UP ) {
    // create a rect for storing the window rect
    Rect r = new Rect ( 0, 0, 0, 0 );
    // retrieve the windows rect
    this.getWindow ().getDecorView ().getHitRect ( r );
    // check if the event position is inside the window rect
    boolean intersects = r.contains ( (int) event.getX (), (int) event.getY () );
    // if the event is not inside then we can close the activity
    if ( !intersects ) {
      // close the activity
      this.finish ();
      // notify that we consumed this event
      return true;
    }
  }
  // let the system handle the event
  return super.onTouchEvent ( event );
}

स्रोत: http://blog.twimager.com/2010/08/closing-activity-by-touching-outside.html


9

या, यदि आप अपनी शैली xml में परिभाषित विषय का उपयोग करके संवाद को अनुकूलित कर रहे हैं, तो इस पंक्ति को अपने विषय में रखें:

<item name="android:windowCloseOnTouchOutside">true</item>

यह सैमसंग गैलेक्सी टैब 2 वाईफाई पर मेरे लिए काम नहीं करता है। dialog.setCanceledOnTouchOutside(true);अद्भुत काम करता है।
doplumi

7
dialog.setCanceledOnTouchOutside(true); 

बाहर स्पर्श पर संवाद बंद करने के लिए।

और यदि आप बाहर के स्पर्श को बंद नहीं करना चाहते हैं, तो नीचे दिए गए कोड का उपयोग करें:

dialog.setCanceledOnTouchOutside(false);

6

इस पद्धति को क्लिक घटनाओं को पुनः प्राप्त करने वाले ग्रे क्षेत्र के नीचे की गतिविधियों से पूरी तरह से बचना चाहिए।

यदि आपके पास यह रेखा निकालें :

window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);

इसे अपनी बनाई गतिविधि पर रखें

getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

इसके बाद टच इवेंट को ओवरराइड करें

@Override
public boolean onTouchEvent(MotionEvent ev)
{
    if(MotionEvent.ACTION_DOWN == ev.getAction())
    {
        Rect dialogBounds = new Rect();
        getWindow().getDecorView().getHitRect(dialogBounds);
        if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
            // You have clicked the grey area
            displayYourDialog();
            return false; // stop activity closing
        }
    }

    // Touch events inside are fine.
    return super.onTouchEvent(ev);
}

4

आप यह कोशिश कर सकते हैं: -

AlterDialog alterdialog;
alertDialog.setCanceledOnTouchOutside(true);

या

alertDialog.setCancelable(true);

और अगर आपके पास एक है AlterDialog.Builderतो आप यह कोशिश कर सकते हैं: -

alertDialogBuilder.setCancelable(true);

4

यह कोड उस समय के लिए उपयोग किया जाता है जब डायलॉगबॉक्स पर क्लिक करने का समय उस समय छुपाता है और जब उपयोगकर्ता डायलॉगबॉक्स के बाहरी तरफ क्लिक करता है तो उस समय सॉफ्टिनप्यूट और डायलॉगबॉक्स दोनों पास होते हैं।

dialog = new Dialog(act) {
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Tap anywhere to close dialog.
        Rect dialogBounds = new Rect();
        getWindow().getDecorView().getHitRect(dialogBounds);
        if (!dialogBounds.contains((int) event.getX(),
                (int) event.getY())) {
            // You have clicked the grey area
            InputMethodManager inputMethodManager = (InputMethodManager) act
                    .getSystemService(act.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(dialog
                    .getCurrentFocus().getWindowToken(), 0);
            dialog.dismiss();
            // stop activity closing
        } else {
            InputMethodManager inputMethodManager = (InputMethodManager) act
                    .getSystemService(act.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(dialog
                    .getCurrentFocus().getWindowToken(), 0);
        }

        return true;
    }
};

2

एक अन्य समाधान, यह कोड Android स्रोत कोड से लिया गया था, Window आपको बस इन दो तरीकों को अपने संवाद स्रोत कोड में जोड़ना चाहिए।

@Override
public boolean onTouchEvent(MotionEvent event) {        
    if (isShowing() && (event.getAction() == MotionEvent.ACTION_DOWN
            && isOutOfBounds(getContext(), event) && getWindow().peekDecorView() != null)) {
        hide();
    }
    return false;
}

private boolean isOutOfBounds(Context context, MotionEvent event) {
    final int x = (int) event.getX();
    final int y = (int) event.getY();
    final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
    final View decorView = getWindow().getDecorView();
    return (x < -slop) || (y < -slop)
            || (x > (decorView.getWidth()+slop))
            || (y > (decorView.getHeight()+slop));
}

इस समाधान में यह समस्या नहीं है:

यह महान काम करता है सिवाय इसके कि नीचे की गतिविधि स्पर्श घटना पर भी प्रतिक्रिया करती है। क्या इससे बचाव का कोई रास्ता है? - हॉवेटल


खिचड़ी भाषा यदि आप अन्य घटनाओं को फिर से समझना चाहते हैं, तो आप सिर्फ अपने संवाद को मोडल बना सकते हैं?

1

dialog.setCancelable(false);अपनी गतिविधि / खंड से कॉल करें।



0

आप backgroundसभी स्क्रीन आकार पर कब्जा कर सकते हैं transparentऔर इसके लिए onClickघटना सुन dismissसकते हैं।


10
बहुत बुरा जवाब! बेशक यह किया जा सकता है, लेकिन कृपया इसे सही तरीके से करें!
jc

-1

यहाँ कोड है

    dialog.getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent ev) {

            if(MotionEvent.ACTION_DOWN == ev.getAction())
            {
                Rect dialogBounds = new Rect();
                dialog. getWindow().getDecorView().getHitRect(dialogBounds);
                if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
                    // You have clicked the grey area
                    UiUtils.hideKeyboard2(getActivity());
                    return false; // stop activity closing
                }
            }
            getActivity().dispatchTouchEvent(ev);
            return false;
        }
    });

इसको आजमाओ । जब आप बाहर स्पर्श करते हैं तो आप कीबोर्ड को छिपा सकते हैं

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