2011-07-13 16 views
27

मेरे पास कुछ विचार हैं जो मैं एक बटन प्रेस पर दिखाई देता हूं। अगर मैं उन विचारों के बाहर क्लिक करता हूं तो मैं उन्हें गायब करना चाहता हूं।एंड्रॉइड दृश्य इसके बाहर क्लिक करके गायब हो जाता है

एंड्रॉइड पर यह कैसे किया जाएगा?

इसके अलावा, मुझे एहसास है कि "बैक बटन" इसके साथ एंड्रॉइड उपयोगकर्ताओं की सहायता भी कर सकता है - मैं इसे दृश्यों को बंद करने के लिए द्वितीयक तरीके के रूप में उपयोग कर सकता हूं - लेकिन कुछ टैबलेट भी 'भौतिक' का उपयोग नहीं कर रहे हैं बटन अब, यह बहुत ही जोर दिया गया है।

उत्तर

29

एक आसान/बेवकूफ तरीका:

  • एक डमी खाली दृश्य बनाएं (के कोई स्रोत के साथ imageView मान लीजिए), यह माता पिता को भरने

  • यदि यह क्लिक किया जाता है, तो आप क्या चाहते हैं करते हैं करने के लिए।

आपको अपनी एक्सएमएल फ़ाइल में रूट टैग को रिलेटिव लयआउट होने की आवश्यकता है। इसमें दो तत्व होंगे: आपका डमी व्यू (इसकी स्थिति align the Parent Top पर सेट करें)। दूसरा आपका विचार है जिसमें दृश्य और बटन शामिल है (यह दृश्य एक लाइनरलाइट या जो भी आप इसे बनाते हैं। align the Parent Top पर अपनी स्थिति सेट करना न भूलें)

आशा है कि यह आपकी मदद करेगा, शुभकामनाएँ!

+0

एक चार्म की तरह काम किया! धन्यवाद :) मुझे संदेह था कि रिक्त छविदृश्यों को पहचाना जाएगा – CQM

+11

आप आसानी से डमी दृश्य के रूप में उपयोग कर सकते हैं। वे थोड़ा हल्का हैं और इसे एक्सएमएल में देखकर एक अच्छा अनुस्मारक है कि इसे विज़ुअल तत्व – zienkikk

+0

@RD के रूप में उपयोग नहीं किया जाता है। जानकर ख़ुशी हुई की :) । मैंने रिलेवेटिवआउट के साथ इस तरह की चालें कीं। यह एक लचीला लेआउट से अधिक है। – iTurki

0

लागू onTouchListener()। जांचें कि स्पर्श के निर्देशांक आपके दृश्य के निर्देशांक के बाहर हैं।

शायद onFocus(), आदि के साथ ऐसा करने का कोई तरीका है - लेकिन मुझे यह नहीं पता।

+0

कैसे मैं करता हूँ निर्धारित करें कि एक्स, वाई मेरे दृश्य गतिशील रूप से क्या निर्देशित करता है? क्या मैं पिक्सल या डुबकी मानों का उपयोग कर रहा हूं जिसे मैंने – CQM

+0

के साथ अपना आकार बनाया है http://stackoverflow.com/questions/2224844/how-to-get-the-absolute-coordinates-of-a-view – RedLeader

20

यह एक पुराना सवाल है, लेकिन मैंने सोचा कि मैं एक उत्तर दूंगा जो onTouch घटनाओं पर आधारित नहीं है। रेडलेडर द्वारा सुझाए गए अनुसार फोकस कार्यक्रमों का उपयोग करके इसे हासिल करना भी संभव है। मेरे पास एक ऐसा मामला था जहां मुझे कस्टम पॉपअप में व्यवस्थित बटनों का एक गुच्छा दिखाने और छिपाने की ज़रूरत थी, यानी बटन सभी को ViewGroup में रखा गया था।

  1. दृश्य समूह है कि आप View.setFocusableInTouchMode(true) सेट करने के लिए की जरूरत को छिपाने के लिए चाहते हैं: कुछ बातें आपको बस इतना करना इस काम करने के लिए। इसे android:focusableintouchmode का उपयोग करके एक्सएमएल में भी सेट किया जा सकता है।

  2. आपके व्यू जड़, अपने पूरे लेआउट की जड़, शायद रैखिक या रिश्तेदार लेआउट किसी तरह का यानी, यह भी जब दृश्य समूह दिखाया गया है

  3. ऊपर प्रति # 1 के रूप फ़ोकस करने योग्य होने के लिए सक्षम होने की जरूरत आप इसे ध्यान देने के लिए View.requestFocus() पर कॉल करें।

  4. आपके व्यू समूह या तो View.onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) ओवरराइड या अपने खुद के OnFocusChangeListener को लागू करने और उपयोगकर्ता आपके विचार के बाहर टैप करता जब फोकस दोनों ही दृश्यों जड़ को स्थानांतरित कर रहा है (क्योंकि आप इसे के रूप में # में फ़ोकस करने योग्य सेट View.setOnFocusChangeListener()

  5. उपयोग करने की आवश्यकता 2) या किसी अन्य का मानना ​​है कि स्वाभाविक फ़ोकस करने योग्य है (EditText या समान) को

  6. जब आप # 4 में तरीकों आप जानते हैं कि ध्यान देने के आपके विचार समूह के बाहर कुछ के लिए स्थानांतरित किया गया है में से एक का उपयोग कर फोकस हानि का पता लगाने और आप छिपा कर सकते हैं यह।

