본문 바로가기
안드로이드

Android's StateListDrawable and RadioButton Example

by 호군 2011. 3. 16.
반응형
링크 : http://vicfaith.blog.me/150096751750

코드상으로 StateListDrawable을 만드는 방법입니다.



A radio button on the Android platform is drawn based on a label and a set of images contained in a StateListDrawable. You can create an image radio button by setting the text label to empty and setting your own images. There is no need to override the class or implement your own.

You can create your own radio buttons either via xml declaration or via code. You can see this in the Android source code but I will describe both methods in the rest of this post.

In the Android source code, you want to have a look at the following files:
StateListDrawable.java
DrawableContainer.java

RadioButton.java
CompoundButton.java

btn_radio.xml


XML DECLARATION:
When you declare your radio button, add the tag android:button="@drawable/resize_button". In your res/drawable/ directory, you must now have a resize_button.xml file that looks like this:

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:state_window_focused="false"
android:drawable="@drawable/resize_button_on" />
<item
android:state_checked="false"
android:state_window_focused="false"
android:drawable="@drawable/resize_button_off" />
<item
android:state_checked="true"
android:state_pressed="true"
android:drawable="@drawable/resize_button_on_pressed" />
<item
android:state_checked="false"
android:state_pressed="true"
android:drawable="@drawable/resize_button_off_pressed" />
<item
android:state_checked="true"
android:state_focused="true"
android:drawable="@drawable/resize_button_on_selected" />
<item
android:state_checked="false"
android:state_focused="true"
android:drawable="@drawable/resize_button_off_selected" />
<item
android:state_checked="true"
android:drawable="@drawable/resize_button_on" />
<item
android:state_checked="false"
android:drawable="@drawable/resize_button_off" />
</selector>


The order of these items seems to matter, but I haven't had the time to delve into the details. It looks like it's caused by the matching algorithm that picks a drawable from the list based on the current state. You'll notice that each image that represents a radio button state has one or more state values associated with it. The radio button class sets the state flags and the Drawable picks the best matching image to display.

By declaring the xml code just shown, I now have a graphical resize radio button that can be checked off. It won't have a label and it will have it's own icon with the usual radio button states.

VIA CODE:

 StateListDrawable drawables = new StateListDrawable();
int stateChecked = android.R.attr.state_checked;
int stateFocused = android.R.attr.state_focused;
int statePressed = android.R.attr.state_pressed;
int stateWindowFocused = android.R.attr.state_window_focused;
drawables.addState(new int[]{ stateChecked, -stateWindowFocused}, getButtonWithThumbnail(R.drawable.button_on , thumbnailBitmap));
drawables.addState(new int[]{-stateChecked, -stateWindowFocused}, getButtonWithThumbnail(R.drawable.button_off , thumbnailBitmap));
drawables.addState(new int[]{ stateChecked, statePressed }, getButtonWithThumbnail(R.drawable.button_on_pressed , thumbnailBitmap));
drawables.addState(new int[]{-stateChecked, statePressed }, getButtonWithThumbnail(R.drawable.button_off_pressed , thumbnailBitmap));
drawables.addState(new int[]{ stateChecked, stateFocused }, getButtonWithThumbnail(R.drawable.button_on_selected , thumbnailBitmap));
drawables.addState(new int[]{-stateChecked, stateFocused }, getButtonWithThumbnail(R.drawable.button_off_selected, thumbnailBitmap));
drawables.addState(new int[]{ stateChecked }, getButtonWithThumbnail(R.drawable.button_on , thumbnailBitmap));
drawables.addState(new int[]{-stateChecked }, getButtonWithThumbnail(R.drawable.button_off , thumbnailBitmap));
thumbnailBitmap.recycle();
thumbnailBitmap = null;
thumbnailButton.setButtonDrawable(drawables);
thumbnailButton.setId(viewId);
layerThumbnails.addView(thumbnailButton);
layerThumbnails.check(thumbnailButton.getId());


The selector tag in the xml file corresponds to the StateListDrawable class. Items are added with addState(). Here, I've copied the basic button drawables from android's jar file, such as R.drawable.button_off and R.drawable.button_off_pressed. I created my own function, getButtonWithThumbnail(), that takes a bitmap and combines it with the basic button image to create a custom radio button on the fly.

Notice that the true and false values of the states are specified in code using positive and negative values of the android.R.attr.state_<*> integer variables and the order in which the images are added to the drawable is the same as in the xml declaration earlier. Finally, I add the StateListDrawable to my radio button, give it an id, add it to a radio group, and simulate a click on the button by calling the check() function on the button's radio group.


반응형