Androidでボタンの色を動的に変更する
Androidでボタンの背景をShapeで作って、その色をコードから動的に変化させるためのメモです。
ボタンをおした時やフォーカスが当たった時の変化に対応しています。
1. 全体のレイアウト
適当にボタンを作っただけです。 android:background=”@drawable/button_background”でボタンの背景を指定しています。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_background"
android:text="Button1"/>
</RelativeLayout>
2. ボタンの背景用Shape
ボタンが押されたとき、フォーカスがあるとき、ボタンが押されていないときの順番で定義しています。順番は次の手順で必要になります。
1.で設定したファイル名に合わせて、drawableの直下にbutton_background.xmlというファイル名で作成しています。
初期の色は適当です。それぞれの状態ごとに本体部分の色と枠線の色を定義しています。
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- ボタンが押されたときの定義 -->
<item android:state_pressed="true">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#0000FF"/>
<stroke
android:width="1dp"
android:color="#00FF00"/>
<corners
android:radius="5dp"/>
</shape>
</item>
<!-- フォーカスがあるときの定義 -->
<item android:state_focused="true">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#FF0000"/>
<stroke
android:width="1dp"
android:color="#00FF00"/>
<corners
android:radius="5dp"/>
</shape>
</item>
<!-- ボタンが押されていないときの定義 -->
<item android:state_pressed="false">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#FF0000"/>
<stroke
android:width="1dp"
android:color="#FF0000"/>
<corners
android:radius="5dp"/>
/>
</shape>
</item>
</selector>
3. ボタンの色を変更するコード
pushedDrawable,focusedDrawable,unselectedDrawableが状態ごとの背景です。Shapeを定義した順番で取得できます。
GradientDrawable.setStroke()で枠線の太さと色を、GradientDrawable.setColor()で本体部分の色を変更しています。
Button button = (Button) findViewById(R.id.button1);
StateListDrawable background = (StateListDrawable) button.getBackground();
DrawableContainer.DrawableContainerState containerStateDrawable = (DrawableContainer.DrawableContainerState) background
.getConstantState();
Drawable[] children = containerStateDrawable.getChildren();
GradientDrawable pushedDrawable = (GradientDrawable) children[0];
GradientDrawable focusedDrawable = (GradientDrawable) children[1];
GradientDrawable unselectedDrawable = (GradientDrawable) children[2];
pushedDrawable.setColor(Color.GRAY);
pushedDrawable.setStroke(10, Color.CYAN);
focusedDrawable.setColor(Color.CYAN);
focusedDrawable.setStroke(10,Color.GRAY);
unselectedDrawable.setColor(Color.MAGENTA);
unselectedDrawable.setStroke(10, Color.YELLOW);
getBackground()でDrawableを変数に取得して、変数の中身を探すという方法で調べたので、すごく時間がかかりました。
調べ終わってから検索して以下のページを見つけました。全て書いてあります。
How can I change colors in my StateListDrawable? - stackOverflow
http://stackoverflow.com/questions/19864337/how-can-i-change-colors-in-my-statelistdrawable
Written with StackEdit.