import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.LinearLayout; import android.widget.Scroller; import com.fans.framework.utils.ViewUtils; import com.fans.momhelpers.R; /** * 选项 * <p/> *声明 R.dimen.wXX 这种类型的是一个dp数字。这种是一种实时的适配方式 * */ public class SwitchView extends ViewGroup implements View.OnTouchListener { private LinearLayout scrollView;// 滑块 private int scrollWidth = 0; private Scroller scroller; private boolean checked = false; private View switchView; private int maskWidth; private Animation gone = AnimationUtils.loadAnimation(getContext(), R.anim.alpha_gone); private Animation show = AnimationUtils.loadAnimation(getContext(), R.anim.alpha_show); private OnCheckedChangedListener onCheckedChangedListener;// 监听选择变化 private View bgView; public SwitchView(Context context, AttributeSet attrs) { super(context, attrs); init(); switchView.setBackgroundResource(R.drawable.switch_mask); maskWidth=(int) getResources().getDimension(R.dimen.w65); int checkedBg = R.drawable.switch_open; int normalBg = R.drawable.switch_close; setBackgroundResource(normalBg); Animation anim = new AlphaAnimation(0, 0); anim.setDuration(0); anim.setFillAfter(true); bgView.startAnimation(anim); bgView.setBackgroundResource(checkedBg); } /** * 初始化 */ private void init() { addView(); scroller = new Scroller(getContext()); scrollView.setOnTouchListener(this); show.setDuration(250); show.setFillAfter(true); gone.setDuration(250); gone.setFillAfter(true); } private int lastX = 0; private int marginLeft = 0;// 按压点距离左边的距离 private long lastTime = 0; @Override public boolean onTouch(View view, MotionEvent motionEvent) { int x = (int) motionEvent.getX(); switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: if (lastX == 0) lastX = x; if (marginLeft == 0) marginLeft = x + scrollView.getScrollX(); lastTime = System.currentTimeMillis(); break; case MotionEvent.ACTION_MOVE: int moveX = marginLeft - x; if (moveX > 0) scrollView.scrollTo(0, 0); else if (moveX < -scrollWidth) scrollView.scrollTo(-scrollWidth, 0); else scrollView.scrollTo(moveX, 0); lastX = x; break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: marginLeft = 0; if (System.currentTimeMillis() - lastTime <= 100) { if (checked) close(); else open(); onCheckedChanged(); return true; } int center = scrollWidth / 2 - scrollView.getScrollX();// 滑块中间的X坐标 if (center > scrollWidth) {// 超过中线 open(); } else { close(); } onCheckedChanged(); break; } return true; } /** * 关闭动画 */ private void close(int during) { int startX = scrollView.getScrollX(); int dx = -startX; scroller.startScroll(startX, 0, dx, 0, during); if (checked && during > 0) { bgView.setVisibility(View.INVISIBLE); bgView.startAnimation(gone); } else { bgView.setVisibility(View.INVISIBLE); } invalidate(); checked = false; // onCheckedChanged(); } private void close() { close(250); } private void open() { open(250); } /** * 开启动画 */ private void open(int during) { int startX = scrollView.getScrollX(); int dx = scrollWidth + startX; scroller.startScroll(startX, 0, -dx, 0, during); bgView.setVisibility(View.VISIBLE); if (!checked && during > 0) { bgView.startAnimation(show); } else { bgView.clearAnimation(); } invalidate(); checked = true; // onCheckedChanged(); } public void setChecked(final boolean isCheck) { if (isChecked() == isCheck) return; if (scrollWidth > 0) { switchCheck(isCheck); } else { post(new Runnable() { @Override public void run() { switchCheck(isCheck); } }); } } private void switchCheck(final boolean isCheck) { if (isCheck) { open(0); } else { close(0); } } /** * 打开或者关闭时候调用 */ private void onCheckedChanged() { if (onCheckedChangedListener != null) onCheckedChangedListener.onCheckedChanged(checked, this); } @Override public void computeScroll() { if (scroller.computeScrollOffset()) { scrollView.scrollTo(scroller.getCurrX(), scroller.getCurrY()); postInvalidate(); } } /** * 是否打开 * * @return bool */ public boolean isChecked() { return checked; } /** * 添加滑块 */ private void addView() { LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); addView(bgView = new View(getContext())); scrollView = new LinearLayout(getContext()); LinearLayout.LayoutParams maskParams = new LinearLayout.LayoutParams((int) getResources().getDimension(R.dimen.w65), (int) getResources().getDimension(R.dimen.w65)); maskParams.gravity = Gravity.CENTER_VERTICAL; maskParams.topMargin = (int) getResources().getDimension(R.dimen.h3); scrollView.addView(switchView = new View(getContext()), maskParams); scrollView.addView(new View(getContext()), new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1)); addView(scrollView, params); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { View child = getChildAt(0); int height = child.getMeasuredHeight(); int width = child.getMeasuredWidth(); child.layout(0, 0, width, height); getChildAt(1).layout(0, 0, width, height); scrollWidth = width - maskWidth; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // @dimen/w95 // @dimen/w58 // int width=get int width = ViewUtils.getDimenPx(R.dimen.w95); int height = ViewUtils.getDimenPx(R.dimen.w58); // int width = MeasureSpec.getSize(widthMeasureSpec); // int height = MeasureSpec.getSize(heightMeasureSpec); widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); setMeasuredDimension(width, height); getChildAt(0).measure(widthMeasureSpec, heightMeasureSpec); getChildAt(1).measure(widthMeasureSpec, heightMeasureSpec); } /** * 设置监听 * * @param listener * listener */ public void setOnCheckedChangedListener(OnCheckedChangedListener listener) { onCheckedChangedListener = listener; } public interface OnCheckedChangedListener { public void onCheckedChanged(boolean isChecked, SwitchView v); } }
在res 中新建一个文件夹anim 然后添加两个动画
这个动画名字是 alpha_gone
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="250" android:fillAfter="true"/> </set>
这个动画叫 alpha_show
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="250" /> </set>
现在已经完成了 你可以想实现CheackBox一样使用这个了
<com.widget.SwitchView android:id="@+id/switch_view" android:layout_width="wrap_content" android:layout_height="wrap_content" />