带圆角的 Android AlertDialog

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12501488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 10:49:46  来源:igfitidea点击:

Android AlertDialog with rounded corners

androidandroid-layoutandroid-alertdialogandroid-styles

提问by VendettaDroid

I have been trying to make my Alert Dialog with rounded corners but somehow I am not able to. I have tried and I failed. I tried to follow this blog http://blog.stylingandroid.com/archives/271and made my styles based on that.

我一直试图用圆角制作我的警报对话框,但不知何故我无法做到。我试过了,但失败了。我尝试关注这个博客http://blog.stylingandroid.com/archives/271并基于此制作我的样式。

Btw, to add to my question now. Some of my new finding. The code in the above link just works fine on 2.3.3 (GB) but does not work at all in ICS . Some change made the code to break.

顺便说一句,现在补充我的问题。我的一些新发现。上面链接中的代码在 2.3.3 (GB) 上运行良好,但在 ICS 中根本不起作用。一些更改使代码中断。

I want to avoid creating 9 patch images and thus I am using shapes. 9 patch image is the last thing that I will try.I know that android alert dialog style is using 9 patch image. I already looked that up before throwing this question.

我想避免创建 9 个补丁图像,因此我使用了形状。9 补丁图像是我将尝试的最后一件事。我知道 android 警报对话框样式正在使用 9 补丁图像。在提出这个问题之前,我已经查过了。

/res/values/themes.xml

/res/values/themes.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="MyTheme" parent="@android:style/Theme.Dialog">
        <item name="android:alertDialogStyle">@style/dialog</item>
    </style>


</resources>

/res/values/styles.xml

/res/values/styles.xml

<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <style name="AppTheme" parent="android:Theme.Light" />

    <style name="myImageView">

        <!-- 3dp so the background border to be visible -->
        <item name="android:padding">3dp</item>
        <item name="android:background">@drawable/image_drawable</item>
        <item name="android:scaleType">fitCenter</item>
    </style>

    <style name="dialog">
        <item name="android:fullDark">@drawable/dialog_body</item>
        <item name="android:topDark">@drawable/dialog_title</item>
        <item name="android:centerDark">@drawable/dialog_body</item>
        <item name="android:bottomDark">@drawable/dialog_footer</item>
        <item name="android:fullBright">@drawable/dialog_body</item>
        <item name="android:centerBright">@drawable/dialog_body</item>
        <item name="android:topBright">@drawable/dialog_title</item>
        <item name="android:bottomBright">@drawable/dialog_footer</item>
        <item name="android:bottomMedium">@drawable/dialog_footer</item>
        <item name="android:centerMedium">@drawable/dialog_body</item>
    </style>

</resources>

/res/drawable/dialog_title.xml

/res/drawable/dialog_title.xml

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="-1dp">
    <shape android:shape="rectangle">
        <solid android:color="#FFFFFF" />
        <corners android:topLeftRadius="5dp" android:topRightRadius="5dp" />
        <stroke android:color="#FFFFFF" android:width="1dp" />
    </shape>
</inset>

/res/drawable/dialog_body.xml

/res/drawable/dialog_body.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient android:startColor="#FFFFFFFF" android:endColor="#FFFFFFFF"
        android:angle="270" />
</shape>

/res/drawable/dialog_footer.xml

/res/drawable/dialog_footer.xml

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

    <solid android:color="#FFFFFF" />

    <corners
        android:bottomLeftRadius="5dp"
        android:bottomRightRadius="5dp" />

    <stroke
        android:width="1dp"
        android:color="#FFFFFF" />

</shape>

res/layout/dialog_layout.xml

res/layout/dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="45dp"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/button1"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="90dp"
        android:layout_toLeftOf="@+id/textView1"
        android:background="@drawable/button_selector"
        android:text="Ok"
        android:textColor="@android:color/white"
        android:textStyle="bold" />

    <Button
        android:id="@+id/button2"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@+id/button1"
        android:layout_marginRight="48dp"
        android:background="@drawable/button_selector"
        android:text="More"
        android:textColor="@android:color/white"
        android:textStyle="bold" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/button1"
        android:layout_marginTop="41dp"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

My code for AlertDialog:

我的 AlertDialog 代码:

