自定义Switch

2018-03-28  本文已影响44人  小玉1991

不多说,直接上代码吧!

package com.smartisan.muse.ui.widget;

/**
 * Created by Administrator on 2018/3/28.
 */

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.smartisan.muse.R;

import static android.content.ContentValues.TAG;


/**
 * 自定义switch开关
 */

public class MySwitch extends FrameLayout {
    private Context context;
    private final static int MP = ViewGroup.LayoutParams.MATCH_PARENT;
    private final static int WC = ViewGroup.LayoutParams.WRAP_CONTENT;
    private Drawable bg_on;
    private Drawable bg_off;
    private ImageView ball;
    private ImageView switchBg;
    private int local_state = 0;//本地状态 0:关  1:开
    private int mWidth;
    private int mHeight;
    private int mBallWidth;


    public MySwitch(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
        this.context = context;
    }

    public MySwitch(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
        this.context = context;
    }

    public MySwitch(Context context) {
        super(context);
        init(context);
        this.context = context;
    }

    private void init(Context context) {

        /**整体布局预设**/
        bg_on = getResources().getDrawable(R.drawable.switch_on_bg);
        bg_off = getResources().getDrawable(R.drawable.switch_off_bg);
        FrameLayout.LayoutParams FParams;
//                =new FrameLayout.LayoutParams(WC,getRealPixel(59));
//        setLayoutParams(FParams);

        ImageView switch_default_Bg = new ImageView(context);
        FParams = new FrameLayout.LayoutParams(WC, WC);
        switch_default_Bg.setImageResource(R.drawable.switch_off_bg);
        addView(switch_default_Bg, FParams);


        switchBg = new ImageView(context);
        FParams = new FrameLayout.LayoutParams(WC, WC);
        addView(switchBg, FParams);


        //开关圆球
        LinearLayout ballLayout = new LinearLayout(context);
        ballLayout.setOrientation(LinearLayout.HORIZONTAL);
        FParams = new FrameLayout.LayoutParams(WC, WC);
        FParams.gravity = Gravity.BOTTOM;
        addView(ballLayout, FParams);

        ball = new ImageView(context);
        LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(WC, WC);
        ball.setImageResource(R.drawable.switch_thumb);
        ballLayout.addView(ball, lParams);

        turnOff(0);

      //获取控件宽高
        post(new Runnable() {
            @Override
            public void run() {
                mWidth = getWidth();
                mHeight = getHeight();
                mBallWidth =ball.getWidth();
                Log.d(TAG, "onGlobalLayout: width = " + mWidth + "   height = " + mHeight+" mBallWidth:"+mBallWidth);
            }
        });

        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (local_state == 0) {
                    turnOn(200);
                } else {
                    turnOff(200);
                }
                if (onSwitchClickListener != null) {
                    onSwitchClickListener.onClickSwitch(local_state);
                }

            }
        });

    }



    /**
     * 需要详细配置请看 {@link #turnOn(int time)}
     * 打开按钮,带渐变动画
     *
     * @param time 渐变时间
     *             0 马上设置成打开状态
     */
    private void turnOn(int time) {
//        ballLayout.setGravity(Gravity.RIGHT);
        switchBg.setImageDrawable(getResources().getDrawable(android.R.color.transparent));
//        ball.setPadding(getRealPixel(80), 0, 0, 0);
//        switchBg.setBackgroundResource(R.drawable.switch_on_bg);
        startAnimator(time,0,mWidth-mBallWidth,ball);
        local_state = 1;

        TransitionDrawable td;

        if (time == 0) {
            td = new TransitionDrawable(new Drawable[]{bg_on, bg_on});
        } else {
            td = new TransitionDrawable(new Drawable[]{getResources().getDrawable(android.R.color.transparent), bg_on});
        }

        td.setCrossFadeEnabled(true);
        td.startTransition(time);
        switchBg.setImageDrawable(td);

    }


    /**
     * 需要详细配置请看 {@link #turnOff(int time)}
     * 打开按钮,带渐变动画
     *
     * @param time 渐变时间
     *             0 马上设置成关闭状态
     */
    private void turnOff(int time) {
//        ballLayout.setGravity(Gravity.RIGHT);
        switchBg.setImageDrawable(getResources().getDrawable(android.R.color.transparent));
//        ball.setPadding(0, 0, getRealPixel(80), 0);
//        switchBg.setBackgroundResource(R.drawable.switch_off_bg);
        startAnimator(time,mWidth-mBallWidth,0,ball);
        local_state = 0;
        TransitionDrawable td;

        if (time == 0) {
            td = new TransitionDrawable(new Drawable[]{getResources().getDrawable(android.R.color.transparent), getResources().getDrawable(android.R.color.transparent)});
        } else {
            td = new TransitionDrawable(new Drawable[]{bg_on, getResources().getDrawable(android.R.color.transparent)});
        }


        td.setCrossFadeEnabled(true);
        td.startTransition(time);
        switchBg.setImageDrawable(td);

    }

    //以渐变效果,在200ms内打开开关
    public void transitionOn() {
        turnOn(200);
    }

    //以渐变效果,在200ms内关闭开关
    public void transitionOff() {
        turnOff(200);
    }

    //无渐变效果,强制打开开关
    public void switchOn() {
        turnOn(0);
    }

    //无渐变效果,强制关闭开关
    public void switchOff() {
        turnOff(0);
    }

    //获取开关本地状态
    public int getLocalState() {
        return this.local_state;
    }

    //点击时回传switch 状态,0为关闭,1为打开
    public interface OnSwitchClickListener {
        void onClickSwitch(int local_state);
    }

    private OnSwitchClickListener onSwitchClickListener;

    public void setOnSwitchClickListener(OnSwitchClickListener l) {
        this.onSwitchClickListener = l;
    }



    private void startAnimator(int time, final int from, final int to, final View v) {
        final ValueAnimator animator = ValueAnimator.ofInt(from, to);
        animator.setDuration(time);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                /**
                 * 通过这样一个监听事件,我们就可以获取
                 * 到ValueAnimator每一步所产生的值。
                 *
                 * 通过调用getAnimatedValue()获取到每个时间因子所产生的Value。
                 * */
                Integer value = (Integer) animation.getAnimatedValue();
                v.setPadding(value, 0, 0, 0);


            }
        });
        animator.start();
    }
}
上一篇下一篇

猜你喜欢

热点阅读