滑动验证--------简易的ViewGroup

初学自定义,因语文水平有限,话不多说,要实现的效果如下:
图一
图二

长按图一中的蓝色图标,滑动至灰色区域时,显示图二布局,返回验证状态,进行下一步操作。
图一布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_margin="10dp"
        android:background="@drawable/view_can_touch_view_drawable_gray"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/image_left"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/icon_selected_verify" />

        <ImageView
            android:id="@+id/image_tag"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="70dp"
            android:layout_marginRight="70dp"
            android:src="@mipmap/icon_double_arrow_right" />

        <ImageView
            android:id="@+id/image_right"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/icon_unselected_verify" />
    </LinearLayout>

图二布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_margin="10dp"
        android:background="@drawable/view_can_touch_view_drawable_green"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:drawableLeft="@mipmap/icon_complete_white"
            android:drawablePadding="10dp"
            android:gravity="center_vertical"
            android:text="验证成功"
            android:textColor="#fff"
            android:textSize="16sp" />
    </LinearLayout>
</LinearLayout>

完整的代码如下:

public class SliderValidationView extends ViewGroup implements View.OnTouchListener {
    private ImageView imageViewRight;
    private ImageView imageViewLeft;
    private ImageView imageTag;
    private int imageTagRight;
    private View inflate, inflateOk;

    public SliderValidationView(Context context) {
        super(context);
        init(context);
    }

    public SliderValidationView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public SliderValidationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public void init(Context context) {
        inflateOk = View.inflate(context, R.layout.view_can_touch_view_ok_layout, null);
        inflate = View.inflate(context, R.layout.view_can_touch_view_layout, null);
        imageViewLeft = (ImageView) inflate.findViewById(R.id.image_left);
        imageViewRight = (ImageView) inflate.findViewById(R.id.image_right);
        imageTag = (ImageView) inflate.findViewById(R.id.image_tag);
        imageViewLeft.setOnTouchListener(this);
        this.addView(inflate);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        View view = getChildAt(0);
        view.layout(l, t, r, b);
        viewLeft = imageViewLeft.getLeft();
        viewRight = imageViewLeft.getRight();
        imageTagRight = imageTag.getRight();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int WRAP_WIDTH = 300;
        int WRAP_HEIGHT = 48;
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, heightMeasureSpec);
        }
        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(WRAP_WIDTH, WRAP_HEIGHT);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(WRAP_WIDTH, height);
        } else if (heightMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(width, WRAP_HEIGHT);
        } else {
            setMeasuredDimension(width, height);
        }
    }

    private int startDownX = 0, lastMoveX = 0;
    private int viewLeft = 0, viewRight = 0;


    public SliderValidationInterface sliderValidationInterface;

    public interface SliderValidationInterface {
        void validation(boolean IsSlider);
    }


    public void setSliderValidationInterface(SliderValidationInterface sliderValidationInterface) {
        this.sliderValidationInterface = sliderValidationInterface;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startDownX = (int) event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                int dx = (int) (event.getX() - startDownX);
                int left = v.getLeft() + dx;
                int right = v.getRight() + dx;
                if (left < viewLeft) {
                    left = viewLeft;
                    right = viewRight;
                }
                if (right > imageViewRight.getRight()) {
                    right = imageViewRight.getRight();
                    left = imageViewRight.getLeft();
                }
                v.layout(left, v.getTop(), right, v.getBottom());
                lastMoveX = (int) event.getX();
                break;
            case MotionEvent.ACTION_UP:
                Log.e("ACTION_UP", "lastMoveX==" + lastMoveX);
                Log.e("ACTION_UP", "imageViewRight.getLeft()==" + imageViewRight.getLeft());
                Log.e("ACTION_UP", "v.getLeft()==" + v.getLeft());
                Log.e("ACTION_UP", "imageTagRight==" + imageTagRight);
                if (v.getLeft() >= imageTagRight) {
                    startAnimationT(v, imageViewRight.getLeft());
                    v.layout(imageViewRight.getLeft(), v.getTop(), imageViewRight.getRight(), v.getBottom());
                    this.removeView(inflate);
                    this.addView(inflateOk);
                    sliderValidationInterface.validation(true);
                } else {
                    startAnimationT(v, viewLeft);
                    v.layout(viewLeft, v.getTop(), viewRight, v.getBottom());
                }
                break;
        }
        return true;
    }

    public void startAnimationT(View v, int toFloat) {
        TranslateAnimation translateAnimation = new TranslateAnimation((float) v.getLeft(), (float) toFloat, 0, 0);
        translateAnimation.setDuration(500);
        translateAnimation.setInterpolator(new AccelerateInterpolator());
        v.startAnimation(translateAnimation);
    }
}

一:首先我们获取图一和图二中的布局,然后把图一添加到该ViewGroup中,设置imageViewLeft的触摸事件监听;

二:测量当前布局和子布局的宽高,具体含义可自行百度搜索,都是一些简单的用法;

三:固定子布局在改父布局中的位置,在这里用的是子布局的宽高,在这里获取子view的高宽需在测量之后,才能够获得,否则获取不到

四:在onTouch()方法中,获取滑动距离,进行临界点限制,防止滑动超出控件本身,然后通过View的layout()方法,将移动中的view进行位置固定,然后在手抬起时移除图一中的布局,把图二布局给add进来,然后通过接口的方式,回调给界面进行操作,在这里将滑动的距离进行了一下判断,如果滑动的距离超过了imageTag的距离位置,则进行移除和添加,否则,通过平移滑动回到远处(margin和padding可自行计算)。

小白一枚,初学自定义,如有思想或逻辑错误之处,还请告知,在此先感谢了!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值