2010年12月27日月曜日

Android AlertDialog の背景を変更する

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

android:alertDialogStyle

を設定します。

res/values/styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="@android:style/Theme.Black">
<item name="android:alertDialogStyle">@style/AlertDialog</item>
</style>

<style name="AlertDialog">
<item name="android:fullBright">@android:color/transparent</item>
<item name="android:fullDark">@android:color/transparent</item>
<item name="android:topBright">@color/basic_blue1</item>
<item name="android:topDark">@color/basic_blue1</item>
<item name="android:centerBright">@color/basic_blue2</item>
<item name="android:centerDark">@color/basic_blue2</item>
<item name="android:centerMedium">@color/basic_blue2</item>
<item name="android:bottomBright">@color/basic_blue3</item>
<item name="android:bottomDark">@color/basic_blue3</item>
<item name="android:bottomMedium">@color/basic_blue3</item>
</style>
</resources>


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


res/values/colors.xml

<resources>
<color name="basic_blue1">#5781a9</color>
<color name="basic_blue2">#a4bcc6</color>
<color name="basic_blue3">#995781a9</color>
<color name="basic_orange1">#99eca14f</color>
<color name="basic_orange2">#66eca14f</color>
<color name="basic_white1">#eeffffff</color>
<color name="basic_white2">#99ffffff</color>
</resources>



@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("dialog");
builder.setMessage("test!");
builder.setPositiveButton("OK", null);
builder.show();
}






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


package yanzm.example.alertdialogsample;

import android.app.AlertDialog;
import android.content.Context;

public class MyAlertDialog extends AlertDialog {

public MyAlertDialog(Context context) {
super(context);
}

public MyAlertDialog(Context context, int theme) {
super(context, theme);
}
}



package yanzm.example.alertdialogsample;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.View;

public class MyActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);
}

// AlertDialog.Builder を使う普通の方法
public void showNormalAlertDialog(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("dialog");
builder.setMessage("test!");
builder.setPositiveButton("OK", null);
builder.show();
}

// 独自ダイアログをつかってテーマを指定
public void showMyDialog(View v) {
MyAlertDialog myDialog = new MyAlertDialog(this, R.style.MyDialog);
myDialog.setTitle("dialog");
myDialog.setMessage("test!");
myDialog.setButton("OK", (OnClickListener)null);
myDialog.show();
}
}



res/values/styles.xml

<style name="MyDialog" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@drawable/rect</item>
</style>


res/drawable/rect.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/white" />
<stroke
android:width="5dip"
android:color="@color/basic_blue1"
android:dashWidth="5dip"
android:dashGap="5dip" />
</shape>



showMyDialog



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

res/values/styles.xml

<style name="MyDialog" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@drawable/rect</item>
<item name="android:buttonStyle">@style/CustomButton</item>
</style>

<style name="CustomButton" parent="@android:style/Widget.Button">
<item name="android:background">@drawable/button_stateful</item>
</style>


res/drawable/button_stateful.xml

<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="@android:color/transparent" />
</shape>
</item>
<item android:top="5dip" android:bottom="8dip" android:left="5dip"
android:right="5dip">
<selector>
<item android:state_pressed="true">
<shape>
<gradient android:startColor="@color/basic_orange1"
android:endColor="@color/basic_white1" android:angle="90" />
<corners android:radius="10dip" />
<stroke android:width="2dip" android:color="@color/basic_blue1" />
<padding android:left="15dip" android:top="15dip"
android:right="15dip" android:bottom="15dip" />
</shape>
</item>
<item android:state_focused="true">
<shape>
<gradient android:startColor="@color/basic_orange2"
android:endColor="@color/basic_white1" android:angle="90" />
<corners android:radius="10dip" />
<stroke android:width="2dip" android:color="@color/basic_blue1" />
<padding android:left="15dip" android:top="15dip"
android:right="15dip" android:bottom="15dip" />
</shape>
</item>
<item>
<shape>
<gradient android:startColor="@color/basic_white2"
android:endColor="@color/basic_white1" android:angle="90" />
<corners android:radius="10dip" />
<stroke android:width="2dip" android:color="@color/basic_blue1" />
<padding android:left="15dip" android:top="15dip"
android:right="15dip" android:bottom="15dip" />
</shape>
</item>
</selector>
</item>
</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. すみません・・自己解決しましたぁ^^;

    返信削除