Android自定义滑动确认控件SlideView

项目GitHub

 https://github.com/Gnepux/SlideView

前言

目前App上有很多对于按钮误操作的控制。比如点击按钮后弹出确认框,但是这样的模式略显死板。为了给App赋予更多的生命力,可以借鉴网站登录滑动确认的方式。这种方式目前更多地用于web登录。以下是某网站登录时使用的滑动验证,用来取代以往的验证码模式。

我们的App可以借鉴上述的模式自定义一个滑动确认的控件,可以用于控制误操作点击的场景。当然其他的应用场景可以等待大家细细挖掘。

设计思路

我们就暂且命名这个自定义的滑动控件叫SlideView

先来总结一下SlideView的主要功能:“按住一个进度条里的按钮往右滑,如果滑到一般松开按钮自动回到原位,如果滑到底则给出完成提示”。

貌似就是这么一句话的事。当然还有更多属性设置,比如背景的文字、颜色、滑动按钮和进度条的比例等等。

通过前面一句话的介绍,是不是让我们想起了Andoird的SeekBar控件?确实重写SeekBar控件的确可以实现我们想要实现的功能,但可定制稍微差了些,所以决定重头开始构建SlideView。

方案

既然要重构构建SlideView,那我们就要实现一个自定义的ViewGroup。添加背景图和提示文字。之后再将可以拖动的按钮加入到这个ViewGroup中。那个所谓“可以拖动的按钮”我们就叫它SlideIcon,这是一个自定义View。也可以添加背景图和提示文字,控制它的宽度与SildeView总宽度的比例,最后为这个View加上触摸事件,按下之后可以拖动,拖动到一般松开回到起点,拖到底触发一个完成的回调。

总体方案就是这样,是不是很简单,下面让我们来一步步实现这个SlideView。

可拖动的部分 - SlideIcon

SlideIcon是一个自定义View,它的主要功能就是拖动。其中我们需要做的工作跟就是测量尺寸、添加触摸事件、绘制背景图和文字。

具体代码如下:

/**
 * 可拖动的View
 */
private class SlideIcon extends View {
    // 用来控制触摸事件是否可用
    private boolean mEnable;

    // 提示文字的Paint
    private Paint mTextPaint = null;

    // 提示文字的字体测量类
    private Paint.FontMetrics mFontMetrics;

    // 回调
    private MotionListener listener = null;

    // 手指按下时SlideIcon的X坐标
    private float mDownX = 0;

    // SlideIcon在非拖动状态下的X坐标
    private float mX = 0;

    // SliedIcon在拖动状态下X轴的偏移量
    private float mDistanceX = 0;

    public SlideIcon(Context context) {
        this(context, null);
    }

    public SlideIcon(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public void setListener(MotionListener listener) {
        this.listener = listener;
    }

    public void setEnable(boolean enable) {
        this.mEnable = enable;
    }

    public boolean getEnable() {
        return mEnable;
    }

    private void init() {
        // 设置文字Paint
        mTextPaint = new Paint();
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setColor(mIconTextColor);
        mTextPaint.setTextSize(mIconTextSize);

        // 获取字体测量类
        mFontMetrics = mTextPaint.getFontMetrics();

        // 设置背景图
        setBackgroundResource(mIconResId);

        // 设置触摸事件可用
        mEnable = true;
    }

    /**
     * 重置SlideIcon
     */
    public void resetIcon() {
        mDownX = 0;
        mDistanceX = 0;
        mX = 0;
        mEnable = true;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 宽度和宽Mode
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        // 高度和高Mode
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        switch (heightMode) {
            case MeasureSpec.AT_MOST:   // layout_height为"wrap_content"时显示最小高度
                setMeasuredDimension(MeasureSpec.makeMeasureSpec((int)(widthSize * mIconRatio), widthMode),
                        MeasureSpec.makeMeasureSpec(mMinHeight, heightMode));
                break;
            default:    // layout_height为"match_parent"或指定具体高度时显示默认高度
                setMeasuredDimension(MeasureSpec.makeMeasureSpec((int)(widthSize * mIconRatio
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值