PopupWindow-外をクリックすると閉じる


93

アクティビティにPopupWindowがあります。アクティビティを操作しているとき(たとえば、リストをスクロールしているとき)でも、PopupWindowは引き続き表示されます。リストをスクロールしても、PopupWindowはまだ表示されています。

私が達成したいのは、PopupWindowではない画面でタッチ/スクロール/クリックなどを行っているときに、PopupWindowを閉じたいです。メニューのしくみと同じです。メニューの外側をクリックした場合、メニューは閉じられます。

私は試しましたsetOutsideTouchable(true)が、ウィンドウを閉じません。ありがとう。

回答:


129

外側をタッチするとウィンドウが閉じるように設定setBackgroundDrawablePopupWindowてみてください。


5
私はそれを逃した。ポップアップウィンドウでsetBackgroundDrawableを使用していますか?背景のドローアブルをnullに設定するとOnTouchListenerが終了することを知っています
Marcin S.

31
それでおしまい!thnx man!この場合、タッチイベントでも適切に処理できます。popupWindow.setOutsideTouchable(true); popupWindow.setTouchable(true); popupWindow.setBackgroundDrawable(new BitmapDrawable()); popupWindow.setTouchInterceptor(new OnTouchListener(){@Override public boolean onTouch(View v、MotionEvent event){if(AppContext.isDebugMode())Log.d( "POPUP_WINDOW"、 "v:" + v.getTag()+ " |イベント: "+ event.getAction()); popupWindow.dismiss(); return true;}});
ビアストーム2013

3
background drawableをnullに設定しても機能しません。他の誰かが問題を抱えているなら、私の答えを見てください。
mpellegr 2013

2
@WareNinja、あなたのコメントはうまくいきました!たぶん、このクエシトンにはすべてのアンスワールを残した方がいいかもしれません。それは、他の人に役立つでしょう
アントンキゼマ

3
@WareNinja BitmapDrawable()は低価格です。ColorDrawable()代わりに使用してください。
Srujan Barai、2015

125

受け入れられた回答に関するWareNinjaのコメントとMarcin S.のコメントもおそらく機能することを除いて、提供された回答はどれもうまくいきませんでした。これが私にとってうまくいく部分です:

myPopupWindow.setBackgroundDrawable(new BitmapDrawable());
myPopupWindow.setOutsideTouchable(true);

または:

myPopupWindow.setFocusable(true);

違いはわかりませんが、ListPopupWindowのソースコードは実際にモダリティがsetModalでtrueに設定されている場合に後者を使用するため、少なくともAndroid開発者はこれを実行可能なアプローチと見なしており、1行しかありません。


6
どうもありがとうございます。他の答えはどれも私にとってうまくいかなかったか、それを十分に説明しませんでした。2番目のオプションは、私にはうまくいきません。
JDN 2013

2
また、BitmapDrawableは非推奨になっています。新しいAPIバージョンでサポートされることが保証されていない一時的な回避策のように見えるため、問題の実際の解決策があると便利です。
HAL9000

BitmapDrawable非推奨のコンストラクタを使用しない場合は、こちらを参照してください:stackoverflow.com/a/21680637/2048266。popupWindow.setBackgroundDrawable(new BitmapDrawable(getResources()、 ""));
nommer 2014年

の代替方法を使用している間setFocusable、ボタンを2回クリックする必要があります(ボタンがポップアップの外側に配置されている場合)。1番目の方法と同様に、うまく機能します:)
Joy Rex

BitmapDrawable()低価格です。ColorDrawable()代わりに使用してください。
Srujan Barai、2015

59

同じ問題に遭遇し、以下のコードで修正しました。それは私にとってはうまくいきます。

    // Closes the popup window when touch outside.
    mPopupWindow.setOutsideTouchable(true);
    mPopupWindow.setFocusable(true);
    // Removes default background.
    mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

ところで、BitmapDrawable非推奨のコンストラクタを使用しないでください。この新しいColorDrawable(android.R.color.transparent)を使用して、デフォルトの背景を置き換えます。

楽しんで@。@


3
popoupWindowを表示する前に、必ずこのコードを追加してください
snersesyan

ポップアップでフォーカスが必要ない場合、本当にfocusableをtrueに設定する必要がありますか?
Levor

