2010-06-25 8 views
59

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

pop.setOnKeyListener(new View.OnKeyListener() { 

     @Override 
     public boolean onKey(View v, int keyCode, KeyEvent event) { 
      // TODO Auto-generated method stub 
      boolean res=false; 
      if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) { 
       // do something on back. 
       Log.e("keydown","back"); 
       if (pw.isShowing()) { 
        Log.e("keydown","pw showing"); 
        pw.dismiss(); 
        res = true; 
       } 
      } else { 
       res = false; 
      } 
      return res; 
     } 
    }); 

जो इस तरह एक पॉपअप में भेजा जाता है:

pw = new PopupWindow(
     pop, 
     240, 
     70, 
     true); 

लेकिन उस श्रोता न आग नहीं करता है। क्या आप मेरी मदद कर सकते हैं? मैं विचारों से बाहर हूं :)

+0

हाँ, पर पॉप अप विंडो क्लिक करने योग्य चित्र शामिल हैं ... – Bostjan

उत्तर

144

ऐसा इसलिए है क्योंकि पॉपअप विंडो टच या ऑन घटनाओं का जवाब नहीं देती है जब तक कि इसकी पृष्ठभूमि न हो! = Null। Check out some code I wrote इस के साथ मदद करने के लिए। मूल मामले में आप PopupWindow#setBackgroundDrawable(new BitmapDrawable()) पर कॉल करने के लिए इसे जिस तरह से उम्मीद कर सकते हैं उसे कार्य करने के लिए मजबूर कर सकते हैं। आपको अपने श्रोता श्रोताओं की आवश्यकता नहीं होगी। यदि आप खिड़की की सीमाओं के बाहर क्लिक करते हैं तो आपको PopupWindow#setOutsideTouchable(true) पर कॉल करने की आवश्यकता हो सकती है।

विस्तारित गूढ़ जवाब:

कारण पृष्ठभूमि नल नहीं हो सकता, क्योंकि जो PopupWindow#preparePopup में क्या होता है की है। यदि यह background != null का पता लगाता है तो यह PopupViewContainer का उदाहरण बनाता है और उस पर setBackgroundDrawable पर कॉल करता है और इसमें आपकी सामग्री दृश्य डालता है। PopupViewContainer मूल रूप से FrameLayout है जो विंडो को खारिज करने के लिए स्पर्श ईवेंट और KeyEvent.KEYCODE_BACK ईवेंट सुनता है। अगर पृष्ठभूमि == शून्य है, तो वह ऐसा नहीं करता है और केवल आपके सामग्री दृश्य का उपयोग करता है। आप इसे संभालने के लिए PopupWindow पर निर्भर करने के विकल्प के रूप में, अपनी इच्छित विधि का व्यवहार करने के लिए अपनी रूट ViewGroup का विस्तार कर सकते हैं।

+0

मैं एक बहुत ही इसी तरह की समस्या है। मेरे CustomView, जो PopupWindow को पारित कर दिया है OnKeyDown पंजीकृत नहीं करता() की घटनाओं, लेकिन यह रजिस्टर onTouchEvent करता है() । – znq

+10

सुनिश्चित करें कि आप टी दिखाने से पहले setBackgroundDrawable फोन कर वह संवाद ... मेरे थोड़ी देर ले लिया लगाने की है कि एक बाहर। – DallinDyer

+2

मैं पूछ सकता है ** कैसे ** आप इस? मेरे लिए, यह सिर्फ अनुमान लगाना असंभव है, इसलिए या तो आप कुछ * छिपा प्रलेखन के लिए उपयोग किया खोजा था * या आप कर रहे हैं एक जादूगर :) – Raffaele

5

एक सचमुच सरल समाधान pw.setFocusable (सत्य) लिखना है, लेकिन शायद आप ऐसा नहीं करना चाहते हैं क्योंकि तब MapActivity स्पर्श ईवेंट को संभाल नहीं पाएगा।

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 

    // Override back button 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     if (pw.isShowing()) { 
      pw.dismiss(); 
      return false; 
     } 
    } 
    return super.onKeyDown(keyCode, event); 
} 

गुड लक:

एक बेहतर समाधान वापस कुंजी, उदा इस तरह ओवरराइड करने के लिए है!

35

के रूप में निम्नलिखित प्रति यह ठीक काम करता है कार्य करें:

PopupWindow pw; 
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup)); 
pw = new PopupWindow(layout,LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT, true); 
pw.setBackgroundDrawable(new BitmapDrawable()); 
pw.setOutsideTouchable(true); 
pw.showAsDropDown(btnSelectWeight); 
3

