89

popup.showAtLocationを使用してポップアップウィンドウを表示するときに背景をぼかしたり暗くしたり、 が呼び出されたときに背景をぼかしたり暗くしたりできるようにしたいと考えていますpopup.dismiss

レイアウト パラメータFLAG_BLUR_BEHINDFLAG_DIM_BEHINDアクティビティに適用しようとしましたが、アプリが起動するとすぐに背景がぼやけて暗くなるように見えます。

ポップアップだけでぼかし/調光するにはどうすればよいですか?

4

11 に答える 11

112

質問はPopupwindowクラスについてでしたが、誰もがDialogクラスを使用する答えを出しました。Popupwindowメソッドがないため、クラスを使用する必要がある場合、これはほとんど役に立ちPopupwindowませんgetWindow()

で実際に機能するソリューションを見つけましたPopupwindow。バックグラウンドアクティビティに使用するxmlファイルのルートが。である必要があるだけですFrameLayoutFramelayout要素にandroid:foregroundタグを付けることができます。このタグが行うことは、アクティビティ全体の上に階層化される描画可能なリソースを指定することです(つまり、Framelayoutがxmlファイルのルート要素である場合)。setAlpha()次に、前景のドローアブルの不透明度()を制御できます。

任意のドローアブルリソースを使用できますが、調光効果が必要な場合は、<shape>タグをルートとしてドローアブルフォルダにxmlファイルを作成します。

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <solid android:color="#000000" />
</shape>

(要素の詳細については、http://developer.android.com/guide/topics/resources/drawable-resource.html#Shapeshapeを参照してください)。描画可能なアイテムを透明にするカラータグにアルファ値を指定しなかったことに注意してください(例 #ff000000)。これは、ハードコードされたアルファ値が、コードでで設定した新しいアルファ値を上書きするように見えるためsetAlpha()、これは望ましくないためです。ただし、これは、描画可能なアイテムが最初は不透明(塗りつぶされた、不透明)になることを意味します。onCreate()したがって、アクティビティのメソッドで透過的にする必要があります。

Framelayoutxml要素コードは次のとおりです。

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainmenu"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:foreground="@drawable/shape_window_dim" >
...
... your activity's content
...
</FrameLayout>

アクティビティのonCreate()メソッドは次のとおりです。

public void onCreate( Bundle savedInstanceState)
{
  super.onCreate( savedInstanceState);

  setContentView( R.layout.activity_mainmenu);

  //
  // Your own Activity initialization code
  //

  layout_MainMenu = (FrameLayout) findViewById( R.id.mainmenu);
  layout_MainMenu.getForeground().setAlpha( 0);
}

最後に、アクティビティを暗くするコード:

layout_MainMenu.getForeground().setAlpha( 220); // dim

layout_MainMenu.getForeground().setAlpha( 0); // restore

アルファ値は0(不透明)から255(非表示)になります。ポップアップウィンドウを閉じるときは、アクティビティの調光を解除する必要があります。

ポップアップウィンドウを表示および非表示にするためのコードは含まれていませんが、その方法へのリンクは次のとおりです:http ://www.mobilemancer.com/2011/01/08/popup-window-in-android/

于 2012-05-23T17:33:03.740 に答える
86

に aをPopupWindow追加するだけなので、 show..() を呼び出した後にのを更新するために使用できます。ViewWindowManagerupdateViewLayout (View view, ViewGroup.LayoutParams params)LayoutParamsPopupWindowcontentView

ウィンドウ フラグFLAG_DIM_BEHINDを設定すると、ウィンドウの後ろのすべてが暗くなります。ディムの量を制御するために使用しますdimAmount(完全に不透明の場合は 1.0、ディムなしの場合は 0.0)。

に背景を設定すると、コンテナPopupWindowに入れられることに注意してくださいcontentView。つまり、親を更新する必要があります。

背景あり:

PopupWindow popup = new PopupWindow(contentView, width, height);
popup.setBackgroundDrawable(background);
popup.showAsDropDown(anchor);

View container = (View) popup.getContentView().getParent();
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams p = (WindowManager.LayoutParams) container.getLayoutParams();
// add flag
p.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
p.dimAmount = 0.3f;
wm.updateViewLayout(container, p);

背景なし:

PopupWindow popup = new PopupWindow(contentView, width, height);
popup.setBackgroundDrawable(null);
popup.showAsDropDown(anchor);

WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams p = (WindowManager.LayoutParams) contentView.getLayoutParams();
// add flag
p.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
p.dimAmount = 0.3f;
wm.updateViewLayout(contentView, p);

マシュマロの更新:

M では、PopupWindow は contentView を mDecorView と呼ばれる FrameLayout 内にラップします。PopupWindow のソースを掘り下げると、次のようなものが見つかりますcreateDecorView(View contentView)。mDecorView の主な目的は、M にとって新しいイベントのディスパッチとコンテンツの遷移を処理することです。これは、コンテナにアクセスするために .getParent() をもう 1 つ追加する必要があることを意味します。

次のような変更が必要な背景があります。

View container = (View) popup.getContentView().getParent().getParent();

API 18+ のより良い代替手段

を使用したハックの少ないソリューションViewGroupOverlay:

1) 目的のルート レイアウトを把握する

ViewGroup root = (ViewGroup) getWindow().getDecorView().getRootView();