public static void createYesNoDialog(final Context context, String positivebuttonname,
            String negativebuttonname, String message, int messagedrawable, String headermessage,
            final DialogResponse dr) {
        final DialogResponse dialogResponse = dr;
        ContextThemeWrapper ctw = new ContextThemeWrapper(context,
                com.gp4ever.worldlogo.quiz.R.style.MyTheme);

        AlertDialog.Builder builder = new AlertDialog.Builder(ctw);
        LayoutInflater inflater = (LayoutInflater)context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout = inflater.inflate(com.gp4ever.worldlogo.quiz.R.layout.dialog_layout, null);
        TextView text = (TextView)layout.findViewById(com.gp4ever.worldlogo.quiz.R.id.textView1);
        Button buttonOk = (Button)layout.findViewById(com.gp4ever.worldlogo.quiz.R.id.button1);
        Button buttonMore = (Button)layout.findViewById(com.gp4ever.worldlogo.quiz.R.id.button2);
        text.setText(message);
        if (messagedrawable > 0) {
            text.setCompoundDrawablesWithIntrinsicBounds(messagedrawable, 0, 0, 0);
        } else if (messagedrawable == 0)
            text.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
        builder.setView(layout);
        builder.setCancelable(false);
        builder.setTitle(headermessage);
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        final AlertDialog dialog = builder.create();

        buttonOk.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                dialog.cancel();
            }
        });
        buttonMore.setOnClickListener(new OnClickListener() {

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

}

}

My current output:

我目前的输出:

I do not get any rounded corners. I can see that it is different from the usual style. Even though I change radius on my drawable, the corners does not reflect to those changes.

我没有得到任何圆角。我可以看到它与通常的风格不同。即使我改变了我的 drawable 的半径,角落也不会反映这些变化。

enter image description here

在此处输入图片说明

回答by androidqq6

You can do it using the following code:

您可以使用以下代码执行此操作:

CustomDialog.java:

自定义对话框.java:

public class MainActivity extends Activity{

    private static final int ALERT_DIALOG = 1;

    @Override
    public void onCreate( Bundle savedInstanceState )
    {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.main );

        ( (Button) findViewById( R.id.button1 ) )
            .setOnClickListener( new OnClickListener()
                {
                    public void onClick( View v )
                    {
                        showDialog( ALERT_DIALOG );
                    }
                }
            );
    }

    @Override
    protected Dialog onCreateDialog( int id ){
        Dialog dialog = null;
        if ( id == ALERT_DIALOG )
        {
            ContextThemeWrapper ctw = new ContextThemeWrapper( this, R.style.MyTheme );
            AlertDialog.Builder builder = new AlertDialog.Builder( ctw );
            builder.setMessage( "Hello World" )
                .setTitle( "Alert Dialog" )
                .setIcon( android.R.drawable.ic_dialog_alert )
                .setCancelable( false )
                .setPositiveButton( "Close", new DialogInterface.OnClickListener()
                    {
                        public void onClick( DialogInterface dialog, int which )
                           {
                                dialog.dismiss();
                           }
                        } 
                    );
            dialog = builder.create();
        }
        if ( dialog == null )
        {
            dialog = super.onCreateDialog( id );
        }
        return dialog;
     }
 }

dialog_title.xml

dialog_title.xml

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetBottom="-1dp">
    <shape android:shape="rectangle">
        <solid android:color="#000000" />
        <corners android:topLeftRadius="20dp" android:topRightRadius="20dp" />
        <stroke android:color="#7F7F7F" android:width="1dp" />
    </shape>
</inset>

dialog_footer.xml

dialog_footer.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#7F7F7F" />
    <corners android:bottomLeftRadius="20dp" android:bottomRightRadius="20dp" />
    <stroke android:color="#7F7F7F" android:width="1dp" />
</shape>

Just change the radius amount in:

只需更改半径量:

dialog_title.xml

dialog_title.xml

and

dialog_footer.xml

dialog_footer.xml

and that'll generate the following output:

这将生成以下输出:

enter image description here

在此处输入图片说明

hope this will help you.

希望这会帮助你。



UPDATE:
I'm not an expert but this is what I found. It may be right or wrong. After many attempts I ended up with the following:

更新:
我不是专家,但这是我发现的。它可能是对的,也可能是错的。经过多次尝试,我最终得到以下结果:

1- ContextThemeWrapperis not applicable for API 14, it works fine on Gingerbread and older versions but with API > 10 it doesn't work.

1-ContextThemeWrapper不适用于 API 14,它在 Gingerbread 和旧版本上运行良好,但 API > 10 它不起作用。

