سؤال

لدي نافذة منبثقة تعرض عند النقر فوق عنصر في نشاط القائمة. المشكلة هي أن المفتاح الخلفي لا يغلقه. حاولت اللحاق بالمفتاح الخلفي في نشاط القائمة الخاص بي ، لكنه لا يسجله ... ثم حاولت تسجيل onKeyListener إلى العرض الذي أمرره إلى نافذتي المنبثقة. مثله:

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);

لكن هذا المستمع لا يطلق النار. هل بإمكانك مساعدتي؟ أنا خارج الأفكار :)

هل كانت مفيدة؟

المحلول

وذلك لأن نافذة المنبثقة لا تستجيب لأحداث OnTouch أو Onkey ما لم يكن لها خلفية! = NULL. تحقق من بعض الرمز الذي كتبته للمساعدة في هذا. في الحالة الأساسية يمكنك الاتصال PopupWindow#setBackgroundDrawable(new BitmapDrawable()) لإجبارها على التصرف بالطريقة التي تتوقعها. لن تحتاج إلى مستمع Onkey الخاص بك. قد تحتاج أيضًا إلى الاتصال PopupWindow#setOutsideTouchable(true) إذا كنت تريد أن تختفي عندما ينقر المستخدم خارج حدود النافذة.

الإجابة الباطنية الممتدة:

السبب في أن الخلفية لا يمكن أن تكون لاغية هو ما يحدث PopupWindow#preparePopup. إذا اكتشف background != null يخلق مثيلًا PopupViewContainer والمكالمات setBackgroundDrawable على ذلك ويضع عرض المحتوى الخاص بك فيه. PopupViewContainer هو أساسا FrameLayout التي تستمع لأحداث اللمس و KeyEvent.KEYCODE_BACK حدث لرفض النافذة. إذا كانت الخلفية == NULL ، فهي لا تفعل أيًا من ذلك وتستخدم فقط عرض المحتوى الخاص بك. يمكنك ، كبديل للاعتماد على PopupWindow للتعامل مع ذلك ، قم بتوسيع جذرك ViewGroup للتصرف بالطريقة التي تريدها.

نصائح أخرى

تفعل حسب ما يليها تعمل بشكل جيد:

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);

بالنسبة للمشاريع الجديدة ، من الأفضل استخدامها

popupWindow.setBackgroundDrawable(new ColorDrawable());

بدلاً من

popupWindow.setBackgroundDrawable(new BitmapDrawable());

كما تم إهمال Bitmapdrawable. أيضا ، هو أفضل من القابلة للتشكيل في هذه الحالة. لقد لاحظت أنه عندما يكون popupwindow مستطيلًا مع زوايا مستديرة ، يملأ زوايا القابلة للرسائل السوداء.

الحل البسيط حقًا هو كتابة pw.setfocusable (صحيح) ، ولكن ربما لا تريد القيام بذلك لأن النشاط الخريطة لن تتعامل مع الأحداث التي تعمل باللمس.

الحل الأفضل هو تجاوز المفتاح الخلفي ، على سبيل المثال:

@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);
} 

حظا طيبا وفقك الله!

للباحثين الجدد, ، كما إنشاء ملف 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);

فقط استخدم هذا

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

الذي لم يتم إهماله. كنت أتجنب جديد من القابلة للعلاج () لأنها ستجعلها ببطء حيث تحاول رسم شكل عندما تحتاج الشاشة إلى إعادة رسمها.

آمل أن يكون هذا هو المساعدة لك

 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;
        }
    });

تحتاج إلى إضافة setBackgroundDrawable(new BitmapDrawable()) من اجلك PopupWindow.

    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 底层 消息 机制 机制 决定 , , 因为 它 阻塞式 的。

pw.setBackgroundDrawable(new ColorDrawable());  

يجب أن يكتبها من قبل setContentView

هذا يعمل بالنسبة لي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top