私はこれが機能することに驚いていますが、API 21では必須です。これにより、ポップアップウィンドウが正しくアニメーション化されないことも修正されました。
EpicPandaForce

24

遅いのはわかりますが、ポップアップウィンドウにまだ問題があることに気づきました。私は、ポップアップウィンドウの外側をタッチまたはクリックするか、ウィンドウ自体に触れるだけでポップアップウィンドウを閉じることができる、完全に機能する例を書くことにしました。そのためには、新しいPopupWindowクラスを作成し、このコードをコピーします。

PopupWindow.class

public class PopupWindow extends android.widget.PopupWindow
{
Context ctx;
Button btnDismiss;
TextView lblText;
View popupView;

public PopupWindow(Context context)
{
    super(context);

    ctx = context;
    popupView = LayoutInflater.from(context).inflate(R.layout.popup, null);
    setContentView(popupView);

    btnDismiss = (Button)popupView.findViewById(R.id.btn_dismiss);
    lblText = (TextView)popupView.findViewById(R.id.text);

    setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
    setWidth(WindowManager.LayoutParams.WRAP_CONTENT);

    // Closes the popup window when touch outside of it - when looses focus
    setOutsideTouchable(true);
    setFocusable(true);

    // Removes default black background
    setBackgroundDrawable(new BitmapDrawable());

    btnDismiss.setOnClickListener(new Button.OnClickListener(){

        @Override
        public void onClick(View v) {


         dismiss();
        }});

    // Closes the popup window when touch it
/*     this.setTouchInterceptor(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                dismiss();
            }
            return true;
        }
    }); */   
   } // End constructor

   // Attaches the view to its parent anchor-view at position x and y
   public void show(View anchor, int x, int y)
   {
      showAtLocation(anchor, Gravity.CENTER, x, y);
   }
}

次に、ポップアップウィンドウのレイアウトを作成します: popup.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout     
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="1dp"
    android:orientation="vertical"
    android:padding="10dp" >

<TextView 
    android:id="@+id/text" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"  
    android:gravity="center" 
    android:padding="5dp" 
    android:text="PopupWindow Example"
    android:textColor="#000000" 
    android:textSize="17sp" 
    android:textStyle="italic" />

<FrameLayout
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center_vertical">

    <Button
        android:id="@+id/btn_dismiss" 
        style="?android:attr/buttonStyleSmall" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="Dismiss" 
        android:visibility="gone" />

    <TextView
        android:id="@+id/lbl_dismiss"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Touch outside of this box to dismiss"
        android:textColor="#ffffff"
        android:textStyle="bold" />

</FrameLayout>      

メインアクティビティで、PopupWindowクラスのインスタンスを作成します。

final PopupWindow popupWindow = new PopupWindow(this);
popupWindow.show(findViewById(R.id.YOUR_MAIN_LAYOUT), 0, -250);

YOUR_MAIN_LAYOUTは、popupWindowがポップアップする現在のアクティビティのレイアウトです。


1
ありがとう-これは私のために働いた。ちょっとしたメモとして、カスタムクラスにPopupWindow以外の名前を使用することをお勧めします。おそらく、PopupwindowではなくMyPopupWindowと呼んで、Androidが標準のAndroidクラスとカスタムクラスとの間で混乱しないようにします。
Simon

@Marcin S. findViewById(R.id.YOUR_MAIN_LAYOUT)?? R.layout.My_Layoutになりますか
Ankesh kumar Jaisansaria

@Simon findViewById(R.id.YOUR_MAIN_LAYOUT)?? R.layout.My_Layoutになりますか?
Ankesh kumar Jaisansaria 2016年

15

@LunaKongの回答と@HourGlassの確認に感謝します。重複したコメントはしたくないが、明確かつ簡潔にしたいだけだ。

// Closes the popup window when touch outside. This method was written informatively in Google's docs.
mPopupWindow.setOutsideTouchable(true);

// Set focus true to prevent a touch event to go to a below view (main layout), which works like a dialog with 'cancel' property => Try it! And you will know what I mean.
mPopupWindow.setFocusable(true);

// Removes default background.
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

Mttdat。


ポップアップウィンドウの外側をクリックして閉じられるようにしたいのですが、閉じると、その下のビュー(ポップアップウィンドウの一部ではなく、アクティビティの一部)がクリックされていました。setFocusabl(true)は私が探していたものでした。ありがとう!
hellaandrew 2018

