获取AlertDialog的默认填充值

62

我需要使用自定义视图创建一个 AlertDialogAlertDialog 的消息具有默认填充,但当我设置视图时,它没有填充。我想要获得与消息默认填充相同的填充。我正在使用扩展 Holo 主题的样式(如果相关的话)。

AlertDialog.Builder builder = new AlertDialog.Builder(PlaylistListView.this.getContext());
builder.setTitle("Title");
builder.setView(inflate(context, R.layout.music_player_create_dialog, null));
builder.setPositiveButton("OK", null);
builder.setNegativeButton("Cancel", null);
builder.show();

这是内容的布局:

<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="@dimen/abc_dialog_padding_material"
    android:paddingRight="@dimen/abc_dialog_padding_material"
    android:paddingTop="@dimen/abc_dialog_padding_top_material"
    android:paddingBottom="@dimen/abc_dialog_padding_top_material">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Title:"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="bottom"
        android:background="@null"
        android:layout_marginTop="20dp"/>
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@color/divider"/>
</LinearLayout>

@snapdragon 请添加你已经完成的代码。 - demo_Ashif
3个回答

93

24
这个功能完美运作,我想指出的是,如果你使用?dialogPreferredPadding而不是?android:dialogPreferredPadding,这个属性在支持库中也是存在的。 - Jarett Millard
1
这个设置是什么值?我猜测是24dp,因为它目前是默认值,但我想知道是否根据材料规格将其设置为20dp在顶部 https://material.io/guidelines/components/dialogs.html#dialogs-specs - David
2
如何在程序中应用它?在我的情况下,我只使用AlertDialog.setAdapter(ListAdapter),没有任何视图。 - David
我想我们永远不会知道。 - Denny

26

我曾遇到同样的问题,因此不得不找到答案。如果有人在寻找答案,请看看我的解决方案。

AlertDialog布局的源代码在alert_dialog.xml中描述(例如,这里显示Android 4.4.1的代码,应该对应Holo主题)。该布局有硬编码填充(并且它们可能在不同版本的Android中不同)。要知道默认填充,您必须总结包含id/message TextView的视图的所有填充。在本例中,它们是3+14+5=22dp 左侧和1+10+5=16dp 右侧。

android:id/custom元素是插入自定义视图的位置,并且它具有3dp左填充和1dp右填充(从根元素开始,其他元素没有填充),您无需手动设置。

因此,为了使自定义视图的最终填充与消息的填充相同,请将其设置为19dp左侧和15dp右侧(并别忘了保留默认的5dp上下填充)。

示例代码:

final EditText input = new EditText( getContext() );
float dpi = ctx.getResources().getDisplayMetrics().density;
AlertDialog dialog = (new AlertDialog.Builder(getContext()))
        .setTitle("Rename track")
        .setMessage("Track name:")
        .setPositiveButton("OK", null)
        .setNegativeButton("Cancel", null)
        .create();
dialog.setView(input, (int)(19*dpi), (int)(5*dpi), (int)(14*dpi), (int)(5*dpi) );
dialog.show();
这些代码会产生这样的结果(看起来不错)。顺便说一下,这是材料主题,似乎有相同的填充(也是硬编码的)。
[]

很巧合的是,你在23小时前回答了我的问题,而我也正处于同样的困境。显然默认布局设计得不太好,但你的回答起作用了,并且让它看起来更漂亮了,谢谢你。 - Matthew Mitchell
1
@MatthewMitchell 没问题!是的,AlertDialog 布局应该使用一些 @android:dimen/dialog_padding 常量而不是硬编码数字,或者强制插入视图的填充(我认为第一种选项更好)。 - Osman-pasha
编译器说@android:dimen/dialog_padding不是公共的。 - Damn Vegetables
@Sin-jeong-hun,它在AlertDialog布局中没有使用,因此它可能包含与AlertDialog中的填充不同的值。 - Osman-pasha
3
我在自定义视图布局的paddingLeft和paddingRight中使用了"?dialogPreferredPadding"。 - Alexey
在我的情况下,这段代码是有效的:View view = getLayoutInflater().inflate(R.layout.dialog_deferred, null); float dpi = getResources().getDisplayMetrics().density; view.setPadding((int)(19*dpi), (int)(5*dpi), (int)(14*dpi), (int)(5*dpi)); builder.setView(view); - pablogupi

11

为了更全面地回答如何使用它的问题:

您可以在布局XML文件中使用android:paddingStart="?dialogPreferredPadding"android:paddingEnd="?dialogPreferredPadding"

或者,如果您想通过代码实现:

@JvmStatic
fun getDimensionFromAttribute(context: Context, attr: Int): Int {
    val typedValue = TypedValue()
    return if (context.theme.resolveAttribute(attr, typedValue, true)) 
           TypedValue.complexToDimensionPixelSize(typedValue.data, context.resources.displayMetrics) 
           else 0
}

用法:

val alertDialogPadding = getDimensionFromAttribute(context, R.attr.dialogPreferredPadding)
view.setPadding(alertDialogPadding, 0, alertDialogPadding, 0)

如果您使用 CheckBox(和可能是其他一些视图),我认为不可能设置填充或边距,以便它可以与对话框中的其他视图对齐,除非您将其包装在不同的视图中,或者扩展它。

1
Java版本: private static int getDimensionFromAttribute(Context context, int attrId) { final TypedValue value = new TypedValue(); if (context.getTheme().resolveAttribute(attrId, value, true)) { return TypedValue.complexToDimensionPixelSize(value.data, context.getResources().getDisplayMetrics()); } return 0; } - Oliver
@Oliver 不是真的需要。Kotlin支持Java,Java也支持Kotlin。而且这两种语言非常相似。 - android developer
也许对于有经验的开发人员来说并不是必需的,但新手可能会欣赏 :). 无论如何,我更喜欢在同一个项目中不混合使用 Kotlin 和 Java。 - Oliver
@Oliver 有时候你没有选择。如果你在一个旧项目上工作,它主要是Java。而且没有任何问题很难全部转换为Kotlin。我必须处理一个大约1000个Java文件的项目,到目前为止我只转换了大约200个文件为Kotlin。一个Android开发人员应该了解两种语言。两种语言都用于各种场合,包括Google的演示文稿和文档。现在Kotlin是主要的默认语言,因此更加重要。 - android developer
你说得没错...但这取决于项目。如果我的项目已经是Java的,我更喜欢所有代码都用同一种语言编写,所以除非完全必要,否则我不会在项目中使用Kotlin :) - Oliver
显示剩余2条评论

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