事件的分发
1.Touch事件分发中只有两个主角:ViewGroup和View。Activity的Touch事件事实上是调用它内部的ViewGroup的Touch事件,可以直接当成ViewGroup处理。
2.View在ViewGroup内,ViewGroup也可以在其他ViewGroup内,这时候把内部的ViewGroup当成View来分析。
3.ViewGroup的相关事件有三个:onInterceptTouchEvent(拦截事件)、dispatchTouchEvent、onTouchEvent。View的相关事件只有两个:dispatchTouchEvent、onTouchEvent。
结构图
activity代码实现
// An highlighted block
package bw.com.Unit7;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import bw.com.Unit1.R;
import bw.com.Unit7.View.CustomLinearLayout;
public class LinearLayoutActivity extends AppCompatActivity {
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_linear_layout);
initView();
initLayout();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.e(LinearLayoutActivity.class.getSimpleName(),"dispatchTouchEvent!!!!!!!");
return super.dispatchTouchEvent(ev);
}
private void initLayout() {
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("CustomButton","OnClickListener!!!!!");
}
});
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("CustomButton","OnTouchListener!!!!!!!!!!");
break;
}
return false;
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d(LinearLayoutActivity.class.getSimpleName(),"ACTION_DOWN!!!!!!!");
break;
case MotionEvent.ACTION_UP:
Log.d(LinearLayoutActivity.class.getSimpleName(),"ACTION_UP!!!!!!!");
break;
}
return super.onTouchEvent(event);
}
private void initView() {
button = findViewById(R.id.custom_btn);
}
}
ViewGroup
// An highlighted block
package bw.com.Unit7.View;
import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;
public class CustomLinearLayout extends LinearLayout {
public CustomLinearLayout(Context context) {
super(context);
}
public CustomLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CustomLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.d(CustomLinearLayout.class.getSimpleName(),"onInterceptTouchEvent!!!!!!!");
return false;
}
//是所有事件执行方法的最后执行的
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d(CustomLinearLayout.class.getSimpleName(),"dispatchTouchEvent!!!!!!!");
return super.dispatchTouchEvent(ev);
}
//如果OnTouchListener 被实现且返回true 会拦截掉所有onTouchEvent方法,包括onclick
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d(CustomLinearLayout.class.getSimpleName(),"ACTION_DOWN!!!!!!!");
break;
case MotionEvent.ACTION_UP:
Log.d(CustomLinearLayout.class.getSimpleName(),"ACTION_UP!!!!!!!");
break;
}
return super.onTouchEvent(event);
}
}
View
// An highlighted block
package bw.com.Unit7.View;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
@SuppressLint("AppCompatCustomView")
public class CustomButton extends Button implements View.OnClickListener, View.OnTouchListener {
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//事件的传递
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d(CustomButton.class.getSimpleName(),"dispatchTouchEvent!!!!!!!!!!!!");
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d(CustomButton.class.getSimpleName(),"ACTION_DOWN!!!!!!!");
break;
case MotionEvent.ACTION_UP:
Log.d(CustomButton.class.getSimpleName(),"ACTION_UP!!!!!!!");
break;
}
return super.onTouchEvent(event);
}
@Override
public void onClick(View v) {
Log.d(CustomButton.class.getSimpleName(),"onClick!!!!!!!");
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d(CustomButton.class.getSimpleName(),"onTouch-->ACTION_DOWN!!!!!!!");
break;
case MotionEvent.ACTION_UP:
Log.d(CustomButton.class.getSimpleName(),"onTouch-->ACTION_UP!!!!!!!");
break;
}
return false;
}
}
解决ScrollView与ListView事件冲突
布局文件
// An highlighted block
<?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"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<bw.com.Unit7.View.CustomListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent"></bw.com.Unit7.View.CustomListView>
<ImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@drawable/_104"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
Java代码(自定义ListView:解决方法)
// An highlighted block
package bw.com.Unit7.View;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class CustomListView extends ListView {
public CustomListView(Context context) {
super(context);
}
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int spec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec,spec);
}
}