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