質問
リストアクティビティのアイテムをクリックすると、ポップアップウィンドウが表示されます。問題は、バックキーがそれを閉じないことです。リストアクティビティでバックキーをキャッチしようとしましたが、登録しません...その後、ポップアップウィンドウに渡されたビューに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
これは私のために働きます。