2- to overcome the above issue and make it work on API > 10 as requested, I replace this line:

2- 为了克服上述问题并使其按要求在 API > 10 上工作,我替换了这一行:

ContextThemeWrapper ctw = new ContextThemeWrapper( this, R.style.MyTheme );
AlertDialog.Builder builder= new AlertDialog.Builder( ctw );

with this:

有了这个:

AlertDialog.Builder builder= new AlertDialog.Builder( this,R.style.MyTheme );

but you need to change:

但你需要改变:

android:minSdkVersion="8"  

to

android:minSdkVersion="11" 

the result will be as shown in the following image on ICS (API 14):

结果将如下面的 ICS (API 14) 图像所示:

enter image description here

在此处输入图片说明

This image is from a Samsung Galaxy S3 running ICS.

此图像来自运行 ICS 的三星 Galaxy S3。

Note: modified project initiated with API 14 SO manifest sdk will be:

注意:使用 API 14 SO manifest sdk 启动的修改项目将是:

<uses-sdk
  android:minSdkVersion="11"
  android:targetSdkVersion="15" />


FINAL WORD:As my little knowledge in Android development (I'm not an expert),

最后一句话:由于我对 Android 开发的了解很少(我不是专家),

1- custom alert dialog runs smoothly in API < 10 but not > 10 with the same Java code,

1- 自定义警报对话框在 API < 10 但不是> 10 中使用相同的 Java 代码顺利运行,

if we want it to run in ICS with the same effect as appeared in API < 10, we need to modify the code, so it will run on ICS but will not run in any version down API 11.

如果我们希望它在 ICS 中运行的效果与 API < 10 中出现的效果相同,我们需要修改代码,以便它可以在 ICS 上运行,但不会在 API 11 下的任何版本中运行。

2- even the result in ICS is not satisfactory, the round corner applies only to the title but not the footer.

2- 即使ICS中的结果不令人满意,圆角仅适用于标题而不适用于页脚。



SECOND UPDATE:FINALLY I get all corners round,

第二次更新:最后我得到了所有的角落,

JUST apply paddingto dialog_footer.xmlas follows:

padding只需适用于dialog_footer.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
    <solid android:color="#7F7F7F" />
    <corners android:bottomLeftRadius="20dp" android:bottomRightRadius="20dp" />
    <stroke android:color="#7F7F7F" android:width="1dp" />
    <padding android:left="10dp" android:top="10dp" android:right="10dp"
android:bottom="10dp" /> 
</shape>

Output image:

输出图像:

enter image description here

在此处输入图片说明

This image is from a Samsung Galaxy S3 running ICS.

此图像来自运行 ICS 的三星 Galaxy S3。

回答by Youtoo

Just one more step from @iDroid Explorer answer

距离@iDroid Explorer 的回答仅一步之遥

add this line when you build the dialog

构建对话框时添加此行

dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

and this will get the rectangle disappear (which actually is transparent) and get a perfect rounded dialog box.

这将使矩形消失(实际上是透明的)并获得一个完美的圆形对话框。

回答by Gabriele Mariotti

Just use the MaterialAlertDialogBuilderincluded in the official Material Components library.

只需使用MaterialAlertDialogBuilder包含在官方材料组件库中的。

new MaterialAlertDialogBuilder(MainActivity.this,R.style.MyThemeOverlay_MaterialComponents_MaterialAlertDialog)
            .setTitle("Dialog")
            .setMessage("Lorem ipsum dolor ....")
            .setPositiveButton("Ok", /* listener = */ null)
            .setNegativeButton("Cancel", /* listener = */ null)
            .show();

Then define the style using the shapeAppearanceOverlayattribute.

然后使用shapeAppearanceOverlay属性定义样式。

 <style name="MyThemeOverlay.MaterialComponents.MaterialAlertDialog" parent="@style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
    <item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.MyApp.Dialog.Rounded</item>
  </style>

  <style name="ShapeAppearanceOverlay.MyApp.Dialog.Rounded" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">8dp</item>
  </style>

enter image description here

在此处输入图片说明

回答by Shreyash Mahajan

I have try the same problem with below one and it works for me. Even for ICS also.

我在下面的一个问题上尝试过同样的问题,它对我有用。即使对于ICS也。

1. First i have put the theme to my AlertDialog.

1. 首先我把主题放到我的 AlertDialog 中。

final Dialog  nag = new Dialog(this,android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
        nag.requestWindowFeature(Window.FEATURE_NO_TITLE);
        nag.setCancelable(true);
        nag.setContentView(R.layout.pop_exit);  
        Button btnNO = (Button)nag.findViewById(R.id.btn_popup_NO);
        Button btnYES = (Button)nag.findViewById(R.id.btn_popup_YES);


        btnNO.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

            nag.cancel();


            }
        });

        btnYES.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                System.exit(0);

            }
        });

        nag.show();

