天天看点

android之事件处理/Handler/AsyncTaskandroid有三种处理方式:

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();
        }
    }
}
           

运行效果:

android之事件处理/Handler/AsyncTaskandroid有三种处理方式:

匿名内部类实现方式:

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();
            }
        });
    }
           

运行结果:

android之事件处理/Handler/AsyncTaskandroid有三种处理方式:

外部类实现方式:

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", "我是通过外部类实现的..");
    }
}
           

运行结果:

android之事件处理/Handler/AsyncTaskandroid有三种处理方式:

该类实现该接口实现方式:

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();
    }
}
           
android之事件处理/Handler/AsyncTaskandroid有三种处理方式:
到这里我们已经学完了四种基于监听事件的处理。接下来就学习基于回调的。

基于回调机制的事件处理

首先我们要了解什么是回调,不懂得可以参考我的另外一篇博客

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;
    }
}
           

运行结果:

android之事件处理/Handler/AsyncTaskandroid有三种处理方式:
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/AsyncTaskandroid有三种处理方式:
到这里我们已经学完了基本的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();
            }
        });

    }
}
           
然后我们运行下,一点击按钮,我们的程序就崩溃。看下错误日志,
android之事件处理/Handler/AsyncTaskandroid有三种处理方式:
意思是说只有主线程(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具体的知识现在在这里就不讲了,只要记住一点。在子线程发送消息让主线程来处理就好了。

运行结果如下:

android之事件处理/Handler/AsyncTaskandroid有三种处理方式:
接下来我们就学习下AsyncTask。

AsyncTask

首先我们来看下官网对它的解释:
android之事件处理/Handler/AsyncTaskandroid有三种处理方式:

第一句话就讲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完成";
    }
}
           

执行的顺序:

android之事件处理/Handler/AsyncTaskandroid有三种处理方式:
画图工具画的,感觉好丑。。。

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