当用户在应用界面上执行各种操作时,应用程序需要为用户的动作提供响应,这种响应过程就是事件处理。
⒈分类
基于监听的事件处理机制
监听三要素
- Event Source(事件源) 【发生事件的控件,事件的源头,监听的目标】
- Event(事件)【发生哪些事件,不同的事件需要不同的监听器去处理】
- Event Listener(事件监听器)【事件监听器和事件是对应的,不同的事件需要对应的事件监听器去处理】
btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { btn1.setText("我被点击了!"); } });
实现监听事件的方法
-
-
- 通过内部类实现【声明类去实现监听器接口,在实现方法中判断不同的按钮事件】
-
public class ContainerActivity extends AppCompatActivity { private Button btn1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_container); btn1 = findViewById(R.id.btn_1); btn1.setOnClickListener(new OnClick()); } class OnClick implements View.OnClickListener{ @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_1: break; case R.id.tv_1: break; } } } }
-
-
- 通过匿名内部类实现【上面的案例就是】
-
public class ContainerActivity extends AppCompatActivity { private Button btn1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_container); btn1 = findViewById(R.id.btn_1); btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); } }
-
-
- 通过事件源所在类实现【让Activity的子类去实现上面的接口,Button设置监听的时候把Activity的子类传递过去】
-
public class ContainerActivity extends AppCompatActivity implements View.OnClickListener { private Button btn1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_container); btn1 = findViewById(R.id.btn_1); btn1.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_1: break; } } }
-
-
- 通过外部类实现
-
package cn.coreqi.listener; import android.view.View; import cn.coreqi.helloworld2.R; public class MyClickListener implements View.OnClickListener { @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_1: break; } } }
public class ContainerActivity extends AppCompatActivity { private Button btn1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_container); btn1 = findViewById(R.id.btn_1); btn1.setOnClickListener(new MyClickListener()); } }
-
-
- 在布局文件中设置控件的onClick属性(针对点击事件)
-
<Button android:id="@+id/btn_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="按钮1" android:onClick="btn1OnClick"/>
给同一事件源添加多个同种类型监听器会怎样?
当给同种同一个事件源设置同种类型监听器的时候,系统只会响应最后一个设置的监听器。
布局文件中所设置的监听器始终排在最前。
基于回调的事件处理机制
回调机制与监听机制的区别
监听一个事件的发生,有事件源、事件、事件的监听者,事件源和事件的监听者是分开的,需要设置一个监听器上去
回调机制,事件源和事件的监听者是绑定在一起的,比如监听一个按钮的触摸事件,写一个类去继承Button,然后重写触摸事件的方法,当触摸按钮的时候就回去回调这么一个方法,也就是说,按钮本身就已经实现了监听的回调,它已经不需要我们去给它额外的设置监听器了。它本身可以内部回调。
基于回调的事件传播
1.重写控件一些内部的方法,当控件被用户做一些操作和回调方法相关动作的时候,那么系统会去回调我们重写的相关动作的方法。
package cn.coreqi.ui; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import androidx.appcompat.widget.AppCompatButton; public class MyButton extends AppCompatButton { public MyButton(Context context) { super(context); } public MyButton(Context context, AttributeSet attrs) { super(context, attrs); } public MyButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.d("info","---onTouchEvent---"); break; } return false; } }
2.回调机制先从控件本身开始回调,执行完成之后再去执行Activity的回调,事件是向外传播的。
3.监听优先于回调,如果给控件设置了监听器,则优先执行监听器,然后再去执行回调。