如何为自定义对话框设置边距?

问题描述

| 有人知道如何为自定义对话框设置边距吗?我之所以问是因为我有一个自定义对话框,但是即使我在布局参数上显式设置了WRAP_CONTENT,但在显示时它会拉伸以填充父对话框。 基本上,对话框包含一个列表视图,该列表视图的元素必须向下滚动,例如,当元素为1时,它不会拉伸,但是当添加更多项时,对话框将占据整个屏幕。 有什么建议么?我尝试了所有可能的解决方案组合,但均未获得令人满意的结果 编辑:添加对话框布局
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:layout_width=\"fill_parent\"
    android:layout_height=\"wrap_content\"
    android:layout_margin=\"50dip\"   
    android:orientation=\"vertical\"
    android:layout_gravity=\"top|center\">

    <FrameLayout android:layout_width=\"fill_parent\" android:layout_margin=\"5dip\" android:layout_height=\"wrap_content\">

            <TextView android:layout_width=\"wrap_content\"        android:layout_height=\"wrap_content\" 
                android:layout_gravity=\"center\"
                android:textSize=\"20sp\" android:textColor=\"@color/black\"/>

            <Button android:layout_height=\"32dip\" android:layout_width=\"32dip\" 
                android:id=\"@+id/guide_dialog_cross_button\"
                android:background=\"@drawable/button_cross_white\"/>

        </FrameLayout>


    <ListView android:layout_width=\"fill_parent\" android:layout_height=\"wrap_content\" 
        android:fadingEdge=\"none\"
        android:layout_margin=\"5dip\"/>

    <ImageButton android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\"
        android:layout_margin=\"5dip\" />

</LinearLayout>
    

解决方法

        边距不能用于对话框,我想顶级窗口视图不是支持边距的布局类型。我见过一些帖子说,将边距定义为Dialog的样式时可以使用(而不是在顶层view元素上),但这似乎也不起作用。 要解决此问题,您需要为Dialog背景使用一个
inset
可绘制对象,并调整任何填充以解决背景的多余插图。在下面的示例中,我将设置左右边距。 对话框背景可绘制:
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<!-- drawable is a reference to your \'real\' dialog background -->
<!-- insetRight and insetLeft add the margins -->
<inset
    xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:drawable=\"@drawable/dialog_background\" 
    android:insetRight=\"10dp\"
    android:insetLeft=\"10dp\">
</inset>
对话框主视图:
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<!-- paddingTop / paddingBottom padding for the dialog -->
<!-- paddingLeft / paddingRight padding must add the additional inset space to be consistent -->
<!-- background references the inset background drawable -->
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:orientation=\"vertical\"
    android:layout_width=\"fill_parent\"
    android:layout_height=\"wrap_content\"
    android:paddingTop=\"5dp\"
    android:paddingBottom=\"5dp\"
    android:paddingLeft=\"15dp\"
    android:paddingRight=\"15dp\"
    android:background=\"@drawable/dialog_background_inset\">

<!-- ...the rest of the layout... -->
您可能还需要将对话框本身的背景色设置为透明。添加颜色资源,如下所示:
<color name=\"transparent\">#00000000</color>
并将对话框的窗口背景颜色设置为此(注意:您不能直接分配颜色,eclipse会抱怨)
<style name=\"Dialog\" parent=\"android:style/Theme.Dialog\">
    <item name=\"android:windowBackground\">@color/transparent</item>
    <item name=\"android:windowNoTitle\">true</item>
    <item name=\"android:windowIsFloating\">true</item>
</style>
此样式应作为
theme
参数传递给Dialog \的构造函数,如
new Dialog(context,R.style.Dialog);
    ,        我有同样的问题,我通过在InsetDrawable上设置窗口背景来解决:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
...
...
AlertDialog dialog = builder.create();

ColorDrawable back = new ColorDrawable(Color.TRANSPARENT);
InsetDrawable inset = new InsetDrawable(back,20);
dialog.getWindow().setBackgroundDrawable(inset);

dialog.show();
在这种情况下,对话框的所有边距将显示为20。     ,        边距似乎在对话框的自定义布局上不起作用,但是填充有效。尝试在顶级线性布局上设置填充。
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:orientation=\"vertical\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"match_parent\"
    android:paddingLeft=\"4dp\"
    android:paddingRight=\"4dp\" >
    ,        可以这样解决:
