如何在对话框中设置边距

16

我在我的安卓应用程序中使用了Dialog来显示广告。但是我需要将这个Dialog从底部向上50dp的位置显示,因此我认为我们应该将Dialog重力设置为底部并将其底部边距设置为50dp。但我无法在Dialog中使用边距。请建议我如何解决。

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/popup_element"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/dialogback"
    android:orientation="vertical" >

    <WebView
        android:id="@+id/webView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

Java:

final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(0));
LayoutInflater inflator = (LayoutInflater) getApplicationContext()
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflator.inflate(R.layout.ad, null, false);
dialog.setContentView(view);
dialog.getWindow().setGravity(Gravity.BOTTOM);
dialog.setCancelable(true);
WebView webView = (WebView) dialog.findViewById(R.id.webView);
webView.loadUrl("");
webView.setWebViewClient(new MyWebViewClient());
webView.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        dialog.dismiss();
    }
});
dialog.show();

这个链接上的答案节省了我大量的时间。 https://dev59.com/YoTba4cB1Zd3GeqP2zet#49010511?newreg=7fe3448044b5406ca2a2dc8866159e72 - Sardorbek Kurbonov
7个回答

27

我做了一个类似的笑脸对话框。我扩展了对话框。

public class SmileCustomDialog extends Dialog {
Context mcontext;
GridView mGridview;

public GridView getGridview() {
    return mGridview;
}

public SmileCustomDialog(final Context context) {
    super(context, R.style.SlideFromBottomDialog);
    this.mcontext = context;
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = inflater.inflate(R.layout.emocategorydialog, null);
    mGridview = (GridView) v.findViewById(R.id.emogrid);
    mGridview.setSelector(new ColorDrawable(Color.TRANSPARENT));

    ImageAdapter mAdapter = new ImageAdapter(mcontext);
    mGridview.setAdapter(mAdapter);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.setContentView(v);

    WindowManager.LayoutParams params = this.getWindow().getAttributes();
    this.setCanceledOnTouchOutside(true);
    params.y = -100;
    this.getWindow().setAttributes(params);

}

}

但是最重要的是

WindowManager.LayoutParams params = yourDialog.getWindow().getAttributes(); // change this to your dialog.

params.y = -100; // Here is the param to set your dialog position. Same with params.x
        yourDialog.getWindow().setAttributes(params);

在展示对话框之前,只需添加此代码。


1
如果我想从左右两侧设置填充怎么办?我尝试使用Gravity和param.x来实现,但没有成功。 - Vaishali Sharma
我没有使用你的整个解决方案,但是 this.setCanceledOnTouchOutside(true); 对于解决我使用另一个解决方案时遇到的问题非常关键! - Carl Smith

24

WindowManager.LayoutParams:
public int x:X位置……当使用LEFT或START或RIGHT或END时,它提供给定边缘的偏移量
public int y:Y位置……当使用TOP或BOTTOM时,它提供给定边缘的偏移量
(http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#x)
因此:

final Dialog dialog = new Dialog(context);
    // ...
    // 例如:顶部+右侧边距:
    dialog.getWindow().setGravity(Gravity.TOP|Gravity.RIGHT);
    WindowManager.LayoutParams layoutParams = dialog.getWindow().getAttributes();
    layoutParams.x = 100; // 右侧边距
    layoutParams.y = 170; // 顶部边距
    dialog.getWindow().setAttributes(layoutParams);
    // 例如:底部+左侧边距:
    dialog.getWindow().setGravity(Gravity.BOTTOM|Gravity.LEFT);
    WindowManager.LayoutParams layoutParams = dialog.getWindow().getAttributes();
    layoutParams.x = 100; // 左侧边距
    layoutParams.y = 170; // 底部边距
    dialog.getWindow().setAttributes(layoutParams);

// 等等。

如何将对话框对齐到右侧,它应该对齐屏幕的右侧,请帮忙解决。 - Gyan Swaroop Awasthi

6
您可以为您的对话框创建样式,并在其中设置边距。
例如:
<style name="custom_style_dialog"> 
    <item name="android:layout_marginStart">16dp</item>
    <item name="android:layout_marginEnd">16dp</item>
</style>

接下来,在您的对话框类中:

class CountryDialog(
    context: Context
) : Dialog(context, R.style.custom_style_dialog) {

  //your code here
}

1
不错的解决方案!此外,您应该指定父样式,例如这样:<style name="custom_style_dialog" parent="Theme.AppCompat.Dialog"> ... - AlexS

4
这是一种设置四个边距的方法,无需考虑重力。我在onCreateDialog方法中测试了这种方法,并将其应用于DialogFragment
public Dialog onCreateDialog( Bundle savedInstanceState )
{
    // create dialog in an arbitrary way
    Dialog dialog = super.onCreateDialog( savedInstanceState ); 
    DialogUtils.setMargins( dialog, 0, 150, 50, 75 );
    return dialog;
}

这是将边距应用于对话框的方法:
public static Dialog setMargins( Dialog dialog, int marginLeft, int marginTop, int marginRight, int marginBottom )
{
    Window window = dialog.getWindow();
    if ( window == null )
    {
        // dialog window is not available, cannot apply margins
        return dialog;
    }
    Context context = dialog.getContext();

    // set dialog to fullscreen
    RelativeLayout root = new RelativeLayout( context );
    root.setLayoutParams( new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) );
    dialog.requestWindowFeature( Window.FEATURE_NO_TITLE );
    dialog.setContentView( root );
    // set background to get rid of additional margins
    window.setBackgroundDrawable( new ColorDrawable( Color.WHITE ) );

    // apply left and top margin directly
    window.setGravity( Gravity.LEFT | Gravity.TOP );
    LayoutParams attributes = window.getAttributes();
    attributes.x = marginLeft;
    attributes.y = marginTop;
    window.setAttributes( attributes );

    // set right and bottom margin implicitly by calculating width and height of dialog
    Point displaySize = getDisplayDimensions( context );
    int width = displaySize.x - marginLeft - marginRight;
    int height = displaySize.y - marginTop - marginBottom;
    window.setLayout( width, height );

    return dialog;
}