2) 電話applyDim(root, 0.5f);またはclearDim()

public static void applyDim(@NonNull ViewGroup parent, float dimAmount){
    Drawable dim = new ColorDrawable(Color.BLACK);
    dim.setBounds(0, 0, parent.getWidth(), parent.getHeight());
    dim.setAlpha((int) (255 * dimAmount));

    ViewGroupOverlay overlay = parent.getOverlay();
    overlay.add(dim);
}

public static void clearDim(@NonNull ViewGroup parent) {
    ViewGroupOverlay overlay = parent.getOverlay();
    overlay.clear();
}
于 2015-04-29T17:30:13.510 に答える
30

xml ファイルに、幅と高さを「match_parent」として次のようなものを追加します。

<RelativeLayout
        android:id="@+id/bac_dim_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#C0000000"
        android:visibility="gone" >
</RelativeLayout>

アクティビティ oncreate で

//setting background dim when showing popup
back_dim_layout = (RelativeLayout) findViewById(R.id.share_bac_dim_layout);

最後に、popupwindow を表示するときに表示し、popupwindow を終了すると表示されないようにします。

back_dim_layout.setVisibility(View.VISIBLE);
back_dim_layout.setVisibility(View.GONE);
于 2013-04-08T12:40:57.957 に答える
12

もう 1 つのトリックは、1 つではなく 2 つのポップアップ ウィンドウを使用することです。最初のポップアップ ウィンドウは、薄暗い効果を提供する半透明の背景を持つ単純なダミー ビューになります。2 番目のポップアップ ウィンドウは、意図したポップアップ ウィンドウです。

ポップアップ ウィンドウの作成中のシーケンス: ダミーのポップアップ ウィンドウを最初に表示し、次に目的のポップアップ ウィンドウを表示します。

破棄中のシーケンス: 意図したポップアップ ウィンドウを閉じてから、ダミーのポップアップ ウィンドウを閉じます。

これら 2 つをリンクする最善の方法は、OnDismissListeneronDismiss()を追加し、ダミーのポップアップ ウィンドウを消すためのメソッドをオーバーライドすることです。

ダミーのポップアップ ウィンドウのコード:

フェードポップアップ.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" 
    android:id="@+id/fadePopup"
    android:background="#AA000000">
</LinearLayout>

フェード ポップアップを表示して背景を暗くする

private PopupWindow dimBackground() {

    LayoutInflater inflater = (LayoutInflater) EPGGRIDActivity.this
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    final View layout = inflater.inflate(R.layout.fadepopup,
            (ViewGroup) findViewById(R.id.fadePopup));
    PopupWindow fadePopup = new PopupWindow(layout, windowWidth, windowHeight, false);
    fadePopup.showAtLocation(layout, Gravity.NO_GRAVITY, 0, 0);
    return fadePopup;
}
于 2013-03-26T07:53:56.710 に答える
5

私はこれに対する解決策を見つけました

カスタムの透明なダイアログを作成し、そのダイアログ内でポップアップウィンドウを開きます。

dialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar);
emptyDialog = LayoutInflater.from(context).inflate(R.layout.empty, null);

/* blur background*/
WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();  
lp.dimAmount=0.0f;  
dialog.getWindow().setAttributes(lp);  
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); 
dialog.setContentView(emptyDialog);
dialog.setCanceledOnTouchOutside(true);
dialog.setOnShowListener(new OnShowListener()
{
    @Override
    public void onShow(DialogInterface dialogIx)
    {
        mQuickAction.show(emptyDialog); //open the PopupWindow here
    }
});
dialog.show();

ダイアログのxml(R.layout.empty):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent" android:layout_width="match_parent"
     style="@android:style/Theme.Translucent.NoTitleBar" />

ここで、ポップアップウィンドウが閉じたときにダイアログを閉じたいと思います。それで

mQuickAction.setOnDismissListener(new OnDismissListener()
{
    @Override
    public void onDismiss()
    {
        if(dialog!=null)
        {
            dialog.dismiss(); // dismiss the empty dialog when the PopupWindow closes
            dialog = null;
        }
    }
});

注:NewQuickActionここでは、PopupWindowを作成するためにプラグインを使用しました。ネイティブのポップアップウィンドウでも実行できます

于 2012-02-17T13:00:07.303 に答える
1
findViewById(R.id.drawer_layout).setAlpha((float) 0.7);

R.id.drawer_layout明るさを暗くしたいレイアウトのIDです。

于 2020-04-06T17:22:14.973 に答える
0

そのために使用できますandroid:theme="@android:style/Theme.Dialog"。アクティビティを作成し、アクティビティを次のようにAndroidManifest.xml定義します。

    <activity android:name=".activities.YourActivity"
              android:label="@string/your_activity_label"
              android:theme="@android:style/Theme.Dialog">
于 2010-07-11T01:34:58.453 に答える
-1

このコードは動作します

        pwindo = new PopupWindow(layout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
        pwindo.showAtLocation(layout, Gravity.CENTER, 0, 0);
        pwindo.setOutsideTouchable(false);

        View container = (View) pwindo.getContentView().getParent();
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        WindowManager.LayoutParams p = (WindowManager.LayoutParams) container.getLayoutParams();
        p.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
        p.dimAmount = 0.3f;
        wm.updateViewLayout(container, p);
于 2017-05-19T09:39:42.077 に答える