一.基本使用
1、导入support:appcompat-v7包。
2、布局:
<android.support.v7.widget.SwitchCompat
android:id="@+id/switch_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is Switch" />
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
<android.support.v7.widget.SwitchCompat
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeight"
android:paddingHorizontal="16dp"
android:text="This is Switch" />
2、PrimaryText和SummaryText加Switch的Item
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeight"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="16dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Primary Text"
android:textColor="#E000"
android:textSize="16sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Summary Text"
android:textColor="#8000"
android:textSize="16sp" />
</LinearLayout>
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false" />
</LinearLayout>
这种情况下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不整齐
默认情况下,开启的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);
}
}
效果:
2、用Shape实现Thumb(不会有很明显的不整齐),
目的是给一个Drawable到DrawableUtils.getOpticalBounds()这里方法里面去,然后返回的Rect没有边距就可以了。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true">
<layer-list>
<item>
<shape android:shape="oval">
<size android:width="24dp" android:height="24dp" />
<solid android:color="#000" />
</shape>
</item>
<item android:bottom="1px">
<shape android:shape="oval">
<size android:width="24dp" android:height="24dp" />
<solid android:color="#EEE" />
</shape>
</item>
</layer-list>
</item>
<item>
<layer-list>
<item>
<shape android:shape="oval">
<size android:width="24dp" android:height="24dp" />
<solid android:color="#100" />
</shape>
</item>
<item android:bottom="1px">
<shape android:shape="oval">
<size android:width="24dp" android:height="24dp" />
<solid android:color="#F00" />
</shape>
</item>
</layer-list>
</item>
</selector>
这里使用layer-list主要是模拟阴影。
四.主题色
1、布局里面:
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:trackTint="@color/colorPrimary"
app:thumbTint="@drawable/thumb_tint_selector"/>
thumb_tint_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#F00" android:state_checked="true" />
<item android:color="#EEE" />
</selector>
2、设置Theme,通过colorControlActivated控制其开启时的颜色。
android:theme="@style/MySwitchCompatTheme"
<style name="MySwitchCompatTheme" parent="Base.Widget.AppCompat.CompoundButton.Switch">
<item name="colorControlActivated">#0FF</item>
</style>
3、Java动态修改TintList
SwitchCompat mSwitch = findViewById(R.id.switch_view);
mSwitch.setThumbTintList(ColorStateList.valueOf(Color.CYAN));
mSwitch.setTrackTintList(ColorStateList.valueOf(Color.RED));
五.背景
其实截图中这个半透明的圆形就是SwitchCompat的默认背景,它只有在按压的情况下才会显示出来,如果不需要这个默认背景这样写就可以了:
<android.support.v7.widget.SwitchCompat
android:id="@+id/switch_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null" />