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" />