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.