Android 入门之常见事件(小白速成2)
接着说基本的组件以及常用的命令啦!
常见的事件及其响应
点击事件
在上一篇中,我们讲了给button添加test方法,使他被点击时能够响应。
而我们也可以选择设置监听器,做到不对xml文件修改,只在java文件中做到对按钮响应的设置,代码如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button=findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"button被点击",Toast.LENGTH_SHORT).show();
v.setX(v.getX()+10);//使每次点击后,按钮向右边移动10个单位
}
});
}
依然是对点击事件的一个简单响应。
这就是对button按钮的动态设置,而上一节中对按钮中添加onclick事件是属于配置方式。
我们也可以将方法放在外面(可复用的方式),方便更多次调用:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button=findViewById(R.id.button);
button.setOnClickListener(myListener);
}
private View.OnClickListener myListener =new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"button被点击",Toast.LENGTH_SHORT).show();
v.setX(v.getX()+10);
}
};
长按事件
button.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Toast.makeText(MainActivity.this,"button被长按",Toast.LENGTH_SHORT).show();
return false;
}
});
返回值是false,表示当前的长按事件响应没有消耗这个事件,所以还可以被别的操作监视器响应。说人话就是:如果这个按钮不仅绑定了长按事件,也绑定的单击事件,那么在我长按之后,也会被判定为单击事件(先输出我长按了按钮,再输出我单击了按钮);但是如果返回值是true,当前的长按响应已经把这个长按行为消耗完,便不会再被单击事件响应了。
滑动事件
滑动事件也叫触摸事件
相比较于长按事件,它也具有布尔类型的返回值,并且多了一个参数 event ,这个event用来记录事件发生现场的情况。(例如单击的坐标位置)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup viewGroup =findViewById(R.id.layout01);
final Button button =findViewById(R.id.button);
viewGroup.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int actionType =event.getAction();
if(actionType ==MotionEvent.ACTION_DOWN){
System.out.println("被按下。。。");
}else if(actionType ==MotionEvent.ACTION_MOVE){
System.out.println("被移动。。。");
button.setX(event.getX());
button.setY(event.getY());
}else if(actionType ==MotionEvent.ACTION_UP){
System.out.println("被松开。。。");
}
return true;
}
});
注:在这里我给layout组件取id为layout01,所以可以在这里查找到,当我在layout区域内点击的时候就能有响应,并且使按钮随着鼠标移动而移动。
焦点事件
当一个元素获取到焦点和失去焦点的时候便会触发响应
button.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
System.out.println("焦点事件");
}
});
我们可以在模拟器上通过键盘的tab键来选择按钮,让它获得焦点。
键盘事件
三个参数,其中keyCode 代表了每次点击键盘所对应的ascii码。
button.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
System.out.println(keyCode);
return false;
}
});
以上就是基本的事件。
添加动画以及线程阻塞
添加动画事件
//为button1添加动画操作
Button button1 = findViewById(R.id.button);
//在水平方向移动
TranslateAnimation animation =new TranslateAnimation(0,150,0,0);
animation.setRepeatCount(30);//重复三十次
animation.setDuration(2000);//完成一次的时间 2s
button1.setAnimation(animation);
这个操作可以使button1在我们运行模拟器时进行左右移动,TranslateAnimation方法的参数就是横纵坐标的起始位置和终止位置。
线程阻塞
但是我们如果添加另一个按钮 button2 ,并且给 button2 添加动作,在点击button2后就会产生线程阻塞,使button1不能正常移动。
原因:一个视图中的多个view组件运行在同一个UI线程当中,多个view组件的监听器的执行会相互影响。
解决方案:采取多线程
但是多线程不能对组件进行设置,例如修改button显示的值,只有创建view的那个主线程可以修改。
多线程代码如下:
Button button2 = findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick( final View v) {
//用post可读性差,维护性差
System.out.println("+++"+Thread.currentThread().getId());
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程开始执行。。。");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行结束。。。");
}
}).start();
}
});
如果要对button2的名字等属性进行修改,可以采用post方法 :
int sum=10;
v.post(new Runnable() {
public void run() {
System.out.println("post开始执行..."+Thread.currentThread().getId());
TextView view =(TextView)v;
view.setText(""+10);
}
});
使用post方法后,post依然是在主线程中执行,执行的顺序是先执行额外的线程,在额外的线程执行结束后,再执行post,因此不会影响别的线程执行。
缺点:可读性差并且维护性差。
所以我们可以选择异步任务(AsyncTask)来解决这个问题。
private Button button2 = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//为button1添加动画操作
Button button1 = (Button) findViewById(R.id.button);
TranslateAnimation animation = new TranslateAnimation(0, 150, 0, 0);
animation.setRepeatCount(30);//重复三十次
animation.setDuration(2000);//完成一次的时间 2s
button1.setAnimation(animation);
button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
new DownloadImageTask().execute();//执行
}
});
}
private class DownloadImageTask extends AsyncTask<String, Void, Integer> {
protected Integer doInBackground(String... urls) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int sum = 10;
return sum;
}
protected void onPostExecute(Integer sum) {
button2.setText(""+sum);
}
}
那么这次基本就说这么多啦!!!
参考自:尚学堂android课程