2010年12月27日月曜日

Android AlertDialog の背景を変更する

ダイアログの背景(タイトル、メッセージ、ボタン部分で色が変わっているところ)を変更するには、

android:alertDialogStyle

を設定します。

res/values/styles.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <style name="MyTheme" parent="@android:style/Theme.Black">  
  4.         <item name="android:alertDialogStyle">@style/AlertDialog</item>  
  5.     </style>  
  6.   
  7.     <style name="AlertDialog">  
  8.         <item name="android:fullBright">@android:color/transparent</item>  
  9.         <item name="android:fullDark">@android:color/transparent</item>  
  10.         <item name="android:topBright">@color/basic_blue1</item>  
  11.         <item name="android:topDark">@color/basic_blue1</item>  
  12.         <item name="android:centerBright">@color/basic_blue2</item>  
  13.         <item name="android:centerDark">@color/basic_blue2</item>  
  14.         <item name="android:centerMedium">@color/basic_blue2</item>  
  15.         <item name="android:bottomBright">@color/basic_blue3</item>  
  16.         <item name="android:bottomDark">@color/basic_blue3</item>  
  17.         <item name="android:bottomMedium">@color/basic_blue3</item>  
  18.     </style>  
  19. </resources>  


AndroidManifest.xml の application タグや activity タグで android:theme="@style/MyTheme" を設定する


res/values/colors.xml
  1. <resources>  
  2.     <color name="basic_blue1">#5781a9</color>  
  3.     <color name="basic_blue2">#a4bcc6</color>  
  4.     <color name="basic_blue3">#995781a9</color>  
  5.     <color name="basic_orange1">#99eca14f</color>  
  6.     <color name="basic_orange2">#66eca14f</color>  
  7.     <color name="basic_white1">#eeffffff</color>  
  8.     <color name="basic_white2">#99ffffff</color>  
  9. </resources>  


  1. @Override  
  2. public void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.   
  5.     setContentView(R.layout.main);  
  6.   
  7.     AlertDialog.Builder builder = new AlertDialog.Builder(this);  
  8.   
  9.     builder.setTitle("dialog");  
  10.     builder.setMessage("test!");  
  11.     builder.setPositiveButton("OK"null);  
  12.     builder.show();  
  13. }  






全体を1つの背景にしたい場合、AlertDialog.Builder クラスには theme を指定する方法がないので、(下記のリンクメモにあるように、master ブランチには theme 付のコンストラクタがあるんだけどなぁ。。。)AlertDialog を extends した独自ダイアログをつくります。

  1. package yanzm.example.alertdialogsample;  
  2.   
  3. import android.app.AlertDialog;  
  4. import android.content.Context;  
  5.   
  6. public class MyAlertDialog extends AlertDialog {  
  7.   
  8.  public MyAlertDialog(Context context) {  
  9.   super(context);  
  10.  }  
  11.    
  12.  public MyAlertDialog(Context context, int theme) {  
  13.   super(context, theme);  
  14.  }  
  15. }  


  1. package yanzm.example.alertdialogsample;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.AlertDialog;  
  5. import android.content.DialogInterface.OnClickListener;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8.   
  9. public class MyActivity extends Activity {  
  10.   
  11.  @Override  
  12.     public void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.     
  15.         setContentView(R.layout.main);  
  16.     }  
  17.       
  18.     // AlertDialog.Builder を使う普通の方法  
  19.     public void showNormalAlertDialog(View v) {  
  20.         AlertDialog.Builder builder = new AlertDialog.Builder(this);  
  21.   
  22.         builder.setTitle("dialog");  
  23.         builder.setMessage("test!");  
  24.         builder.setPositiveButton("OK"null);  
  25.         builder.show();  
  26.     }  
  27.       
  28.     // 独自ダイアログをつかってテーマを指定  
  29.     public void showMyDialog(View v) {  
  30.         MyAlertDialog myDialog = new MyAlertDialog(this, R.style.MyDialog);  
  31.         myDialog.setTitle("dialog");  
  32.         myDialog.setMessage("test!");  
  33.         myDialog.setButton("OK", (OnClickListener)null);  
  34.         myDialog.show();  
  35.     }  
  36. }  



res/values/styles.xml
  1. <style name="MyDialog" parent="@android:style/Theme.Dialog">  
  2.     <item name="android:windowBackground">@drawable/rect</item>  
  3. </style>  


res/drawable/rect.xml
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:shape="rectangle">  
  4.     <solid android:color="@android:color/white" />  
  5.     <stroke   
  6.         android:width="5dip"   
  7.         android:color="@color/basic_blue1"  
  8.         android:dashWidth="5dip"   
  9.         android:dashGap="5dip" />  
  10. </shape>  



showMyDialog



ついでに、ボタンをカスタマイズするには、独自ダイアログのコンストラクタで渡すスタイルで android:buttonStyle を設定します。

