【问题标题】:Android AlertDialog with rounded corners带有圆角的 Android AlertDialog
【发布时间】:2012-09-12 03:53:17
【问题描述】:

我一直在尝试制作带有圆角的警报对话框,但不知何故我无法做到。我试过了,但我失败了。我尝试关注这个博客http://blog.stylingandroid.com/archives/271,并以此为基础制作了我的风格。

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

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

/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

<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

<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

<?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

<?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

<?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>

我的 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();
            }
        });

}

我目前的输出:

我没有得到任何圆角。我可以看到它与通常的风格不同。即使我更改了可绘制对象的半径,角也不会反映这些更改。

【问题讨论】:

  • 不能用9块的图片作为圆角的背景吗?
  • 不,我想避免创建 9 个补丁图像,而是使用形状。 9 补丁图像我将尝试的最后一件事。让我在我的问题中也澄清一下。
  • 我知道 android 警报对话框样式使用 9 补丁图像。在提出这个问题之前我已经查过了。

标签: android android-layout android-alertdialog android-styles


【解决方案1】:

您可以使用以下代码来完成:

CustomDialog.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

<?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

<?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>

只需更改半径量:

dialog_title.xml

dialog_footer.xml

这将生成以下输出:

希望这会对你有所帮助。


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

1- ContextThemeWrapper 不适用于 API 14,它适用于 Gingerbread 和旧版本,但 API > 10 则不起作用。

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

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

用这个:

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

但你需要改变:

android:minSdkVersion="8"  

android:minSdkVersion="11" 

在 ICS (API 14) 上的结果将如下图所示:

这张图片来自运行 ICS 的三星 Galaxy S3。

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

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

最后一句话: 作为我对Android开发的一点了解(我不是专家),

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

如果我们想让它在 ICS 中运行,效果与 API 我们需要修改代码,所以它可以在 ICS 上运行,但不会在任何版本下运行API 11。

2- 即使在ICS中的结果也不尽如人意,圆角只适用于标题而不适用于页脚。


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

只需将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>

输出图像:

这张图片来自运行 ICS 的三星 Galaxy S3。

【讨论】:

  • 我知道我可以用对话框做到这一点,但我想用 AlertDialog 做到这一点。我正在尝试使用我的主题创建警报对话框。我不想要任何其他自定义。我只想要圆角。如果您查看我发布的博客链接,该代码确实有朝一日可以工作,但现在无法正常工作。我不知道现在有什么问题。
  • @VendettaDroid 我尝试了上面链接中的示例代码并在我的手机上运行它,它已经是圆角了。
  • @VendettaDroid 我应用了你的主题我也搞定了
  • 你可以尝试改变圆度,看看它是否正在改变。我根本看不到这种变化。
  • 我已经知道我需要更改可绘制形状中的半径以获得更多圆度。我已经尝试改变那些半径。它对我不起作用。
【解决方案2】:

距离@iDroid Explorer 答案仅一步之遥

在构建对话框时添加这一行

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

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

【讨论】:

  • 不错!由于语法错误,稍微编辑一下: dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
  • 只需将对话框背景设置为圆形drawable而不是view,不需要两次调用。
【解决方案3】:

只需使用官方材料组件库中包含的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();

然后使用 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>

【讨论】:

  • 很好解释。谢谢先生
  • 不错且简单的解决方案!但是,我必须将 '@color/' 添加到“MyThemeOverlay.MaterialComponents.MaterialAlertDialog”,否则我的应用会崩溃。
【解决方案4】:

我尝试了以下一个相同的问题,它对我有用。 即使是 ICS 也是如此。

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。然后为对话框视图实现了自定义布局

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.现在将形状添加到 pop_exit.xml 的父布局的背景中

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>

我就是这么做的。它适用于您也适用于 ICS

希望对您有所帮助。如果没有,请告诉我。

享受编码...

:)

【讨论】:

  • 感谢您花时间回答。如果您查看上面的 cmets 和 android116 的答案修订历史。他的回答和你说的差不多。我再次回复你,我知道我可以通过这种方式完成圆角,但我使用的是 AlertDialog.Builder。我编写的代码对于 GB 来说很好,但对于 ICS 则不起作用。我想知道原因。
  • 它工作正常,但它在警报框之外给出圆角矩形。这意味着它将外层作为圆角矩形和内层与矩形请帮助我。我只想要一个圆角矩形层
【解决方案5】:

正如您所说,您不想使用 9 补丁图像,请看这里。

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

原理完全一样,只是将背景分配给布局,而本示例是线性布局。

【讨论】:

  • 我确实尝试过这样做,但后来我的对话框布局具有圆角,然后是外部矩形,默认情况下它是 android 中对话框主题的一部分。所以想想矩形内的圆形布局,这就是我得到的。
  • 放弃自定义对话框的警报对话框。
  • 这不是问题。我知道如果我选择对话活动和其他选项,我可以轻松做到这一点。但我想确保我可以按照我想要的方式更改 AlertDialog 样式。
【解决方案6】:

最简单的方法:

dialog_card.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@android:color/white"/>
    <corners android:radius="8dp"/>
</shape>

themes.xml

<!--    ... your other style codes -->

<style name="MyAlertTheme" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
    <item name="android:windowBackground">@drawable/dialog_card</item>
</style>

在您的活动中

AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this, R.style.MyAlertTheme);
alert.setTitle("<Your Title>");
alert.setMessage("<Your Message>");
// ...

奖金:

如果您想在应用中的任何位置使用此 AlertDialog
只需在您的AppTheme 中添加&lt;item name="alertDialogTheme"&gt;@style/MyAlertTheme&lt;/item&gt;

所以你不必在AlertDialog.BUilder的第二个参数中传递R.style.MyAlertTheme

themes.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
<!-- here -->
    <item name="alertDialogTheme">@style/MyAlertTheme</item>
</style>

【讨论】:

  • 最佳答案!
【解决方案7】:
  1. 使用 dialog_corner 在可绘制文件夹中创建 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));

【讨论】:

    【解决方案8】:

    这对我有用:

    <style name="AppTheme.AlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
            <item name="android:colorBackground">@android:color/transparent</item>
            <item name="android:background">@drawable/dialog_bg</item>
    </style>
    

    dialog_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid android:color="@color/white"/>
        <corners android:radius="12dp"/>
    </shape>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-02
      • 2022-12-10
      • 1970-01-01
      • 2020-01-15
      • 1970-01-01
      • 2020-05-11
      相关资源
      最近更新 更多