@hellaandrew、それがあなたを助けてくれてうれしいです:)
Nguyen Tan Dat

8

ListPopupWindow示されたときに、ウィンドウがモーダルになるように設定。

mListPopupWindow.setModal(true);

このようにして、の外側をクリックすると、表示ListPopupWindowされなくなります。


ありがとう、私はこれを探していました。これは、ビューの外側に触れた後にlistpopupwindowを閉じることができるようにするだけでなく、listpopwindowの横にある他のビューにタッチイベントを渡しません。私の場合、listpopwindowの外側をタッチすると、その下にあるrecyclerviewにイベントを渡して、listpopupwindowを非表示にするのではなく、recyclerviewアイテムが不要に選択されていたため、これを必死に探していました。
shankar_vl

またmListPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);、ポップアップウィンドウが画面キーボードと干渉しないようにするために、が必要になる場合もあります。
Mr-IDE、

6

でキャンセルするにはpopupWindow.setOutsideTouchable(true)、幅と高さwrap_contentを以下のコードのようにする必要があることに注意してください:

PopupWindow popupWindow = new PopupWindow(
            G.layoutInflater.inflate(R.layout.lay_dialog_support, null, false),
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT, true);

popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(view, Gravity.RIGHT, 0, 0);

5
  popupWindow.setTouchable(true);
  popupWindow.setFocusable(true);
  popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);

画面をクリックまたはタッチすると、PopupWindowが閉じます。showAtLocationの前にfocusableをtrueに設定していることを確認してください。


1
これが質問に対する正確な回答を提供する方法を詳しく説明するために、いくつかの説明文を追加してください。ありがとう。
philantrovert 2017

ありがとう!showAtLocation()を呼び出す前に、セッターを呼び出す必要があります。
droid256

5

isOutsideTouchable OR isFocusableを使用して、外をタッチしたときにポップアップウィンドウを閉じることができます

popupWindow.isOutsideTouchable = true // dismiss popupwindow when touch outside

popupWindow.isFocusable = true // dismiss popupwindow when touch outside AND when press back button

注意

  • 現在、テスト後、ポップアップウィンドウを閉じるのに役立ち setBackgroundDrawable ません。

  • PopupWindowPopupWindow->PopupDecorView->dispatchKeyEventPopupWindow->PopupDecorView->onTouchEvent)で却下のコードを見る場合。あなたは、戻るボタンを押すと、彼らは却下しACTION_UP、外に触れると、彼らは却下するACTION_UPか、ACTION_OUTSIDE


4

@LunaKong提案作業は魅力のようです。

ただし、mPopupWindow.setFocusable(false)を設定します。ポップアップウィンドウを非表示にするために必要な不要なタッチを削除します。

例:画面にポップアップウィンドウが表示されていて、ボタンをクリックしようとしているとします。したがって、この場合、ボタンポップアップウィンドウの最初のクリックで(mpopwindow.setFocusable(true)の場合)は閉じます。ただし、ボタンを機能させるには、もう一度クリックする必要があります。if **(mpopwindwo.setFocusable(false)**ボタンを1回クリックすると、ポップアップウィンドウが閉じ、ボタンのクリックがトリガーさ れます。


1
どうもありがとう!私はまったく同じものを探していました
ガネーシュ


3

ウィンドウの背景を透明に設定します。

PopupWindow.getBackground().setAlpha(0);

その後、レイアウトに背景を設定します。正常に動作します。


1
getBackground()はnullになる可能性があります。
Jared Rummler 2015年

1

ポップアップをフォーカス可能にすることが望ましくない場合もあります(たとえば、別のビューからフォーカスを奪いたくない場合があります)。

別のアプローチは、タッチインターセプターを使用することです。

popupWindow.setOutsideTouchable(true);
popupWindow.setTouchInterceptor(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
            popupWindow.dismiss();
        }
        return false;
    }
});

0

View popupViewを使用して、popupWindowを閉じます。

`popupView.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View view) {
                       popupWindow.dismiss();
                   }
               }); 

`これを使用する場合、popupWindow内の任意のボタンにSetOnClickListenerを設定することもできます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.