我可以创建和显示一个自定义警报对话框很好,但即使这样,我有android:layout_width/height=“fill_parent”在对话xml中,它只和内容一样大。

我想要的是填充整个屏幕的对话框,除了20像素的填充。 然后,作为对话框一部分的图像将自动使用fill_parent拉伸到完整的对话框大小。


当前回答

根据Android平台开发人员Dianne Hackborn在这个讨论组的帖子,对话框将窗口的顶层布局宽度和高度设置为WRAP_CONTENT。要使对话框更大,可以将这些参数设置为MATCH_PARENT。

演示代码:

    AlertDialog.Builder adb = new AlertDialog.Builder(this);
    Dialog d = adb.setView(new View(this)).create();
    // (That new View is just there to have something inside the dialog that can grow big enough to cover the whole screen.)

    WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
    lp.copyFrom(d.getWindow().getAttributes());
    lp.width = WindowManager.LayoutParams.MATCH_PARENT;
    lp.height = WindowManager.LayoutParams.MATCH_PARENT;
    d.show();
    d.getWindow().setAttributes(lp);

注意,属性是在对话框显示之后设置的。系统对设置时间很挑剔。(我猜布局引擎必须在对话框第一次显示时设置它们。)

最好通过扩展Theme来实现这一点。对话,那么您就不必玩什么时候调用setAttributes的猜谜游戏了。(尽管让对话框自动采用适当的明暗主题或蜂巢Holo主题需要更多的工作。这可以根据http://developer.android.com/guide/topics/ui/themes.html#SelectATheme来做)

其他回答

如果你使用对话片段,你可以用onResume方法。 这是Xamarin Android的代码,但我认为它很容易理解

public override void OnResume() 
{
    base.OnResume();
    var metrics = Resources.DisplayMetrics;

    double width = metrics.WidthPixels * 0.9;
    double height = metrics.HeightPixels * 0.6;

    this.Dialog.Window.SetLayout((int)width, (int)height);
    this.Dialog.Window.SetGravity(Android.Views.GravityFlags.Center);
}

部分基于阿南德的回答。这对我来说很管用:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val fragmentActivity = requireActivity()
    val v = View.inflate(context, R.layout.fragment_about_dialog, null)
    val dialog = Dialog(fragmentActivity)
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
    dialog.setContentView(v)

    val wm = fragmentActivity.getSystemService(Context.WINDOW_SERVICE) as WindowManager 

    val display = if (VERSION.SDK_INT >= VERSION_CODES.R) {
        fragmentActivity.display
    } else {
        wm.defaultDisplay // deprecated in API 30
    }

    val size = Point()
    display?.getSize(size)

    val width = size.x - 50
    val height = size.y - 50
    val lp = WindowManager.LayoutParams()
    lp.copyFrom(dialog.window?.attributes)
    lp.width = width
    lp.height = height
    dialog.show()
    dialog.window?.attributes = lp
    
    return dialog
}

对于对话框布局使用constraintLayout:

<androidx.constraintlayout.widget.ConstraintLayout 
        android:id="@+id/dialogLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    ...
</androidx.constraintlayout.widget.ConstraintLayout>

结果:

这在改变屏幕方向时工作得很好。

你必须在显示之前设置对话框的高度和宽度(dialog.show())

所以,像这样做:

dialog.getWindow().setLayout(width, height);

//then

dialog.show()
    final AlertDialog alertDialog;

    LayoutInflater li = LayoutInflater.from(mActivity);
    final View promptsView = li.inflate(R.layout.layout_dialog_select_time, null);

    RecyclerView recyclerViewTime;
    RippleButton buttonDone;

    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mActivity);
    alertDialogBuilder.setView(promptsView);

    // create alert dialog
    alertDialog = alertDialogBuilder.create();

    /**
     * setting up window design
     */
    alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);


    alertDialog.show();

    DisplayMetrics metrics = new DisplayMetrics(); //get metrics of screen
    mActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int height = (int) (metrics.heightPixels * 0.9); //set height to 90% of total
    int width = (int) (metrics.widthPixels * 0.9); //set width to 90% of total

    alertDialog.getWindow().setLayout(width, height); //set layout
    recyclerViewTime = promptsView.findViewById(R.id.recyclerViewTime);


    DialogSelectTimeAdapter dialogSelectTimeAdapter = new DialogSelectTimeAdapter(this);
    RecyclerView.LayoutManager linearLayoutManager = new LinearLayoutManager(this);
    recyclerViewTime.setLayoutManager(linearLayoutManager);
    recyclerViewTime.setAdapter(dialogSelectTimeAdapter);

    buttonDone = promptsView.findViewById(R.id.buttonDone);
    buttonDone.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            alertDialog.dismiss();

        }
    });

让你的对话成为一种活动。3个步骤

步骤1: 将其中一个放在styles.xml中

风格: 我喜欢这个,因为你可以将父主题更改为你的主题的名称,你将在你的应用程序的其余部分使用。

<style name="DialogTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@color/transparent</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:windowMinWidthMajor">90%</item>
    <item name="android:windowMinWidthMinor">90%</item>
</style>

方式二:

<style name="DialogTheme" parent="Theme.AppCompat.Dialog">
    <item name="android:windowMinWidthMajor">90%</item>
    <item name="android:windowMinWidthMinor">90%</item>
</style>

步骤2: 然后把它放在AndroidManifest.xml中

<activity
    android:name="com.example.YourApp.DialogActivity"
    android:theme="@style/DialogTheme" />

步骤3: 确保你的主布局宽度fill_parent或match_parent在activity_dialog.xml中

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    tools:context=".DialogActivity">

</androidx.constraintlayout.widget.ConstraintLayout>