初学自定义,因语文水平有限,话不多说,要实现的效果如下:
长按图一中的蓝色图标,滑动至灰色区域时,显示图二布局,返回验证状态,进行下一步操作。
图一布局:
<?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可自行计算)。
小白一枚,初学自定义,如有思想或逻辑错误之处,还请告知,在此先感谢了!!!