मैं इस मदद हो जाएगा आशा के लिए आप

pw.setTouchInterceptor(new View.OnTouchListener() { 

     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      // TODO Auto-generated method stub 
      if (event.getAction() == MotionEvent.ACTION_DOWN) { 
       pw.dismiss(); 
      } 
      return true; 
     } 
    }); 
+0

हाय, क्या यह एक जरूरी है जब हम पॉपअप विंडो से निपट रहे हों? या pw.setOutside टच करने योग्य (सत्य); जब हम पॉपअप विंडो के बाहर क्लिक करते हैं तो पॉपअप विंडो को खारिज करने के लिए पर्याप्त है? – GMsoF

+0

@GMsoF दोनों को जरूरी है, मेरा जवाब देखें –

0
private void initPopupWindow() { 
    // TODO Auto-generated method stub 

    View view = getLayoutInflater().inflate(R.layout.main_choice, null); 

    ListView main_menu_listview = (ListView) view.findViewById(R.id.main_menu_listview); 

    ShowMainChoice madapter = new ShowMainChoice(context); 
    main_menu_listview.setAdapter(madapter); 

    int width = (int)getWindowManager().getDefaultDisplay().getWidth()/2; 
    popupWindow = new PopupWindow(view, width,WindowManager.LayoutParams.WRAP_CONTENT); 
    popupWindow.setBackgroundDrawable(new BitmapDrawable());//this is important,如果缺少这句将导致其他任何控件及监听都得不到响应 
    popupWindow.setOutsideTouchable(true); 
    popupWindow.setFocusable(true); 

    main_menu_listview.setOnItemClickListener(new OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) { 
      // TODO Auto-generated method stub 

      Log.e("++++++>", arg2+""); 

     } 
    }); 
} 

यह समस्या popupwindow है अंतर्निहित संदेश सेवा निर्णय, क्योंकि यह की अवरुद्ध है। गुड लक

4

नई खोजकर्ताओं के लिए, एक new BitmapDrawable बनाने के रूप में अब (The constructor BitmapDrawable() is deprecated) की अनुमति नहीं है, ताकि आप एक new ShapeDrawable() लिए इसे बदलने के लिए है, इसलिए है कि आप बदल जाएगा:

pw.setBackgroundDrawable(new BitmapDrawable()); 

करने के लिए:

pw.setBackgroundDrawable(new ShapeDrawable()); 

और सारी काम तरह होगा:

PopupWindow pw; 
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup)); 
pw = new PopupWindow(layout,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, true); 
pw.setOutsideTouchable(true); 
pw.setBackgroundDrawable(new ShapeDrawable()); 
pw.setTouchInterceptor(new OnTouchListener() { // or whatever you want 
     @Override 
     public boolean onTouch(View v, MotionEvent event) 
     { 
      if(event.getAction() == MotionEvent.ACTION_OUTSIDE) // here I want to close the pw when clicking outside it but at all this is just an example of how it works and you can implement the onTouch() or the onKey() you want 
      { 
       pw.dismiss(); 
       return true; 
      } 
      return false; 
     } 

}); 
pw.showAtLocation(layout, Gravity.CENTER, 0, 0); 
4

बस का उपयोग इस

mPopupWindow.setBackgroundDrawable(new BitmapDrawable(null,"")); 

जिसका बहिष्कार नहीं है। मैं नए ShapeDrawable) से बचने चाहते हैं (अपने धीरे-धीरे प्रस्तुत करने के लिए जा के रूप में के रूप में यह जब स्क्रीन फिर से ताज़ा करने की आवश्यकता है एक आकार आकर्षित करने के लिए कोशिश करता है ।

6

नई परियोजनाओं के लिए यह

popupWindow.setBackgroundDrawable(new ColorDrawable()); 
बजाय

012 उपयोग करने के लिए बेहतर है
popupWindow.setBackgroundDrawable(new BitmapDrawable()); 

रूप BitmapDrawable मान्य नहीं है। इसके अलावा, यह इस मामले में ShapeDrawable की तुलना में बेहतर है। मैंने देखा है कि जब PopupWindow गोलाकार कोनों के साथ एक आयत है, ShapeDrawable ब्लैक के साथ कोनों भरता है।

1

आप अपने PopupWindow के लिए setBackgroundDrawable(new BitmapDrawable()) जोड़ने की जरूरत ।