android 高仿ios开关,android仿ios开关Switch

先看效果图(实际效果很丝滑!)

412fc98ff299

GIF 2020-6-10 19-17-21.gif

代码没太整理,将就看哈,可以自行调整修改。

public class OnOffView extends FrameLayout implements View.OnClickListener {

private static String TAG = "OnOffView";

private int onColor = 0;

private int offColor = 0;

private float iconSize = 0;

private float iconPaddingSize = 0;

private int animationTime = 450;

private CardView icon;

private boolean animationRun = false;

private ImageView backView;

private boolean defOff = false;

private boolean defOff2 = false;

private CheckBoxCall checkBoxCall;

public OnOffView(Context context) {

super(context);

}

@RequiresApi(api = Build.VERSION_CODES.P)

public OnOffView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.OnOffView);

iconSize = typedArray.getDimension(R.styleable.OnOffView_iconSize, 0f);

iconPaddingSize = typedArray.getDimension(R.styleable.OnOffView_paddingSize, 5);

defOff2 = defOff = typedArray.getBoolean(R.styleable.OnOffView_defOff, false);

onColor = typedArray.getColor(R.styleable.OnOffView_onColor, 0x4CAF50);

offColor = typedArray.getColor(R.styleable.OnOffView_offColor, 0xFFFFFF);

backView = new ImageView(getContext());

addView(backView);

FrameLayout.LayoutParams layoutParams1 = (LayoutParams) backView.getLayoutParams();

layoutParams1.height = ViewGroup.LayoutParams.MATCH_PARENT;

layoutParams1.width = ViewGroup.LayoutParams.MATCH_PARENT;

icon = new CardView(getContext());

addView(icon);

FrameLayout.LayoutParams layoutParams2 = (LayoutParams) icon.getLayoutParams();

layoutParams2.height = (int)(iconSize - iconPaddingSize * 2);

layoutParams2.width = (int)(iconSize - iconPaddingSize * 2);

icon.setX(iconPaddingSize);

icon.setY(iconPaddingSize);

icon.setRadius(((iconSize - iconPaddingSize))/2);

typedArray.recycle();

setOnClickListener(this);

}

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

super.onLayout(changed, left, top, right, bottom);

initIcon();

}

public OnOffView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

public OnOffView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {

super(context, attrs, defStyleAttr, defStyleRes);

}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

private void startAnimation(final boolean isOff){

TranslateAnimation animation;

int w = backView.getMeasuredWidth();

if ( w == 0 || w == -1){

w = backView.getWidth();

}

if (!defOff2) {

if (isOff)

animation = new TranslateAnimation(w - icon.getLayoutParams().width - iconPaddingSize * 2, 0, 0, 0);

else

animation = new TranslateAnimation(0, w - icon.getLayoutParams().width - iconPaddingSize * 2, 0, 0);

}else{

if (isOff)

animation = new TranslateAnimation(0, -(w - icon.getLayoutParams().width - iconPaddingSize * 2), 0, 0);

else

animation = new TranslateAnimation(-(w - icon.getLayoutParams().width - iconPaddingSize * 2), 0, 0, 0);

}

animation.setDuration(animationTime);

animation.setRepeatMode(Animation.REVERSE);

animation.setInterpolator(new AccelerateDecelerateInterpolator());

animation.setFillAfter(true);

animation.setAnimationListener(new Animation.AnimationListener() {

@Override

public void onAnimationStart(Animation animation) {

animationRun = true;

//如果想动画结束再执行回调的话, 就把这段话放在 onAnimationEnd 就阔以了

if (checkBoxCall != null){

checkBoxCall.check(isOff);

}

}

@Override

public void onAnimationEnd(Animation animation) {

animationRun = false;

}

@Override

public void onAnimationRepeat(Animation animation) { }

});

icon.startAnimation(animation);

GradientDrawable background = (GradientDrawable) backView.getBackground();

ValueAnimator animator;

if (isOff)

animator = ObjectAnimator.ofInt(background, "color", onColor, offColor);

else

animator = ObjectAnimator.ofInt(background, "color", offColor, onColor);

animator.setDuration(animationTime);

animator.setEvaluator(new ArgbEvaluator());//渐变色平滑

animator.start();

}

private void initIcon(){

if (defOff){

icon.setX(backView.getMeasuredWidth() - icon.getLayoutParams().width - iconPaddingSize);

}else{

icon.setX(iconPaddingSize);

}

GradientDrawable drawable = new GradientDrawable();

//小球圆角角度

drawable.setCornerRadius(Utils.dp2px(50));

//外框颜色

drawable.setStroke(Utils.dp2px(1), Color.parseColor("#EAEAEA"));

if (defOff)

drawable.setColor(onColor);

else

drawable.setColor(offColor);

backView.setBackground(drawable);

}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

@Override

public void onClick(View v) {

animationCheck();

}

//设置初始状态 也可以在xml中设置 app:defOff = false|true

public void setDefOff(boolean off){

defOff2 = defOff = off;

initIcon();

}

//动画切换按钮状态

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

public void animationCheck(){

if (animationRun)

return;

if (defOff) {

startAnimation(true);

defOff = false;

}else{

startAnimation(false);

defOff = true;

}

}

public void setCheckBoxCall(CheckBoxCall checkBoxCall){

this.checkBoxCall = checkBoxCall;

}

public interface CheckBoxCall{

void check(boolean isOff);

}

}

另外需要在attrs.xml里加上属性 values > attrs.xml 没有就创建

使用

android:id="@+id/onOffView"

android:layout_width="100dp"

android:layout_height="60dp"

android:layout_centerInParent="true"

app:offColor="#FFFFFF"

app:onColor="#4CAF50"

app:paddingSize="5dp"

app:iconSize="60dp"/>

另外上面用到了一个单位转换工具Utils.dp2px我也把代码贴一下吧

public static int dp2px(final float dp) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (dp * scale + 0.5f);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值