锁屏页滑动控件
先看下要实现的效果:
链接地址
这是我实际开发一个项目中的效果,这里我就只抽取出锁屏页的滑动控件,其实滑动控件搞出来了其他效果都是easy的,滑动控件才是重点。
准备工作
Android中关于View的位置参数相关的知识点还是挺多的,而且比较容易搞混,所以在自定义View前我觉得有必要把基础的知识理一遍。
View有4个属性:top、left、right、bottom
top指的是左上角的纵坐标
left指的是左上角的横坐标
right指的是右下角的横坐标
bottom指的是右下角的纵坐标
一个event事件也有很多坐标方法:
getX()指的是事件相对于控件本身最左边的距离
getY()指的是事件相对于控件本身最上边的距离
getRawX()指的是事件相对于屏幕左边的距离
getRawY()指的是时间相对于屏幕上边的距离
TouchSlop:Android判断触摸的时候到底是滑动事件还是点击事件的临界点
基本概念搞清楚了,自定义view起来就方便多了
搞事情
首先,先把布局文件写了,布局文件简单,直接上代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="60dp">
<ImageView
android:id="@+id/image_lock_view_drag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@mipmap/home" />
<ImageView
android:id="@+id/image_lock_view_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginLeft="50dp"
android:src="@mipmap/xiazai" />
<ImageView
android:id="@+id/image_lock_view_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_marginRight="50dp"
android:src="@mipmap/yaoshi" />
<ImageView
android:id="@+id/image_lock_view_zuo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:layout_toLeftOf="@+id/image_lock_view_drag"
android:src="@mipmap/zuo"
android:visibility="gone" />
<ImageView
android:id="@+id/image_lock_view_you"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/image_lock_view_drag"
android:src="@mipmap/you"
android:visibility="gone" />
</RelativeLayout>
那么接下来就是自定义View了,这里我采用继承RelativeLayout的方式,简单说下思路:这个控件的难点在于中间的home键当你滑动的时候随着你的手指的滑动而滑动,还有就是判断是否滑动到了左边和右边的图标范围,滑动到了图标就回调给Activity来处理对应的事件。
其实很好解决,在move事件中去判断,如果事件相对于屏幕左边的横坐标的距离(getRawX()方法)小于屏幕宽度的一半,那么意思就是用户是想左滑动的,反之则向右滑动。
当向左滑动的时候,getRawX()获取到的距离小于左图标的右边距到屏幕左边的距离的时候,就说明它滑到了左边,记录下这个tag,当up事件的时候如果tag成立,则接口回调。反之亦然。
ok,思路都说好了,那就直接上代码好了,思路清晰了以后代码看上去就简单多了:
public class LockView extends RelativeLayout {
private static final String TAG = "MainActivity";
private ImageView homeImageView; //home
private ImageView zuoImageView; //home左边的左箭头
private ImageView youImageView; //home右边的右箭头
private ImageView leftImageView; //左边去赚钱的imageView
private ImageView rightImageView; //右边解锁的imageView
private int width; //屏幕宽度
private int mx, my;
private int top;
private int bottom;
private int left;
private int right;
private int leftImageView_left;
private int rightImageView_right;
private boolean left_flag = false;
private boolean right_flag = false;
private int leftImageView_right;
private int rightImageView_left;
private Context mContext;
private LockViewClickListener lockViewClickListener;
//home键按下的坐标
private float homeDownX, homeDownY;
//home键抬起的坐标
private float homeUpX, homeUpY;
public interface LockViewClickListener{
public void clickRight();
public void clickLeft();
public void clickHome();
}
public void setOnLockViewClickListener(LockViewClickListener lockViewClickListener){
this.lockViewClickListener = lockViewClickListener;
}
public LockView(Context context) {
super(context);
mContext = context;
width = MeasureUtil.getWidth(context);
LayoutInflater.from(context).inflate(R.layout.layout_lock_view, this);
initViews();
addListener();
}
public LockView(Context context, AttributeSet attributeSet){
super(context, attributeSet);
mContext = context;
width = MeasureUtil.getWidth(context);
LayoutInflater.from(context).inflate(R.layout.layout_lock_view, this);
initViews();
addListener();
}
private void addListener() {
homeImageView.setOnTouchListener(new OnTouchListener() {
private int height;
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
homeDownX = event.getRawX();
homeDownY = event.getRawY();
homeImageView.setImageResource(R.mipmap.tongqian_pressed);
leftImageView.setImageResource(R.mipmap.xiazaizhong);
rightImageView.setImageResource(R.mipmap.yaoshizhong);
// leftImageView_left:32 rightImageView_right:688
zuoImageView.setVisibility(View.VISIBLE);
youImageView.setVisibility(View.VISIBLE);
leftImageView_left = leftImageView.getLeft();
leftImageView_right = leftImageView.getRight();
rightImageView_right = rightImageView.getRight();
rightImageView_left = rightImageView.getLeft();
Log.i(TAG, "leftImageView_left:" + leftImageView_left + "rightImageView_right:" + rightImageView_right);
Log.i(TAG, "event.getRawX()" + event.getRawX() + "event.getRawY()" + event.getRawY());
Log.i(TAG, "event.getX()" + event.getX() + "event.getY()" + event.getY());
height = (int) (event.getRawY() - 50);
System.out.println("v.getTop()" + v.getTop() + "v.getBottom()" + v.getBottom() + "v.getLeft()" + v.getLeft() + "v.getRight" + v.getRight());
left = v.getLeft();
right = v.getRight();
top = v.getTop();
bottom = v.getBottom();
break;
case MotionEvent.ACTION_MOVE:
System.out.println("----------event.getRawX()" + event.getRawX() + "event.getRawY()" + event.getRawY());
System.out.println("----------event.getX()" + event.getX() + "event.getY()" + event.getY());
mx = (int) (event.getRawX());
my = (int) (event.getRawY() - 50);
Log.i(TAG, " mx " + mx + " my" + my + " img.getWidth()/2" + homeImageView.getWidth() / 2 + " img.getHeight()/2" + zuoImageView.getHeight() / 2);
if (mx < width / 2) {
if (mx < leftImageView_right) {
v.layout(leftImageView_left, top, leftImageView_right, bottom);
left_flag = true;
} else {
v.layout(mx - homeImageView.getWidth() / 2, top, mx + homeImageView.getWidth() / 2, bottom);
left_flag = false;
}
} else if (mx > width / 2) {
if ((mx + homeImageView.getWidth() / 2) < rightImageView_right) {
v.layout(mx - homeImageView.getWidth() / 2, top, mx + homeImageView.getWidth() / 2, bottom);
Log.i(TAG, " int l " + (mx - homeImageView.getWidth() / 2) + " int top" + (my - homeImageView.getHeight() / 2) + " " +
"int right" + (mx + zuoImageView.getWidth() / 2)
+ " int bottom" + (my + homeImageView.getHeight() / 2));
}
if (mx > rightImageView_left) {
v.layout(rightImageView_left, top, rightImageView_right, bottom);
right_flag = true;
} else {
v.layout(mx - homeImageView.getWidth() / 2, top, mx + homeImageView.getWidth() / 2, bottom);
right_flag = false;
}
}
break;
case MotionEvent.ACTION_UP:
homeImageView.setImageResource(R.mipmap.home);
homeUpX = event.getRawX();
homeUpY = event.getRawY();
zuoImageView.setVisibility(View.GONE);
youImageView.setVisibility(View.GONE);
if (Math.abs(homeUpX - homeDownX) > 3){
//拖拽
leftImageView.setImageResource(R.mipmap.xiazai);
rightImageView.setImageResource(R.mipmap.yaoshi);
if (right_flag) {
lockViewClickListener.clickRight();
rightImageView.setImageResource(R.mipmap.yaoshiok);
} else if (left_flag) {
lockViewClickListener.clickLeft();
leftImageView.setImageResource(R.mipmap.xiazaiok);
}
right_flag = false;
left_flag = false;
v.layout(left, top, right, bottom);
}else {
//点击
lockViewClickListener.clickHome();
}
break;
}
return true;
}
});
}
private void initViews() {
leftImageView = (ImageView) findViewById(R.id.image_lock_view_left);
rightImageView = (ImageView) findViewById(R.id.image_lock_view_right);
homeImageView = (ImageView) findViewById(R.id.image_lock_view_drag);
zuoImageView = (ImageView) findViewById(R.id.image_lock_view_zuo);
youImageView = (ImageView) findViewById(R.id.image_lock_view_you);
}
}
最后上 github地址:github
我的微信公共号,欢迎关注