最近项目中需要到自定义的switch控件,但是google原生的switch空间不符合客户的需求,客户要求仿OPPO的switch样式,因此自己查资料做了一个,基本功能与原生无差别,样式可根据自身的实际需求做修改
修改Switch的主要思想是:1. Switch中含有高版本SDK代码,需要去掉或者改写这样的代码 2. Switch对应declare-styleable属性声明应该在Android SDK安装目录中找到对应的源码声明片段,基本上copy过来就行了。所在路径:\Android\android-sdk\platforms\android-17\data\res
修改后的MySwitch控件接口基本与原Switch控件一致,并且除了可支持所有SDK外,增加了2项小功能:
1. 支持用Track背景图片的方式代替Texton Textoff等文字方式表现开关状态
2.支持调整控制Switch的高度
下面贴出Switch修改的关键代码:
1.MySwitch.java
package com.test.wison;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.widget.CompoundButton;
import android.widget.Switch;
/**
* A Switch is a two-state toggle switch widget that can select between two
* options. The user may drag the "thumb" back and forth to choose the selected option,
* or simply tap to toggle as if it were a checkbox. The {@link #setText(CharSequence) text}
* property controls the text displayed in the label for the switch, whereas the
* {@link #setTextOff(CharSequence) off} and {@link #setTextOn(CharSequence) on} text
* controls the text on the thumb. Similarly, the
* {@link #setTextAppearance(android.content.Context, int) textAppearance} and the related
* setTypeface() methods control the typeface and style of label text, whereas the
* {@link #setSwitchTextAppearance(android.content.Context, int) switchTextAppearance} and
* the related seSwitchTypeface() methods control that of the thumb.
*
* <p>
* modified from android SDK 14(4.0) android.widget.Switch.
* <br/>
* <strong>new feature: </strong>
* <ol>
* <li>support SDK 1 or higher. </li>
* <li>you can use track drawable instead of text to display the changes of off-on state!</li>
* <li>you can control the Switch minimum height. </li>
* </ol>
* </p>
*
* @see {@link Switch}
* @author Wison
*/
public class MySwitch extends CompoundButton {
private static final int TOUCH_MODE_IDLE = 0;
private static final int TOUCH_MODE_DOWN = 1;
private static final int TOUCH_MODE_DRAGGING = 2;
// Support track drawable instead of text
private Drawable mTrackOnDrawable;
private Drawable mTrackOffDrawable;
// Enum for the "typeface" XML parameter.
private static final int SANS = 1;
private static final int SERIF = 2;
private static final int MONOSPACE = 3;
private Drawable mThumbDrawable;
private Drawable mTrackDrawable;
private int mThumbTextPadding;
private int mSwitchMinWidth;
// Support minimum height
private int mSwitchMinHeight;
private int mSwitchPadding;
private CharSequence mTextOn;
private CharSequence mTextOff;
private int mTouchMode;
private int mTouchSlop;
private float mTouchX;
private float mTouchY;
@SuppressLint("Recycle")
private VelocityTracker mVelocityTracker = VelocityTracker.obtain();
private int mMinFlingVelocity;
private float mThumbPosition;
private int mSwitchWidth;
private int mSwitchHeight;
private int mThumbWidth; // Does not include padding
private int mSwitchLeft;
private int mSwitchTop;
private int mSwitchRight;
private int mSwitchBottom;
private TextPaint mTextPaint;
private ColorStateList mTextColors;
private Layout mOnLayout;
private Layout mOffLayout;
// @SuppressWarnings("hiding")
private final Rect mTempRect = new Rect();
private static final int[] CHECKED_STATE_SET = {
android.R.attr.state_checked
};
/**
* Construct a new Switch with default styling.
*
* @param context The Context that will determine this widget's theming.
*/
public MySwitch(Context context) {
this(context, null);
}
/**
* Construct a new Switch with default styling, overriding specific style
* attributes as requested.
*
* @param context The Context that will determine this widget's theming.
* @param attrs Specification of attributes that should deviate from default styling.
*/
public MySwitch(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.switchStyle);
}
/**
* Construct a new Switch with a default style determined by the given theme attribute,
* overriding specific style attributes as requested.
*
* @param context The Context that will determine this widget's theming.
* @param attrs Specification of attributes that should deviate from the default styling.
* @param defStyle An attribute ID within the active theme containing a reference to the
* default style for this widget. e.g. android.R.attr.switchStyle.
*/
public MySwitch(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
Resources res = getResources();
mTextPaint.density = res.getDisplayMetrics().density;
//float scaledDensity = res.getDisplayMetrics().scaledDensity;
//mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Switch, defStyle, 0);
// off-on 模式�?图片模式或文字模式,图片模式是用Track背景图片表示off-on的状态,文字模式是用文字来表示off-on状�?�?
mTrackOnDrawable = a.getDrawable(R.styleable.Switch_trackOn);
mTrackOffDrawable = a.getDrawable(R.styleable.Switch_trackOff);
if (checkTrackOffOnDrawable()) {
// 如果设定图片模式,则默认显示off状�?
mTrackDrawable = mTrackOffDrawable;
} else {
mTrackDrawable = a.getDrawable(R.styleable.Switch_track);
}
mThumbDrawable = a.getDrawable(R.styleable.Switch_thumb);
mTextOn = a.getText(R.styleable.Switch_textOn);
mTextOff = a.getText(R.styleable.Switch_textOff);
mThumbTextPadding = a.getDimensionPixelSize(R.styleable.Switch_thumbTextPadding, 0);
mSwitchMinWidth = a.getDimensionPixelSize(R.styleable.Switch_switchMinWidth, 0);
android之自定义switch
最新推荐文章于 2024-04-28 17:13:46 发布
本文介绍了如何在Android中自定义Switch控件MySwitch,它不仅支持所有SDK,还新增了两个特性:使用Track背景图片展示开关状态和调整Switch高度。关键代码包括对MySwitch的构造函数和触摸事件的处理,以及布局和绘制方法的重写,以实现自定义功能。
摘要由CSDN通过智能技术生成