1、处理冲突:
1.内部拦截法(由子View根据条件来让事件由谁处理),一定要想办法让子View拿到事件;
2.外部拦截法(由父容器处理)
2、公共类
package com.leo.dispatch;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private int[] iv = new int[]{R.mipmap.iv_0, R.mipmap.iv_1, R.mipmap.iv_2,
R.mipmap.iv_3, R.mipmap.iv_4, R.mipmap.iv_5,
R.mipmap.iv_6, R.mipmap.iv_7, R.mipmap.iv_8};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpager);
BadViewPager pager = findViewById(R.id.viewpager);
List<Map<String, Integer>> strings = new ArrayList<>();
Map<String, Integer> map;
for (int i = 0; i < 20; i++) {
map = new HashMap<>();
map.put("key", iv[i % 9]);
strings.add(map);
}
MyPagerAdapter adapter = new MyPagerAdapter(this, strings);
pager.setAdapter(adapter);
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".MainActivity">
<com.leo.dispatch.BadViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
package com.leo.dispatch;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import androidx.viewpager.widget.PagerAdapter;
import java.util.List;
import java.util.Map;
public class MyPagerAdapter extends PagerAdapter {
private Context mContext;
private List<Map<String, Integer>> mData;
public MyPagerAdapter(Context context, List<Map<String, Integer>> list) {
mContext = context;
mData = list;
}
@Override
public int getCount() {
return 5;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = View.inflate(mContext, R.layout.item_list, null);
ListView list = view.findViewById(R.id.list);
list.setAdapter(new SimpleAdapter(container.getContext(), mData, R.layout.item_base, new String[]{"key"}, new int[]{R.id.iv}));
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
3、内部拦截法
1、MyListView
package com.leo.dispatch;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ListView;
// 子View -- 容器 -- ViewGroup.dispatchTouchEvent --> super.dispatchTouchEvent
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
private int mLastX, mLastY;
/**
* 内部拦截处理
*
* @param event
* @return
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
//请求父容器不拦截
getParent().requestDisallowInterceptTouchEvent(true);
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
// deltaX>deltaY,让父容器拦截,执行父容器的左右滑动
if (Math.abs(deltaX) > Math.abs(deltaY)) {
//请求父容器拦截
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
}
case MotionEvent.ACTION_UP: {
break;
}
default:
break;
}
mLastX = x;
mLastY = y;
return super.dispatchTouchEvent(event);
}
}
2、BadViewPager
package com.leo.dispatch;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;
// 父容器
public class BadViewPager extends ViewPager {
private int mLastX, mLastY;
public BadViewPager(@NonNull Context context) {
super(context);
}
public BadViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
// 内部拦截法
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// down事件的时候不能拦截,因为这个时候 requestDisallowInterceptTouchEvent 无效
if (event.getAction() == MotionEvent.ACTION_DOWN) {
super.onInterceptTouchEvent(event);
return false;
}
return true;
}
}
4、外部拦截法
package com.leo.dispatch;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.ViewPager;
// 父容器
public class BadViewPager extends ViewPager {
private int mLastX, mLastY;
public BadViewPager(@NonNull Context context) {
super(context);
}
public BadViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
// 外部拦截法:一般只需要在父容器处理,根据业务需求,返回true或者false
public boolean onInterceptTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mLastX = (int) event.getX();
mLastY = (int) event.getY();
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
return true;
}
break;
}
case MotionEvent.ACTION_UP: {
break;
}
default:
break;
}
return super.onInterceptTouchEvent(event);
}
}
5、Kotlin 中Math.abs的用法
Kotlin中的Math.abs()函数用于返回一个数的绝对值。它接受一个参数,可以是任何数字类型,包括整数、浮点数等。
例如,以下代码将返回-5的绝对值:
val num = -5
val absNum = Math.abs(num)
println(absNum) // 输出:5
如果参数是正数,则返回该数本身。如果参数是负数,则返回该数的相反数。
网友评论