心声
- 今天在写滑动解锁demo中提前学习了事件处理的方式,主要是学习回调处理事件。有些东西比较容易搞混,比如屏幕大小和容器大小,哪个方法是以容器为坐标系,哪些又是以屏幕为坐标系,虽然容易弄混,但并不难,只要理解了,也是很容易看懂的。
Android事件处理的两种方式
-
1.监听处理事件
-
2.回调处理事件
1.监听处理事件
参与者:
1.事件源:事件在哪发生(比如按钮被点了,那么事件源就是一个按钮)
2.监听者:谁来处理事件
3.事件: 到底是什么事件(点击,长按,旋转)
监听处理事件的过程
以事件源为按钮为例:
image.png
当用户做出点击按钮的行为,按钮就是所谓的事件源,监听者需要注册通知自己要监听的行为,然后获取事件(如:点击按钮就是一个事件),并处理按钮。而我们操作者所需要做的就是设置控件和监听者
2.回调处理事件
监听处理事件的过程
首先有一个事件源->用户的某一个行为触发事件源->事件源自己处理事件->将事件处理之后的结果通过接口回调->处理回调事件(重写回调方法)
image.png
处理一个touch事件,实现手在屏幕上滑动,控件跟着走或实现改变控件的颜色
-
xml文件里面,添加一个控件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="@+id/root">
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorAccent"
android:id="@+id/view"
android:tag="1"/>
</RelativeLayout>
步骤解析:
image.png
运行效果:
image.png
- MainActivity中
前提须知
1.getX()与getRawx()、getY()与getRawY()的区别
- 当你触到按钮时,x,y是相对于该按钮左上点
(控件本身)
的相对位置。
而Rawx,Rawy始终是相对于屏幕的位置。
image.png
2.setX()、setY()用来改变控件的位置
实现手在屏幕上滑动,控件跟着走
public class MainActivity extends AppCompatActivity {
View redView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//通过id找到对应的控件
redView =findViewById(R.id.view);
}
//重写触摸回调的时间onTouch
//返回值表示这个事件是否已经被处理
//true:表示已经处理了 不会继续传递
//false:表示自己不消费 时间还要继续往下传
//系统自动将事件包装为MotionEvent类
//用户可以获取事件的行为:getAction(ACTION_DOWN 手放在屏幕上、ACTION_MOVE手在屏幕上滑动、ACTION_UP 手放开了、ACTION_CANCER 被打断了)
//获取触摸点的坐标:getX,getY
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取事件对应的类型
//获取屏幕的大小
Point p=new Point();
getWindowManager().getDefaultDisplay().getSize(p);
System.out.println("屏幕宽度:"+p.x);
System.out.println("屏幕高度:"+p.y);
//获取容器本身的宽高
RelativeLayout rl=findViewById(R.id.root);
System.out.println("界面宽度:"+rl.getWidth());
System.out.println("界面高度:"+rl.getHeight());
//计算界面和屏幕之间的间距
//计算状态栏和标题栏的高度
float padding= p.y-rl.getHeight();
int action=event.getAction();
if(action==MotionEvent.ACTION_DOWN){
//按下
//获取触摸点的x坐标和y坐标
float x = event.getX() ;
float y = event.getY() - padding;
//改变控件的位置
redView.setX(x-(float)(redView.getWidth()*0.5));
redView.setY(y-(float)(redView.getWidth()*0.5));
}else if(action==MotionEvent.ACTION_MOVE){
//滑动
}else if(action==MotionEvent.ACTION_UP){
//离开屏幕
}else{
//被打断了
}
return true;
}
实现改变控件的颜色
public class MainActivity extends AppCompatActivity {
View redView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//通过id找到对应的控件
redView =findViewById(R.id.view);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//更改控件的颜色
//redView.setBackgroundColor(Color.BLACK);
//找到父容器
RelativeLayout rl=findViewById(R.id.root);
//通过tag查找父容器下面的子控件
View iv=rl.findViewWithTag("1");
iv.setBackgroundColor(Color.TRANSPARENT);
return true;
}
}
网友评论