res/values/styles.xml
  1. <style name="MyDialog" parent="@android:style/Theme.Dialog">  
  2.     <item name="android:windowBackground">@drawable/rect</item>  
  3.     <item name="android:buttonStyle">@style/CustomButton</item>  
  4. </style>  
  5.   
  6. <style name="CustomButton" parent="@android:style/Widget.Button">  
  7.     <item name="android:background">@drawable/button_stateful</item>  
  8. </style>  


res/drawable/button_stateful.xml
  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android">  
  3.  <item>  
  4.   <shape>  
  5.    <solid android:color="@android:color/transparent" />  
  6.   </shape>  
  7.  </item>  
  8.  <item android:top="5dip" android:bottom="8dip" android:left="5dip"  
  9.   android:right="5dip">  
  10.   <selector>  
  11.    <item android:state_pressed="true">  
  12.     <shape>  
  13.      <gradient android:startColor="@color/basic_orange1"  
  14.       android:endColor="@color/basic_white1" android:angle="90" />  
  15.      <corners android:radius="10dip" />  
  16.      <stroke android:width="2dip" android:color="@color/basic_blue1" />  
  17.      <padding android:left="15dip" android:top="15dip"  
  18.       android:right="15dip" android:bottom="15dip" />  
  19.     </shape>  
  20.    </item>  
  21.    <item android:state_focused="true">  
  22.     <shape>  
  23.      <gradient android:startColor="@color/basic_orange2"  
  24.       android:endColor="@color/basic_white1" android:angle="90" />  
  25.      <corners android:radius="10dip" />  
  26.      <stroke android:width="2dip" android:color="@color/basic_blue1" />  
  27.      <padding android:left="15dip" android:top="15dip"  
  28.       android:right="15dip" android:bottom="15dip" />  
  29.     </shape>  
  30.    </item>  
  31.    <item>  
  32.     <shape>  
  33.      <gradient android:startColor="@color/basic_white2"  
  34.       android:endColor="@color/basic_white1" android:angle="90" />  
  35.      <corners android:radius="10dip" />  
  36.      <stroke android:width="2dip" android:color="@color/basic_blue1" />  
  37.      <padding android:left="15dip" android:top="15dip"  
  38.       android:right="15dip" android:bottom="15dip" />  
  39.     </shape>  
  40.    </item>  
  41.   </selector>  
  42.  </item>  
  43. </layer-list>  


でーきた!







■リンクめも

 ・AlertController.java

setBackground() メソッドで

537 private void setBackground(LinearLayout topPanel, LinearLayout contentPanel,
538 View customPanel, boolean hasButtons, TypedArray a, boolean hasTitle,
539 View buttonPanel) {
540
541 /* Get all the different background required */
542 int fullDark = a.getResourceId(
543 R.styleable.AlertDialog_fullDark, R.drawable.popup_full_dark);
544 int topDark = a.getResourceId(
545 R.styleable.AlertDialog_topDark, R.drawable.popup_top_dark);
546 int centerDark = a.getResourceId(
547 R.styleable.AlertDialog_centerDark, R.drawable.popup_center_dark);
548 int bottomDark = a.getResourceId(
549 R.styleable.AlertDialog_bottomDark, R.drawable.popup_bottom_dark);
550 int fullBright = a.getResourceId(
551 R.styleable.AlertDialog_fullBright, R.drawable.popup_full_bright);
552 int topBright = a.getResourceId(
553 R.styleable.AlertDialog_topBright, R.drawable.popup_top_bright);
554 int centerBright = a.getResourceId(
555 R.styleable.AlertDialog_centerBright, R.drawable.popup_center_bright);
556 int bottomBright = a.getResourceId(
557 R.styleable.AlertDialog_bottomBright, R.drawable.popup_bottom_bright);
558 int bottomMedium = a.getResourceId(
559 R.styleable.AlertDialog_bottomMedium, R.drawable.popup_bottom_medium);


 ・AlertDialog.java

 ここ(master)には、theme を第2引数にもつコンストラクタがあるのに...

 ・http://code.google.com/p/android/issues/detail?id=6278

 なんか関連ありそうな issue

 ・attrs.xml

 AlertDialog っていう styleable がある

 ・styles.xml

 ・themes.xml

  ダイアログのスタイルを設定している

 ・AlertDialog の styleable

 ・obtainStyledAttributes

 ・ContextThemeWrappter


 

2 件のコメント:

  1. いつも参考にさせて貰っています。

    アラートダイアログのテーマの変更なのですが、
    3.0以上になると外枠は変わるのですが、内側が変更されないようです。

    2.xと3.x以上の共通で出来る変更方法ご存じないでしょうか?

    返信削除
  2. すみません・・自己解決しましたぁ^^;

    返信削除