質問

リストアクティビティのアイテムをクリックすると、ポップアップウィンドウが表示されます。問題は、バックキーがそれを閉じないことです。リストアクティビティでバックキーをキャッチしようとしましたが、登録しません...その後、ポップアップウィンドウに渡されたビューにonekeyListenerを登録してみました。このような:

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

しかし、そのリスナーはどちらも起きません。手伝って頂けますか?私はアイデアから外れています:)

役に立ちましたか?

解決

これは、ポップアップウィンドウが、!= nullという背景がない限り、OntouchまたはOnkeyイベントに応答しないためです。 私が書いたいくつかのコードをチェックしてください これを助けるために。基本的なケースでは、電話をかけることができます 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が非推奨であるため。また、この場合、ShapedRawableよりも優れています。 PopupWindowが丸い角を持つ長方形であるとき、ShapedRawable Fill Cornersが黒の角を埋めていることに気付きました。

本当に簡単な解決策は、pw.setfocusable(true)を記述することですが、おそらくこれを行いたくないでしょう。なぜなら、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);
} 

幸運を!

新しい検索者向け, 、作成として 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,""));

これは非推奨ではありません。画面を再描画する必要があるときに形状を描画しようとするので、ゆっくりとレンダリングするので、新しいShapeDrawable()を避けます。

これがあなたの助けになることを願っています

 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