Android 自定义按钮状态
需求描述:
最近做个项目,有一个按钮,有下载,安装,点击,安装中,下载中和使用这六个不同的状态,每个状态对应的按钮颜色也是不一样的,加上按下去的变色,大概有12种状态。
解决方案:
- 6种状态对应不一样的background,设置为不同的状态的时候,换上对应的背景。
- 自定义按钮状态
选择方案:
其实第二种和第一种的本质区别就是把所有的状态的文件写到一个xml里,但是更优雅,果断使用第二种
方案实现:
- 定义自己的状态
- 重写控件的onCreateDrawableState(int extraSpace) 告诉系统你有多少种状态
就这两个步骤,非常简单
定义自己的状态
<declare-styleable name="ColorStateButton">
<attr name="state_download" format="boolean"/>
<attr name="state_downloading" format="boolean"/>
<attr name="state_install" format="boolean"/>
<attr name="state_installing" format="boolean"/>
<attr name="state_open" format="boolean"/>
</declare-styleable>
其实我想试试可不可以直接用数字类型的,当时时间比较紧急,就没试了,有兴趣的可以试试
重写onCreateDrawableState
@Override
protected int[] onCreateDrawableState(int extraSpace) {
if (mColorStatus != null && mColorStatus.getMergeState() != null && isEnabled()) {
final int[] drawableStatus = super.onCreateDrawableState(extraSpace + mColorStatus.getMergeState().length);//告诉系统你要添加拓展的状态数量
//告诉系统你要合并的状态
mergeDrawableStates(drawableStatus, mColorStatus.getMergeState());
// printList(drawableStatus);
return drawableStatus;
}¡
return super.onCreateDrawableState(extraSpace);
}
详细代码:
按钮的background
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- 需要下载状态-->
<item
android:drawable="@drawable/ic_color_button_download_normal"
android:state_pressed="false"
app:state_download="true"/>
<item
android:drawable="@drawable/ic_color_button_download_pressed"
android:state_pressed="true"
app:state_download="true"/>
<!--需要安装状态-->
<item
android:drawable="@drawable/ic_color_button_install"
android:state_pressed="false"
app:state_install="true"/>
<item
android:drawable="@drawable/ic_color_button_install_pressed"
android:state_pressed="true"
app:state_install="true"/>
<!--按钮不可用-->
<item
android:drawable="@drawable/ic_color_button_disable"
android:state_enabled="false"/>
<item
android:drawable="@drawable/ic_color_button_normal_pressed"
android:state_pressed="true"/>
<!--正常状态-->
<item
android:drawable="@drawable/ic_color_button_normal"/>
</selector>
按钮的源码
package com.bingwish.bibao.ui.fragment;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.annotation.StringRes;
import android.util.AttributeSet;
import android.widget.Button;
import com.bingwish.bibao.R;
import com.hangox.xlog.XLog;
/**
* Created With Android Studio
* User hangox
* Date 16/1/11
* Time 下午8:58
* 下载显示按钮
*/
public class ColorStateButton extends Button {
public static final int[] STATUS_DOWNLOAD = {R.attr.state_download};
public static final int[] STATUS_INSTALL = {R.attr.state_install};
private ColorStatus mColorStatus = ColorStatus.DOWNLOAD;
public ColorStateButton(Context context) {
super(context);
init(context);
}
public ColorStateButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ColorStateButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ColorStateButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
setColorState(ColorStatus.DOWNLOAD);
}
/***
* 设置颜色类型
*
* @param colorState
*/
public void setColorState(ColorStatus colorState) {
setText(colorState.getButtonTextRes());
switch (colorState) {
case DOWNLOADING:
case INSTALLING:
setEnabled(false);
return;
}
setEnabled(true);
mColorStatus = colorState;
refreshDrawableState();
invalidate();
}
@Override
protected int[] onCreateDrawableState(int extraSpace) {
if (mColorStatus != null && mColorStatus.getMergeState() != null && isEnabled()) {
final int[] drawableStatus = super.onCreateDrawableState(extraSpace + mColorStatus.getMergeState().length);
mergeDrawableStates(drawableStatus, mColorStatus.getMergeState());
// printList(drawableStatus);
return drawableStatus;
}
return super.onCreateDrawableState(extraSpace);
}
private void printList(int[] ints) {
StringBuilder builder = new StringBuilder();
for (int state : ints) {
builder.append(state).append("#");
}
XLog.i(builder.toString());
}
public enum ColorStatus {
DOWNLOAD(STATUS_DOWNLOAD, R.string.state_download),
CLICK(STATUS_INSTALL, R.string.state_click),
OPEN(null, R.string.state_open),
DOWNLOADING(null, R.string.state_downloading),
INSTALL(STATUS_INSTALL, R.string.state_install),
INSTALLING(null, R.string.state_installing);
int[] mergeState;
@StringRes
int mButtonTextRes;
ColorStatus(int[] statusDownload, @StringRes int buttonTextRes) {
mergeState = statusDownload;
mButtonTextRes = buttonTextRes;
}
public int getButtonTextRes() {
return mButtonTextRes;
}
public int[] getMergeState() {
return mergeState;
}
}
}