dialog.getWindow().getAttributes().height = 
           (int) (getDeviceMetrics(context).heightPixels*0.8);
`getDeviceMetrics方法:
public static DisplayMetrics getDeviceMetrics(Context context) {
    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    display.getMetrics(metrics);
    return metrics;
}
    ,        这是一种直接的,程序化的方式来设置带有边距的对话框的位置和大小。 我通过在
onCreateDialog
方法中应用tested12ѭ来测试我的方法:
public Dialog onCreateDialog( Bundle savedInstanceState )
{
    // create dialog in an arbitrary way
    Dialog dialog = super.onCreateDialog( savedInstanceState ); 
    DialogUtils.setMargins( dialog,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\",\"android\" );
    return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}
我的另一个SO回答中介绍了辅助方法。 本要点包含一个扩展版本,也支持沉浸模式。     ,        一个对我有用的简单解决方案是将我的整个View包裹在另一个View中,并设置内部View的边距。
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    xmlns:tools=\"http://schemas.android.com/tools\"
    android:layout_width=\"wrap_content\"
    android:layout_height=\"wrap_content\">

    <LinearLayout
        android:layout_margin=\"22dp\"
        android:orientation=\"vertical\"
        android:layout_width=\"220dp\"
        android:layout_height=\"wrap_content\">

    ... Buttons,TextViews,etc

    </LinearLayout>

</LinearLayout>
Obs:当我想在AlertDialog中留出边距时,该方法起作用。不考虑屏幕。     ,        1)如下更改主父布局高度layout18 height:
<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:layout_width=\"fill_parent\"
    android:layout_height=\"match_content\"
    android:layout_margin=\"50dip\"   
    android:orientation=\"vertical\"
    android:layout_gravity=\"top|center\">
2)现在将样式添加到您的styles.xml
<style name=\"dialogTheme\" parent=\"Base.Theme.AppCompat.Light.Dialog.Alert\"/>
3)现在添加以下代码以显示对话框:
Dialog dialog = new Dialog(DayActivity.this,R.style.dialogTheme);
dialog.setContentView(R.layout.dialog_custom_layout);
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
dialog.show();
    ,        如果要使用背景创建自定义对话框,则可以选择以下几行代码。 您可以将窗口属性
MATCH_PARENT
更改为全屏显示。   我的问题是对话框向其父级行进的宽度没有边距 尝试按照要求遵循以下代码
    Window window = event_dialog.getWindow();
    window.setGravity(Gravity.CENTER);
    WindowManager.LayoutParams wlp = window.getAttributes();
    wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
    wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
    wlp.flags &= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
    window.setAttributes(wlp);
dialog.show()
之前设置这些属性,或者通过将
margin
设置为
root
布局并将
custom background
设置为其子布局,可以将对话框的
LEFT,RIGHT,TOP,BOTTOM
边距设置为
<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:layout_margin=\"10dp\">
   <LinearLayout
    android:id=\"@+id/customLayout\"
    android:layout_width=\"match_parent\"
    android:layout_height=\"wrap_content\"
    android:background=\"@drawable/card_round_corner\"
    android:orientation=\"vertical\">

   </LinearLayout>
</RelativeLayout>
    ,        正如@simpleApps和@pospi指出的那样,您需要向对话框的backgroundDrawable中添加插图。如果使用自定义对话框,则可以尝试使用xml中定义的drawable
dialog?.window?.setBackgroundDrawableResource(R.drawable.background_dialog)
其中R.drawable.background_dialog定义为
<inset xmlns:android=\"http://schemas.android.com/apk/res/android\"
    android:insetLeft=\"20dp\"
    android:insetTop=\"40dp\"
    android:insetRight=\"20dp\"
    android:insetBottom=\"40dp\">
    <shape android:shape=\"rectangle\">
        <solid android:color=\"@color/color_background_fragment\" />
        <corners android:radius=\"10dp\" />
    </shape>
</inset>
    ,        一种简单的方法是将根布局设置为透明背景。然后,让其第一个孩子有边距或预设的高度和宽度。