android事件的处理非常重要,一个好的应用必定有很好的交互体验。接下来我们就学习下android几种事件处理的方式吧。
android有三种处理方式:
- 基于事件的监听。
- 基于回调机制。
- 基于控件的绑定。
基于事件的监听有四种方式:
- 内部类
- 匿名内部类
- 外部类
- 该类实现该接口
接下来我们就一个一个讲吧,并且会附上代码。
内部类实现方式:
activity_main.xml布局文件代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.edu.androidforlistener.MainActivity">
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确定"/>
</LinearLayout>
里面就一个按钮,然后为按钮声明了一个id,我可以通过该id找到该控件。
MainActivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button mBtn;//声明mBtn
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn= (Button) findViewById(R.id.btn);//初始化mBtn
MyOnClickListener mListener=new MyOnClickListener();//初始化我们定义的事件
mBtn.setOnClickListener(mListener);//为按钮绑定事件
}
/*
这就是内部类
*/
class MyOnClickListener implements View.OnClickListener{
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"",Toast.LENGTH_SHORT).show();
}
}
}
运行效果:
匿名内部类实现方式:
acitivity_main.xml布局文件代码跟上面的一样,就不放出来了。
MainActivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button mBtn;//声明mBtn
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn= (Button) findViewById(R.id.btn);//初始化mBtn
/*
setOnClickListener方法参数里面接受一个
OnClickListener接口参数。我们通过匿名类的方式传递一个OnClickListener参数
*/
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"我是通过匿名类实现的",Toast.LENGTH_SHORT).show();
}
});
}
运行结果:
外部类实现方式:
acitivity_main.xml布局文件代码跟上面的一样,就不放出来了。
MainActivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button mBtn;//声明mBtn
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn = (Button) findViewById(R.id.btn);//初始化mBtn
MyOnClickLinstener mListener = new MyOnClickLinstener();//初始化mListener
mBtn.setOnClickListener(mListener);//为mBtn绑定事件
}
}
//这是外部类
class MyOnClickLinstener implements View.OnClickListener {
@Override
public void onClick(View v) {
//这个会报错,MainActivity.this,因为这是外部类不属于该MainActivity中。我们就打印log吧
//Toast.makeText(MainActivity.this,"我是通过外部类实现的",Toast.LENGTH_SHORT).show();
Log.i("TAG", "我是通过外部类实现的..");
}
}
运行结果:
该类实现该接口实现方式:
activity_main.xml布局文件代码跟上面的一样,就不放出来了。
MainAcitivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
/*
MainActivity实现OnClickListener接口
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button mBtn;//声明mBtn
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn = (Button) findViewById(R.id.btn);//初始化mBtn
mBtn.setOnClickListener(this);//为mBtn绑定事件
}
/*
这是OnClickListener接口中的方法。
*/
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "我是实现OnClickListener接口", Toast.LENGTH_SHORT).show();
}
}
到这里我们已经学完了四种基于监听事件的处理。接下来就学习基于回调的。
基于回调机制的事件处理
首先我们要了解什么是回调,不懂得可以参考我的另外一篇博客
http://blog.csdn.net/song_shui_lin/article/details/51426595
看完了,基本知道什么是回调。那我们就开始演示代码吧。
首先我们先定义自己的view,MyButton代码如下:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.Button;
/**
* Created by Administrator on 2016/9/21.
*/
public class MyButton extends Button {
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i("TAG", " MyButton 这个类中的onTouchEvent方法被执行。。。");
//false代表的意思是该事件传到这里不截断,还是向外抛
return false;
}
}
activity_main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.edu.androidforlinstener.MainActivity">
<com.example.edu.androidforlinstener.MyButton
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确定"
/>
</LinearLayout>
可以看到,我们使用的是我们自己定义的MyButton,是包名加上你的类名才能使用
MainActivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private MyButton mBtn;//声明mBtn
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn = (MyButton) findViewById(R.id.btn);//获取mBtn对象
mBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("TAG", " 该按钮触摸事件被处理了。。。");
//false代表的意思是该事件传到这里不截断,还是向外抛
return false;
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.i("TAG", " MainActivity 这个类中的onTouchEvent这个方法被被执行。。。");
//false代表的意思是该事件传到这里不截断,还是向外抛
return false;
}
}
运行结果:
MyButton类中的onTouchEvent方法就是一个回调方法。。
基于控件的绑定事件处理
activity_main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.edu.androidforlistener1.MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="确定"
android:onClick="onClick"/>
</LinearLayout>
这个布局文件也很简单,就一个按钮,特别注意的是 android:onClick属性值必须跟我们 方法名一样,不然会报错
MainActivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//方法名必须跟onClick属性的值一样
public void onClick(View view) {
Toast.makeText(MainActivity.this, "我是绑定控件实现的", Toast.LENGTH_SHORT).show();
}
}
运行结果如下:
到这里我们已经学完了基本的android事件处理。。接下来我们再学习下Handler和 AsyncTask。这两个我们也是必须掌握的。
Handler演示下简单的使用。
首先我们就实现简单的demo吧,就是从1加到100的过程。来学习下handler的使用
main_activity.xml代码如下:
<?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:orientation="vertical">
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="0dp"
android:text="确定" />
<TextView
android:id="@+id/number_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="0"
android:textColor="#ff0000"
android:textSize="28sp" />
</LinearLayout>
这个布局文件就是一个按钮和一个textview,
MainAcitivity.java代码如下:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button mBtn;
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn = (Button) findViewById(R.id.btn);
mTv = (TextView) findViewById(R.id.number_tv);
//为按钮添加点击事件
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = ; i < ; i++) {
mTv.setText("" + i);
}
}
}).start();
}
});
}
}
然后我们运行下,一点击按钮,我们的程序就崩溃。看下错误日志,
意思是说只有主线程(ui线程)才能更改ui。所以我们这种方法不行。
MainAcitivity.java更改后代码如下:
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button mBtn;
private TextView mTv;
int tempNumber;
//定义一个hangler,并重写了里面的方法、
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (tempNumber == ) {
Toast.makeText(MainActivity.this, "100完成", Toast.LENGTH_SHORT).show();
}
if (msg.what == ) {
mTv.setText(tempNumber + "");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn = (Button) findViewById(R.id.btn);
mTv = (TextView) findViewById(R.id.number_tv);
//为按钮添加点击事件
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = ; i < ; i++) {
tempNumber = i;
handler.sendEmptyMessage();
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
});
}
}
这里使用了handler机制来处理。我们通过在子线程发送一个消息,然后主线程收到消息后。就会处理这个消息。handler具体的知识现在在这里就不讲了,只要记住一点。在子线程发送消息让主线程来处理就好了。
运行结果如下:
接下来我们就学习下AsyncTask。
AsyncTask
首先我们来看下官网对它的解释:
第一句话就讲AsyncTask enables proper and easy use of the UI thread.
AsyncTask 能够恰当和容易地去使用ui线程。这是官网对AsyncTask详细的解释和使用步骤 ,访问这网站需要翻墙。不会翻的找我。嘎嘎。。。
https://developer.android.com/reference/android/os/AsyncTask.html
我们先创建自己的任务MyTask 代码如下:
import android.content.Context;
import android.os.AsyncTask;
import android.widget.TextView;
import android.widget.Toast;
/**
* Created by Administrator on 2016/9/21.
*/
public class MyTask extends AsyncTask<Integer, Integer, String> {
private TextView mTv;
private Context mContext;
public MyTask() {
}
public MyTask(TextView mTv, Context mContext) {
this.mTv = mTv;
this.mContext = mContext;
}
/*
一般这个方法用来初始化工作
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/*
任务执行完然后调用,
*/
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mTv.setText(values[] + "");
}
/*
这个方法是在子线程执行的。我们必须要实现的方法
*/
@Override
protected String doInBackground(Integer... params) {
for (int i = ; i < ; i++) {
publishProgress(i);//执行这个方法,会回调onProgressUpdate这个方法。
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "100完成";
}
}
执行的顺序:
画图工具画的,感觉好丑。。。
MainAcitivity.java代码如下:
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button mBtn;
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtn = (Button) findViewById(R.id.btn);
mTv = (TextView) findViewById(R.id.number_tv);
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyTask task=new MyTask(mTv,MainActivity.this);
task.execute();
}
});
}
}
运行效果跟handler一样。不信运行一遍。。
到这里我们已经学完了handler和AsyncTask知识了。跟着上面敲一遍,应该能学到点东西。。嘎嘎。
源码下载
https://github.com/songshuilin/AndroidForBlog/tree/master/androidforhandler