मुझे लगता है कि यह समाधान सभी परिदृश्यों में काम नहीं करता है, लेकिन यह मेरे विशिष्ट मामले में काम करता है और ऐसा लगता है जैसे यह ओपी के लिए भी काम कर सकता है।

+1

छोटे सुझाव: setFocusableInTouchMode सेट सुनिश्चित करने योग्य भी सेट है। – Edison

+0

आप सही हैं, मैंने दस्तावेज़ को ठीक से नहीं पढ़ा है। मैं जवाब अपडेट करूंगा। – britzl

8

मैं बाहर स्पर्श करते समय अपना दृश्य बंद करने का एक तरीका ढूंढ रहा हूं और इनमें से कोई भी तरीका मेरी आवश्यकताओं को वास्तव में अच्छी तरह फिट नहीं करता है। मुझे एक समाधान मिला और अगर कोई दिलचस्पी लेता है तो उसे यहां पोस्ट कर देगा।

मेरे पास एक मूल गतिविधि है जो मेरी सभी गतिविधियों का विस्तार करती है। इसमें मेरे पास है:

@Override 
public boolean dispatchTouchEvent(MotionEvent ev) { 
    if (myViewIsVisible()){ 
      closeMyView(); 
     return true; 
    } 
    return super.dispatchTouchEvent(ev); 
} 

तो अगर मेरे विचार से दिखाई देता है यह सिर्फ बंद हो जाएगा, और यदि नहीं यह एक सामान्य स्पर्श घटना की तरह व्यवहार करेगा। सुनिश्चित नहीं है कि यह करने का सबसे अच्छा तरीका है, लेकिन ऐसा लगता है कि यह मेरे लिए काम करता है।

+5

आपका दृश्य दिखाई देने पर क्या होता है और आप उस पर क्लिक करते हैं? ऐसा लगता है कि यह वैसे भी बंद हो जाएगा – Guillaume

+0

बहुत उपयोगी। यह निर्धारित करने में सक्षम होने के लिए निम्न देखें कि स्पर्श दृश्य के अंदर है या नहीं, जब क्लिक इसके बाहर होता है: http://stackoverflow.com/questions/20700286/how-to-detect-a-motionevent-inside- dispatchtouchevent [link] – dazed

+0

मैं @ गुइलाउम के साथ हूं, क्या यह अनिवार्य रूप से बेकार नहीं है क्योंकि आप कभी भी अपने विचार पर क्लिक नहीं कर सकते? – behelit

2

मुझे इसके बाहर क्लिक करते समय केवल एक दृश्य को हटाने की विशिष्ट क्षमता की आवश्यकता नहीं है, बल्कि क्लिक को सामान्य रूप से गतिविधि से गुज़रने की अनुमति भी देता है। उदाहरण के लिए, मेरे पास एक अलग लेआउट है, अधिसूचना_बार.एक्सएमएल, कि मुझे गतिशील रूप से फुलाया जाना चाहिए और जब आवश्यक हो तो वर्तमान गतिविधि को जोड़ना चाहिए।

यदि मैं अधिसूचना_बार दृश्य के बाहर किसी भी क्लिक प्राप्त करने के लिए स्क्रीन के आकार को ओवरले बना देता हूं और इन दोनों दृश्यों को एक क्लिक पर हटा देता हूं, तो मूल दृश्य (गतिविधि का मुख्य दृश्य) अभी भी कोई क्लिक प्राप्त नहीं हुआ है , जिसका अर्थ है, जब अधिसूचना_बार दिखाई दे रहा है, तो बटन पर क्लिक करने के लिए दो क्लिक लगते हैं (अधिसूचना_बार दृश्य को खारिज करने के लिए एक और बटन को क्लिक करने के लिए एक)।

इस का समाधान करने के लिए, तुम सिर्फ अपने खुद के DismissViewGroup कि ViewGroup प्रदान करता है और निम्न विधि को ओवरराइड करता है बना सकते हैं:

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    ViewParent parent = getParent(); 
    if(parent != null && parent instanceof ViewGroup) { 
     ((ViewGroup) parent).removeView(this); 
    } 
    return super.onInterceptTouchEvent(ev); 
} 

