web-dev-qa-db-fra.com

Android AlertDialog avec des coins arrondis

J'ai essayé de créer mon dialogue d'alerte avec des angles arrondis, mais je n'y parviens pas. J'ai essayé et j'ai échoué. J'ai essayé de suivre ce blog http://blog.stylingandroid.com/archives/271 et j'ai créé mes styles sur cette base.

Btw, pour ajouter à ma question maintenant. Quelques unes de mes nouvelles découvertes. Le code dans le lien ci-dessus fonctionne correctement sous 2.3.3 (Go) mais ne fonctionne pas du tout dans ICS. Certains changements ont provoqué la rupture du code.

Je veux éviter de créer 9 images de patch et j'utilise donc des formes. 9 images de patch est la dernière chose que je vais essayer. Je sais que le style de dialogue d'alerte Android utilise 9 images de patch. Je l'ai déjà regardé avant de lancer cette question.

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

Mon code pour 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();
            }
        });

}

Ma sortie actuelle:

Je n'ai pas de coins arrondis. Je peux voir que c'est différent du style habituel. Même si je change de rayon sur mon dessin, les coins ne reflètent pas ces changements.

enter image description here

27
VendettaDroid

Vous pouvez le faire en utilisant le code suivant:

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>

Il suffit de changer le montant du rayon en: 

dialog_title.xml

et

dialog_footer.xml

et ça va générer le résultat suivant:

enter image description here

j'espère que ceci vous aidera.


METTRE À JOUR:
Je ne suis pas un expert mais c'est ce que j'ai trouvé. Cela peut être juste ou faux ... Après plusieurs tentatives, je me suis retrouvé avec ce qui suit:

1- ContextThemeWrapper ne s'applique pas à l'API 14, cela fonctionne très bien sur Gingerbread et les versions antérieures, mais avec l'API> 10, cela ne fonctionne pas.

2- pour surmonter le problème ci-dessus et le faire fonctionner sur API> 10 à la demande, je remplace cette ligne:

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

avec ça:

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

mais vous devez changer: 

Android:minSdkVersion="8"  

à 

Android:minSdkVersion="11" 

le résultat sera comme indiqué dans l'image suivante sur ICS (API 14):

enter image description here

Cette image provient d'un Samsung Galaxy S3 exécutant l'ICS. 

Remarque: le sdk manifeste du projet modifié lancé avec l'API 14 SO sera:

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

FINAL Word: Comme mes connaissances en développement Android (je ne suis pas un expert),

1- Le dialogue d'alerte personnalisé fonctionne sans heurts dans les API <10 mais pas> 10 avec le même code Java.

si nous voulons qu'il fonctionne dans ICS avec le même effet que dans l'API <10, nous devons modifier le code , de sorte qu'il s'exécute sur ICS mais ne s'exécute pas dans aucun version down API 11.

2- même le résultat dans ICS n'est pas satisfaisant, le coin arrondi s'applique uniquement au titre mais pas au pied de page.


DEUXIÈME MISE À JOUR: FINALEMENT, je fais tous les virages,

JUST applique padding à dialog_footer.xml comme suit:

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

Image de sortie:

enter image description here

Cette image provient d'un Samsung Galaxy S3 exécutant l'ICS.

34
androidqq6

Encore une étape de la réponse de @iDroid Explorer

ajoutez cette ligne lorsque vous construisez le dialogue

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

et cela fera disparaître le rectangle (qui est en fait transparent) et une boîte de dialogue arrondie parfaite.

18
Youtoo

J'ai essayer le même problème avec ci-dessous un et cela fonctionne pour moi. Même pour ICS également.

1. Tout d'abord, j'ai mis le thème sur mon 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. Ensuite, avez mis en œuvre la disposition personnalisée pour la vue Dialogue

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. Ajoutez maintenant une forme à l'arrière-plan de la présentation parent de pop_exit.xml

round.xml // fichier de forme

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

Je le fais juste. Cela fonctionnera pour vous également pour ICS .

J'espère que cela vous aidera. Sinon, faites le moi savoir.

Profitez de la programmation ...

:)

5
iDroid Explorer

Comme vous dites que vous ne voulez pas utiliser une image de 9 patchs, jetez un coup d’oeil ici.

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

Le principe est exactement le même, sauf que vous affectez l'arrière-plan à votre mise en page, où cet exemple correspond à une mise en page linéaire.

4
Doomsknight
  1. créer xml dans un dossier pouvant être dessiné avec 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. dans votre fichier Java, conservez le code ci-dessous

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

0
siddhartha shankar