Android代码实现状态选择器

为了体现更好的用户体验,改变以往的在drawable目录下创建不同的selector.xml文件,减少apk包的体积,提高代码的复用性,所以java代码更适合一些。
/**
 *@author jiangrongtao
 * 
 *csdn:http://blog.csdn.net/jiang_rong_tao
 * 
 *github:https://github.com/jiangrongtao/jiangrongtao.github.io
 *
 * created at 2016/6/2 11:15
*/

public class TintDrawableUtils {
    /**
     * 获取Drawable资源
     * @param drawable
     * @param color
     * @return
     */
    public static Drawable getTintDrawable(Drawable drawable, @ColorInt int color) {
        Drawable.ConstantState state = drawable.getConstantState();
        Drawable drawable1 = DrawableCompat.wrap(state == null ? drawable : state.newDrawable()).mutate();
        drawable1.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        DrawableCompat.setTint(drawable1, color);
        return drawable1;
    }
    /**
     * 获取一个设置了选择器的状态列表
     * @param drawable
     * @param colors
     * @param states
     * @return
     */
    public static Drawable getStateDrawable(Drawable drawable, int[] colors, int[][] states) {
        ColorStateList colorList = new ColorStateList(states, colors);
        Drawable.ConstantState state = drawable.getConstantState();
        drawable = DrawableCompat.wrap(state == null ? drawable : state.newDrawable()).mutate();
        DrawableCompat.setTintList(drawable,colorList);
        return drawable;
    }

    /**
     * 获取状态列表
     * @param drawable
     * @param states
     * @return
     */
    @NonNull
    public static StateListDrawable getStateListDrawable(Drawable drawable, int[][] states) {
        StateListDrawable stateListDrawable = new StateListDrawable();
        for (int[] state:states) {
            stateListDrawable.addState(state,drawable);
        }
        return stateListDrawable;
    }
}

具体用法如下:
布局文件


<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"
    tools:context="com.rongtao.smartselector.MainActivity">
    <ImageView
        android:id="@+id/iv_image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:clickable="true"
        android:layout_centerInParent="true"
        />
RelativeLayout>

java文件:

  private void init() {
   mImageView = (ImageView)findViewById(R.id.iv_image);
   //一个存放颜色的数组
 int[] colors =
   new int[] { ContextCompat.getColor(this,R.color.icon_pre),
        ContextCompat.getColor(this,R.color.icon_nor)};
 //选择状态的二维数组
        int[][] states = new int[2][];
        states[0] = new int[] { android.R.attr.state_pressed};
        states[1] = new int[] {};//表示正常状态
 //获取Drawable资源,只要一张图片资源my_nor
Drawable drawable = ContextCompat
                    .getDrawable(this,R.mipmap.my_nor);

 //获取状态列表
StateListDrawable stateListDrawable =TintDrawableUtils.getStateListDrawable(drawable, states);
        Drawable drawable3 = TintDrawableUtils.getStateDrawable(stateListDrawable, colors, states);
        //设置选择器
        mImageView.setImageDrawable(drawable3);
    这里用到了一个类ContextCompat,其实就是为了兼容低版本而已,这个类源码只有455行,我们可以看一下源码就明白它是干什么的了.

Android代码实现状态选择器_第1张图片
Android代码实现状态选择器_第2张图片
Android代码实现状态选择器_第3张图片
这样我们就可以放心的使用了,不怕出现版本兼容问题了。

总结:其实在我们真正的开发中,一旦整个app的主题需求定了以后,我们的上面的类可以进行进一步的封装处理,一般为了统一都是normal状态和pressed颜色一致,所以只要在color.xml将这两个颜色配置一下,然后全局使用。减少原来UI要切两种状态图的麻烦,减少了drawable目录下selector.xml文件的书写,优化了app的体积。

你可能感兴趣的:(android)