以下是我使用的辅助方法:

@NonNull
public static Point getDisplayDimensions( Context context )
{
    WindowManager wm = ( WindowManager ) context.getSystemService( Context.WINDOW_SERVICE );
    Display display = wm.getDefaultDisplay();

    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics( metrics );
    int screenWidth = metrics.widthPixels;
    int screenHeight = metrics.heightPixels;

    // find out if status bar has already been subtracted from screenHeight
    display.getRealMetrics( metrics );
    int physicalHeight = metrics.heightPixels;
    int statusBarHeight = getStatusBarHeight( context );
    int navigationBarHeight = getNavigationBarHeight( context );
    int heightDelta = physicalHeight - screenHeight;
    if ( heightDelta == 0 || heightDelta == navigationBarHeight )
    {
        screenHeight -= statusBarHeight;
    }

    return new Point( screenWidth, screenHeight );
}

public static int getStatusBarHeight( Context context )
{
    Resources resources = context.getResources();
    int resourceId = resources.getIdentifier( "status_bar_height", "dimen", "android" );
    return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}

public static int getNavigationBarHeight( Context context )
{
    Resources resources = context.getResources();
    int resourceId = resources.getIdentifier( "navigation_bar_height", "dimen", "android" );
    return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}

助手方法在我另一个SO答案中有解释。

这个Gist包含一个扩展版本,也支持沉浸模式。


3
View view = layoutInflater.inflate(R.layout.dialog_layout, null);
        AlertDialog infoDialog = new AlertDialog.Builder(this)
        .setView(view)  
        .create();
        Window window =infoDialog.getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND );
        WindowManager.LayoutParams wlp = window.getAttributes();
        wlp.gravity = Gravity.BOTTOM;
        wlp.dimAmount=(float) 0.0;
        //wlp.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND ;

        window.setAttributes(wlp);
        infoDialog.show();

将重力设置为底部


1

对我来说最有效的方法是将对话框视图包装在FrameLayout中,并添加填充,然后将onClickListner设置为“dismiss”对话框。像这样:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/parentFl"
    android:background="@android:color/transparent"
    android:padding="@dimen/vvlarge_margin">


 dialog?.window?.setBackgroundDrawable(context?.getDrawable(android.R.color.transparent))
 view.parentFl.setOnClickListener { dismiss() }

0
另一种方法是使用InsetDrawable。您只需指定insetLeftinsetRight,并将其应用为您的背景,如下所示:

inset_drawable.xml(在drawable文件夹中创建)

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/dialog_bg" <!-- this is simply a shape drawable with corners applied-->
android:insetLeft="30dp" <!-- specify your dimension -->
android:insetRight="30dp" />

your_layout.xml(您的自定义对话框)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/popup_element"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/inset_drawable"
android:orientation="vertical" >

<WebView
    android:id="@+id/webView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</LinearLayout>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接