リストアクティビティでアイテムをクリックすると、ポップアップウィンドウが表示されます。問題は、バックキーが閉じないことです。リストアクティビティでバックキーをキャッチしようとしましたが、登録されません...それから、ポップアップウィンドウに渡すビューに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);
しかし、そのリスナーはどちらも起動しません。手伝って頂けますか?私はアイデアがありません:)
これは、ポップアップウィンドウの背景が!= nullでない限り、onTouchイベントまたはonKeyイベントに応答しないためです。 私が書いたコードをチェックしてください これを支援します。基本的なケースでは、PopupWindow#setBackgroundDrawable(new BitmapDrawable())
を呼び出して、期待どおりに動作させることができます。独自のonKeyリスナーは必要ありません。また、ユーザーがウィンドウの境界の外側をクリックすると消える場合は、PopupWindow#setOutsideTouchable(true)
を呼び出す必要があります。
拡張された難解な答え:
バックグラウンドをnullにできない理由は、PopupWindow#preparePopup
で発生することです。 background != null
を検出すると、PopupViewContainer
のインスタンスを作成し、その上でsetBackgroundDrawable
を呼び出し、コンテンツビューをその中に配置します。 PopupViewContainer
は基本的に、タッチイベントとKeyEvent.KEYCODE_BACK
イベントをリッスンしてウィンドウを閉じるFrameLayout
です。 background == 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は角を黒で塗りつぶすことに気付きました。
本当に簡単な解決策は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;
}
});
PopupWindow
にsetBackgroundDrawable(new BitmapDrawable())
を追加する必要があります。
pw.setBackgroundDrawable(new ColorDrawable());
setContentViewの前に作成する必要があります
これは私のために動作します。
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+"");
}
});
}
この問題は、ポップアップウィンドウの最下層にあるメッセージマシンで発生します。