और फिर अपने गतिशील रूप से जोड़ा दृश्य एक छोटे तरह दिखेगा:

<com.example.DismissViewGroup android:id="@+id/touch_interceptor_view" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@android:color/transparent" ... 
    <LinearLayout android:id="@+id/notification_bar_view" ... 

यह आपको दृश्य के साथ बातचीत करने की अनुमति देगा, और जिस क्षण आप दृश्य के बाहर क्लिक करेंगे, आप दोनों दृश्य को खारिज कर देंगे और सामान्य रूप से गतिविधि के साथ बातचीत करेंगे।

16

दृश्य आयत खोजें, और फिर पता लगाएं कि क्लिक ईवेंट दृश्य के बाहर है या नहीं।

@Override 
public boolean dispatchTouchEvent(MotionEvent ev) { 
    Rect viewRect = new Rect(); 
    mTooltip.getGlobalVisibleRect(viewRect); 
    if (!viewRect.contains((int) ev.getRawX(), (int) ev.getRawY())) { 
     setVisibility(View.GONE); 
    } 
    return true; 
} 

आप संपर्क घटना अन्य जगह का उपयोग करना चाहते हैं, तो कोशिश

return super.dispatchTouchEvent(ev); 
+2

बस ध्यान दें, 'प्रेषण टचवेन्ट()' को बुलियन लौटाया जाना चाहिए, लेकिन आप अपने उदाहरण में कुछ भी वापस नहीं करते हैं। इसके अतिरिक्त, आप परिभाषित नहीं करते हैं और न ही समझाते हैं कि 'viewRect' क्या है। – CaptJak

+0

धन्यवाद, कैप्टनक। –

+0

यह वास्तव में अच्छी तरह से काम करता है और इसे लागू करने के लिए आसान है। – behelit

0

मैं कस्टम ViewGroup बना लिया है जानकारी बॉक्स अन्य दृश्य (पॉपअप गुब्बारा) के लिए लंगर डाले प्रदर्शित करने के लिए। चाइल्ड व्यू वास्तविक जानकारी बॉक्स है, बुलून व्यू बच्चे की पूर्ण स्थिति के लिए पूर्णस्क्रीन है, और स्पर्श को अवरुद्ध करता है।

public BalloonView(View anchor, View child) { 
    super(anchor.getContext()); 
    //calculate popup position relative to anchor and do stuff 
    init(...); 
    //receive child via constructor, or inflate/create default one 
    this.child = child; 
    //this.child = inflate(...); 
    //this.child = new SomeView(anchor.getContext()); 
    addView(child); 
    //this way I don't need to create intermediate ViewGroup to hold my View 
    //but it is fullscreen (good for dialogs and absolute positioning) 
    //if you need relative positioning, see @iturki answer above 
    ((ViewGroup) anchor.getRootView()).addView(this); 
} 

private void dismiss() { 
    ((ViewGroup) getParent()).removeView(this); 
} 

बच्चे के अंदर हैंडल क्लिक:

child.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     //write your code here to handle clicks inside 
    } 
}); 

अंतर्निहित देखने के लिए स्पर्श सौंपने के बिना बाहर क्लिक करके मेरी देखें खारिज करने के लिए:

BalloonView.this.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     dismiss(); 
    } 
}); 

स्पर्श सौंपने के साथ बाहर क्लिक करके मेरी देखें खारिज करने के लिए अंतर्निहित देखें:

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    dismiss(); 
    return false; //allows underlying View to handle touch 
} 

वापस बटन दबाया पर खारिज करने के लिए:

//do this in constructor to be able to intercept key 
setFocusableInTouchMode(true); 
requestFocus(); 

@Override 
public boolean onKeyPreIme(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     dismiss(); 
     return true; 
    } 
    return super.onKeyPreIme(keyCode, event); 
} 
-1

विचार

FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/search_container" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="#80000000" 
android:clickable="true"> 

<LinearLayout 
    android:clickable="true" // not trigger 
    android:layout_width="match_parent" 
    android:layout_height="300dp" 
    android:background="#FFF" 
    android:orientation="vertical" 
    android:padding="20dp"> 

    ............... 

</LinearLayout> 
</FrameLayout> 

और जावा कोड के लिए @ituki धन्यवाद

mContainer = (View) view.findViewById(R.id.search_container); 
    mContainer.setOnTouchListener(new View.OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      if(event.getAction() == MotionEvent.ACTION_DOWN){ 
       Log.d("aaaaa", "outsite"); 
       return true; 
      } 
      return false; 
     } 
    }); 

यह काम है जब LinearLayout बाहर स्पर्श

संबंधित मुद्दे