Android SwitchCompat详解

一.基本使用

1、导入support:appcompat-v7包。
2、布局:


3、设置监听

final SwitchCompat mSwitch = findViewById(R.id.switch_view);
mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    }
});

4、Thumb和Track
Thumb是Switch的手指触摸的Drawable,Track是Switch的轨迹Drawable。

二.属性介绍

1、app:switchPadding:Switch与文字之间的距离。
2、app:splitTrack="":true表示Switch的Thumb和Track会分隔开来,false则不会分割,默认false。
3、android:thumb="":设置一个Thumb图,默认是v7包里面的abc_switch_thumb_material.xml Drawable资源,可以通过getThumbDrawable()获取这个Drawable对象,并且这是一个StateListDrawable。
4、app:track="":设置一个Track图,默认是v7包里面的abc_switch_track_mtrl_alpha.9.png 资源文件,
5、app:thumbTint="":给Thumb着色,传一个颜色值或者ColorStateList。
6、app:thumbTintMode="":给Thumb着色时的颜色叠加方式,参考PorterDuff.Mode。
7、 app:trackTint=""和app:trackTintMode=""的使用与Thumb类似。
8、下面属性可以搭配着使用:
app:showText="true":在Thumb上面展示文字,默认是on和off;
app:thumbTextPadding="8dp":Thumb上文字的边距;
android:textOff="Off":关闭时的文字;
android:textOn="On":打开时的文字;
app:switchTextAppearance="@style/TextAppearance.AppCompat.Body1":设置文字的字体样式。
9、app:switchMinWidth="100dp":设置Switch的最小宽度,其效果和android:minWidth=""完全不同,android:minWidth=""设置的是View的最小宽度,switchMinWidth设置的是Track所在区域的宽度。

三.放在Item中使用

1、单条文字加Switch的Item


device-2019-12-07-213926.png

2、PrimaryText和SummaryText加Switch的Item


device-2019-12-07-215342.png


        

            

            

        

        
    

这种情况下Item 的点击事件不用设置给Switch,需要设置给Item,点击Item 之后通过Switch的toggle()方法改变它的状态。

findViewById(R.id.list_item0).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SwitchCompat mSwitch = v.findViewById(R.id.switch_view);
        mSwitch.toggle();
    }
});

3、Switch不整齐


device-2019-12-07-220559.png

默认情况下,开启的Switch和关闭的Switch并不是整齐的在一条数直线上面,往往在开发过程中需要对齐显示(由于这个问题好几次设计师要求我更改成对齐的),但是Android却没有提供出设置对齐的API。
查看SwitchCompat的源码会发现有DrawableUtils.getOpticalBounds个方法,在draw方法里面通过DrawableUtils.getOpticalBounds拿到一个Rect,在设置TrackDrawable边距的时候使用了这个Rect。

@Override
    public void draw(Canvas c) {
        final Rect padding = mTempRect;
        final int switchLeft = mSwitchLeft;
        final int switchTop = mSwitchTop;
        final int switchRight = mSwitchRight;
        final int switchBottom = mSwitchBottom;

        int thumbInitialLeft = switchLeft + getThumbOffset();

        final Rect thumbInsets;
        if (mThumbDrawable != null) {
            thumbInsets = DrawableUtils.getOpticalBounds(mThumbDrawable);
        } else {
            thumbInsets = DrawableUtils.INSETS_NONE;
        }

        // Layout the track.
        if (mTrackDrawable != null) {
            mTrackDrawable.getPadding(padding);

            // Adjust thumb position for track padding.
            thumbInitialLeft += padding.left;

            // If necessary, offset by the optical insets of the thumb asset.
            int trackLeft = switchLeft;
            int trackTop = switchTop;
            int trackRight = switchRight;
            int trackBottom = switchBottom;
            if (thumbInsets != null) {
                if (thumbInsets.left > padding.left) {
                    trackLeft += thumbInsets.left - padding.left;
                }
                if (thumbInsets.top > padding.top) {
                    trackTop += thumbInsets.top - padding.top;
                }
                if (thumbInsets.right > padding.right) {
                    trackRight -= thumbInsets.right - padding.right;
                }
                if (thumbInsets.bottom > padding.bottom) {
                    trackBottom -= thumbInsets.bottom - padding.bottom;
                }
            }
            mTrackDrawable.setBounds(trackLeft, trackTop, trackRight, trackBottom);
        }

        // Layout the thumb.
        if (mThumbDrawable != null) {
            mThumbDrawable.getPadding(padding);

            final int thumbLeft = thumbInitialLeft - padding.left;
            final int thumbRight = thumbInitialLeft + mThumbWidth + padding.right;
            mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);

            final Drawable background = getBackground();
            if (background != null) {
                DrawableCompat.setHotspotBounds(background, thumbLeft, switchTop,
                        thumbRight, switchBottom);
            }
        }

        // Draw the background.
        super.draw(c);
    }

这里提供两种思路去解决:
1、继承SwitchCompat并重写onDraw方法,在super.onDraw(canvas);之前修改TrackDrawable的Bounds。

public class MySwitch extends SwitchCompat {
    public MySwitch(Context context) {
        super(context);
    }

    public MySwitch(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable trackDrawable = getTrackDrawable();
        Rect bounds = trackDrawable.getBounds();
        trackDrawable.setBounds(getPaddingLeft(), bounds.top, getWidth() - getPaddingRight(), bounds.bottom);
        super.onDraw(canvas);
    }
}

效果:


device-2019-12-07-222447.png

2、用Shape实现Thumb(不会有很明显的不整齐),
目的是给一个Drawable到DrawableUtils.getOpticalBounds()这里方法里面去,然后返回的Rect没有边距就可以了。



    
        
            
                
                    
                    
                
            

            
                
                    
                    
                
            
        
    
    
        
            
                
                    
                    
                
            

            
                
                    
                    
                
            
        
    

这里使用layer-list主要是模拟阴影。

四.主题色

1、布局里面:


thumb_tint_selector:



    
    

2、设置Theme,通过colorControlActivated控制其开启时的颜色。
android:theme="@style/MySwitchCompatTheme"


3、Java动态修改TintList

SwitchCompat mSwitch = findViewById(R.id.switch_view);
mSwitch.setThumbTintList(ColorStateList.valueOf(Color.CYAN));
mSwitch.setTrackTintList(ColorStateList.valueOf(Color.RED));

五.背景

device-2019-12-07-232258.png

其实截图中这个半透明的圆形就是SwitchCompat的默认背景,它只有在按压的情况下才会显示出来,如果不需要这个默认背景这样写就可以了:


你可能感兴趣的:(Android SwitchCompat详解)