2. Then have implemented the Custom Layout for the Dialog view

2.然后为Dialog视图实现了自定义布局

pop_exit.xml

pop_exit.xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:gravity="center" android:layout_height="fill_parent">

    <!-- <LinearLayout android:orientation="vertical" android:layout_marginLeft="20dp" 
        android:layout_marginRight="20dp" android:background="#95000056" android:layout_width="fill_parent" 
        android:layout_height="wrap_content"> -->

    <LinearLayout android:orientation="vertical"
        android:layout_marginLeft="20dp" android:layout_marginRight="20dp"
        android:background="@drawable/round" android:layout_width="fill_parent"
        android:layout_height="wrap_content">



        <TextView android:text="Exit Application"
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal" android:textStyle="bold"
            android:textColor="#fff" android:textSize="20dp"
            android:layout_marginTop="5dp" />


        <LinearLayout android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:orientation="horizontal"
            android:layout_marginTop="5dp" android:weightSum="2"
            android:layout_marginLeft="10dp" android:layout_marginRight="10dp"
            android:gravity="center">

            <Button android:text="No" android:layout_weight="1"
                android:gravity="center" android:layout_width="wrap_content"
                android:layout_height="wrap_content" android:id="@+id/btn_popup_NO" />

            <Button android:text="Ok" android:layout_weight="1"
                android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:id="@+id/btn_popup_YES" />
        </LinearLayout>


    </LinearLayout>

</LinearLayout>

3. Now add shape to the Background of parent layout of pop_exit.xml

3. 现在在 pop_exit.xml 的父布局的背景中添加形状

round.xml // shape file

round.xml // 形状文件

    <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#99000056" />
    <corners android:radius="35px" />
    <padding android:left="0dp" android:top="0dp" android:right="0dp"
        android:bottom="0dp" />
</shape>

I just do it. It will works for you also for ICS.

我只是这样做。它也适用于 ICS

Hope it will help you. If not then let me know.

希望它会帮助你。如果没有,那么让我知道。

Enjoy Coding...

享受编码...

:)

:)

回答by Doomsknight

As you state you dont want to use a 9 patch image, take a look here.

当您声明您不想使用 9 个补丁图像时,请查看此处。

https://stackoverflow.com/a/1683195/940834

https://stackoverflow.com/a/1683195/940834

The principle is exactly the same, except you assign the background to your layout where this example is to a linear layout.

原理完全相同,除了您将背景分配给您的布局,而本示例是线性布局。

回答by siddhartha shankar

  1. create xml in drawable folder with dialog_corner.

    <?xml version="1.0" encoding="utf-8"?>
     <shape xmlns:android="http://schemas.android.com/apk/res/android">
      <solid android:color="@color/main_background"/>
    <corners
        android:topLeftRadius="@dimen/margin_10" android:topRightRadius="@dimen/margin_10"
        android:bottomRightRadius="@dimen/margin_10" android:bottomLeftRadius="@dimen/margin_10" />
    </shape>
    

    2.put in layout

    android:background="@drawable/dialog_corner"

    3.in you java file keep below code

  1. 使用 dialog_corner 在 drawable 文件夹中创建 xml。

    <?xml version="1.0" encoding="utf-8"?>
     <shape xmlns:android="http://schemas.android.com/apk/res/android">
      <solid android:color="@color/main_background"/>
    <corners
        android:topLeftRadius="@dimen/margin_10" android:topRightRadius="@dimen/margin_10"
        android:bottomRightRadius="@dimen/margin_10" android:bottomLeftRadius="@dimen/margin_10" />
    </shape>
    

    2.放入布局

    android:background="@drawable/dialog_corner"

    3.在你的java文件中保留下面的代码

View mView=LayoutInflater.from(mContext).inflate(R.layout.layout_pob,null); alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

查看 mView=LayoutInflater.from(mContext).inflate(R.layout.layout_pob,null); alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));