网站用什么开发,杭州西湖区网站建设,做个商城网站怎么做便宜吗,嘉兴新闻头条最新消息1. 内部拦截法#xff1a; 父容器不拦截事件#xff0c;所有的事件全部都传递给子元素#xff0c;如果子元素需要此事件就直接消耗掉#xff0c;否则就交给父容器进行处理。 这种方法和Android中的事件分发机制不一样#xff0c;需要配合requestDisallowInterceptTouchEve…1. 内部拦截法 父容器不拦截事件所有的事件全部都传递给子元素如果子元素需要此事件就直接消耗掉否则就交给父容器进行处理。 这种方法和Android中的事件分发机制不一样需要配合requestDisallowInterceptTouchEvent方法才能正常工作使用起来较外部拦截法稍显负责一点。 我们需要重写子元素的dispatchTouchEvent方法。 这种方法的伪代码是 1 Override2 public boolean dispatchTouchEvent(MotionEvent event) {3 int x (int) event.getX();4 int y (int) event.getY();5 6 switch (event.getAction()) {7 case MotionEvent.ACTION_DOWN: {8 parent.requestDisallowInterceptTouchEvent(true);9 break;
10 }
11 case MotionEvent.ACTION_MOVE: {
12 int deltaX x - mLastX;
13 int deltaY y - mLastY;
14 if (父容器需要此类点击事件) {
15 parent.requestDisallowInterceptTouchEvent(false);
16 }
17 break;
18 }
19 case MotionEvent.ACTION_UP: {
20 break;
21 }
22 default:
23 break;
24 }
25
26 mLastX x;
27 mLastY y;
28 return super.dispatchTouchEvent(event);
29 } 上面重写的子元素的dispatchTouchEvent方法这里同时需要重写父容器的onInterceptTouchEvent方法为什么呢 那是因为ACTION_DOWN事件并不受FLAG_DISALLOW_INTERCEPT这个标记位的控制所以一旦父容器拦截ACTION_DOWN事件那么所有的事件都无法传递到子元素之中这样内部拦截法就无法起作用了。 父容器所做的修改如下 1 Override2 public boolean onInterceptTouchEvent(MotionEvent event) {3 4 int action event.getAction();5 if (action MotionEvent.ACTION_DOWN) {6 return false;7 } else {8 return true;9 }
10 } 2. 下面通过一个Demo示例说明 1首先我们创建一个Android工程如下 2首先我们来到主布局activity_main.xml如下 1 com.himi.viewconflict1.ui.RevealLayout2 xmlns:androidhttp://schemas.android.com/apk/res/android3 xmlns:toolshttp://schemas.android.com/tools4 android:layout_widthmatch_parent5 android:layout_heightmatch_parent6 android:orientationvertical7 android:padding12dp8 tools:context${relativePackage}.${activityClass} 9
10 Button
11 android:idid/button1
12 stylestyle/AppTheme.Button.Green
13 android:onClickonButtonClick
14 android:text滑动冲突场景1-内部拦截 /
15
16 /com.himi.viewconflict1.ui.RevealLayout 3接下来来到MainActivity如下 1 package com.himi.viewconflict;2 3 import android.app.Activity;4 import android.content.Intent;5 import android.os.Bundle;6 import android.view.View;7 8 public class MainActivity extends Activity {9
10 Override
11 protected void onCreate(Bundle savedInstanceState) {
12 super.onCreate(savedInstanceState);
13 setContentView(R.layout.activity_main);
14 }
15
16
17
18 public void onButtonClick(View view) {
19 Intent intent new Intent(this, DemoActivity_1.class);
20 startActivity(intent);
21 }
22 } 4上面很自然地跳转到DemoActivity_2之中如下 1 package com.himi.viewconflict1;2 3 import java.util.ArrayList;4 5 import com.himi.viewconflict1.ui.HorizontalScrollViewEx2;6 import com.himi.viewconflict1.ui.ListViewEx;7 import com.himi.viewconflict1.utils.MyUtils;8 9 import android.app.Activity;
10 import android.graphics.Color;
11 import android.os.Bundle;
12 import android.util.Log;
13 import android.view.LayoutInflater;
14 import android.view.MotionEvent;
15 import android.view.View;
16 import android.view.ViewGroup;
17 import android.widget.AdapterView;
18 import android.widget.AdapterView.OnItemClickListener;
19 import android.widget.ArrayAdapter;
20 import android.widget.TextView;
21 import android.widget.Toast;
22
23 public class DemoActivity_2 extends Activity {
24 private static final String TAG DemoActivity_2;
25
26 private HorizontalScrollViewEx2 mListContainer;
27
28 Override
29 protected void onCreate(Bundle savedInstanceState) {
30 super.onCreate(savedInstanceState);
31 setContentView(R.layout.demo_2);
32 Log.d(TAG, onCreate);
33 initView();
34 }
35
36 private void initView() {
37 LayoutInflater inflater getLayoutInflater();
38 mListContainer (HorizontalScrollViewEx2) findViewById(R.id.container);
39 final int screenWidth MyUtils.getScreenMetrics(this).widthPixels;
40 final int screenHeight MyUtils.getScreenMetrics(this).heightPixels;
41 for (int i 0; i 3; i) {
42 ViewGroup layout (ViewGroup) inflater.inflate(
43 R.layout.content_layout2, mListContainer, false);
44 layout.getLayoutParams().width screenWidth;
45 TextView textView (TextView) layout.findViewById(R.id.title);
46 textView.setText(page (i 1));
47 layout.setBackgroundColor(Color
48 .rgb(255 / (i 1), 255 / (i 1), 0));
49 createList(layout);
50 mListContainer.addView(layout);
51 }
52 }
53
54 private void createList(ViewGroup layout) {
55 ListViewEx listView (ListViewEx) layout.findViewById(R.id.list);
56 ArrayListString datas new ArrayListString();
57 for (int i 0; i 50; i) {
58 datas.add(name i);
59 }
60 ArrayAdapterString adapter new ArrayAdapterString(this,
61 R.layout.content_list_item, R.id.name, datas);
62 listView.setAdapter(adapter);
63 listView.setHorizontalScrollViewEx2(mListContainer);
64 listView.setOnItemClickListener(new OnItemClickListener() {
65 Override
66 public void onItemClick(AdapterView? parent, View view,
67 int position, long id) {
68 Toast.makeText(DemoActivity_2.this, click item position,
69 Toast.LENGTH_SHORT).show();
70
71 }
72 });
73 }
74
75 Override
76 public boolean dispatchTouchEvent(MotionEvent ev) {
77 Log.d(TAG, dispatchTouchEvent action: ev.getAction());
78 return super.dispatchTouchEvent(ev);
79 }
80
81 Override
82 public boolean onTouchEvent(MotionEvent event) {
83 Log.d(TAG, onTouchEvent action: event.getAction());
84 return super.onTouchEvent(event);
85 }
86 } 上面的DemoActivity_2主布局demo_2.xml如下 1 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android2 xmlns:toolshttp://schemas.android.com/tools3 android:layout_widthmatch_parent4 android:layout_heightmatch_parent5 android:background#ffffff6 android:orientationvertical 7 8 com.himi.viewconflict1.ui.HorizontalScrollViewEx29 android:idid/container
10 android:layout_widthwrap_content
11 android:layout_heightmatch_parent /
12
13
14 /LinearLayout 上面使用到HorizontalScrollViewEx2是自定义控件继承自ViewGroup如下 HorizontalScrollViewEx2是父容器这里需要重写它的onInterceptTouchEvent方法让父容器不拦截ACTION_DOWN事件。 1 package com.himi.viewconflict1.ui;2 3 import android.content.Context;4 import android.util.AttributeSet;5 import android.util.Log;6 import android.view.MotionEvent;7 import android.view.VelocityTracker;8 import android.view.View;9 import android.view.ViewGroup;10 import android.widget.Scroller;11 12 public class HorizontalScrollViewEx2 extends ViewGroup {13 private static final String TAG HorizontalScrollViewEx2;14 15 private int mChildrenSize;16 private int mChildWidth;17 private int mChildIndex;18 // 分别记录上次滑动的坐标19 private int mLastX 0;20 private int mLastY 0;21 22 // 分别记录上次滑动的坐标(onInterceptTouchEvent)23 private int mLastXIntercept 0;24 private int mLastYIntercept 0;25 26 private Scroller mScroller;27 private VelocityTracker mVelocityTracker;28 29 public HorizontalScrollViewEx2(Context context) {30 super(context);31 init();32 }33 34 public HorizontalScrollViewEx2(Context context, AttributeSet attrs) {35 super(context, attrs);36 init();37 }38 39 public HorizontalScrollViewEx2(Context context, AttributeSet attrs,40 int defStyle) {41 super(context, attrs, defStyle);42 init();43 }44 45 private void init() {46 mScroller new Scroller(getContext());47 mVelocityTracker VelocityTracker.obtain();48 }49 50 Override51 public boolean onInterceptTouchEvent(MotionEvent event) {52 int x (int) event.getX();53 int y (int) event.getY();54 int action event.getAction();55 if (action MotionEvent.ACTION_DOWN) {56 mLastX x;57 mLastY y;58 if (!mScroller.isFinished()) {59 mScroller.abortAnimation();60 return true;61 }62 return false;63 } else {64 return true;65 }66 }67 68 Override69 public boolean onTouchEvent(MotionEvent event) {70 Log.d(TAG, onTouchEvent action: event.getAction());71 mVelocityTracker.addMovement(event);72 int x (int) event.getX();73 int y (int) event.getY();74 switch (event.getAction()) {75 case MotionEvent.ACTION_DOWN: {76 if (!mScroller.isFinished()) {77 mScroller.abortAnimation();78 }79 break;80 }81 case MotionEvent.ACTION_MOVE: {82 int deltaX x - mLastX;83 int deltaY y - mLastY;84 Log.d(TAG, move, deltaX: deltaX deltaY: deltaY);85 scrollBy(-deltaX, 0);86 break;87 }88 case MotionEvent.ACTION_UP: {89 int scrollX getScrollX();90 int scrollToChildIndex scrollX / mChildWidth;91 Log.d(TAG, current index: scrollToChildIndex);92 mVelocityTracker.computeCurrentVelocity(1000);93 float xVelocity mVelocityTracker.getXVelocity();94 if (Math.abs(xVelocity) 50) {95 mChildIndex xVelocity 0 ? mChildIndex - 1 : mChildIndex 1;96 } else {97 mChildIndex (scrollX mChildWidth / 2) / mChildWidth;98 }99 mChildIndex Math.max(0, Math.min(mChildIndex, mChildrenSize - 1));
100 int dx mChildIndex * mChildWidth - scrollX;
101 smoothScrollBy(dx, 0);
102 mVelocityTracker.clear();
103 Log.d(TAG, index: scrollToChildIndex dx: dx);
104 break;
105 }
106 default:
107 break;
108 }
109
110 mLastX x;
111 mLastY y;
112 return true;
113 }
114
115 Override
116 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
117 super.onMeasure(widthMeasureSpec, heightMeasureSpec);
118 int measuredWidth 0;
119 int measuredHeight 0;
120 final int childCount getChildCount();
121 measureChildren(widthMeasureSpec, heightMeasureSpec);
122
123 int widthSpaceSize MeasureSpec.getSize(widthMeasureSpec);
124 int widthSpecMode MeasureSpec.getMode(widthMeasureSpec);
125 int heightSpaceSize MeasureSpec.getSize(heightMeasureSpec);
126 int heightSpecMode MeasureSpec.getMode(heightMeasureSpec);
127 if (childCount 0) {
128 setMeasuredDimension(0, 0);
129 } else if (heightSpecMode MeasureSpec.AT_MOST) {
130 final View childView getChildAt(0);
131 measuredHeight childView.getMeasuredHeight();
132 setMeasuredDimension(widthSpaceSize, childView.getMeasuredHeight());
133 } else if (widthSpecMode MeasureSpec.AT_MOST) {
134 final View childView getChildAt(0);
135 measuredWidth childView.getMeasuredWidth() * childCount;
136 setMeasuredDimension(measuredWidth, heightSpaceSize);
137 } else {
138 final View childView getChildAt(0);
139 measuredWidth childView.getMeasuredWidth() * childCount;
140 measuredHeight childView.getMeasuredHeight();
141 setMeasuredDimension(measuredWidth, measuredHeight);
142 }
143 }
144
145 Override
146 protected void onLayout(boolean changed, int l, int t, int r, int b) {
147 Log.d(TAG, width: getWidth());
148 int childLeft 0;
149 final int childCount getChildCount();
150 mChildrenSize childCount;
151
152 for (int i 0; i childCount; i) {
153 final View childView getChildAt(i);
154 if (childView.getVisibility() ! View.GONE) {
155 final int childWidth childView.getMeasuredWidth();
156 mChildWidth childWidth;
157 childView.layout(childLeft, 0, childLeft childWidth,
158 childView.getMeasuredHeight());
159 childLeft childWidth;
160 }
161 }
162 }
163
164 private void smoothScrollBy(int dx, int dy) {
165 mScroller.startScroll(getScrollX(), 0, dx, 0, 500);
166 invalidate();
167 }
168
169 Override
170 public void computeScroll() {
171 if (mScroller.computeScrollOffset()) {
172 scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
173 postInvalidate();
174 }
175 }
176
177 Override
178 protected void onDetachedFromWindow() {
179 mVelocityTracker.recycle();
180 super.onDetachedFromWindow();
181 }
182 } 5来到主布局之中在HorizontalScrollViewEx2之中包含一个子布局content_layout2.xml如下 1 ?xml version1.0 encodingutf-8?2 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android3 android:layout_widthmatch_parent4 android:layout_heightmatch_parent5 android:orientationvertical 6 7 TextView8 android:idid/title9 android:layout_widthwrap_content
10 android:layout_heightwrap_content
11 android:layout_marginTop5dp
12 android:layout_marginBottom5dp
13 android:textTextView /
14
15 com.himi.viewconflict1.ui.ListViewEx
16 android:idid/list
17 android:layout_widthmatch_parent
18 android:layout_heightmatch_parent
19 android:background#fff4f7f9
20 android:cacheColorHint#00000000
21 android:divider#dddbdb
22 android:dividerHeight1.0px
23 android:listSelectorandroid:color/transparent /
24
25 /LinearLayout 上面的ListViewEx是自定义的控件继承自ListView在ListViewEx里面实现了内部拦截法的逻辑如下 1 package com.himi.viewconflict1.ui;2 3 import android.content.Context;4 import android.util.AttributeSet;5 import android.util.Log;6 import android.view.MotionEvent;7 import android.widget.ListView;8 9 public class ListViewEx extends ListView {
10 private static final String TAG ListViewEx;
11
12 private HorizontalScrollViewEx2 mHorizontalScrollViewEx2;
13
14 // 分别记录上次滑动的坐标
15 private int mLastX 0;
16 private int mLastY 0;
17
18 public ListViewEx(Context context) {
19 super(context);
20 }
21
22 public ListViewEx(Context context, AttributeSet attrs) {
23 super(context, attrs);
24 }
25
26 public ListViewEx(Context context, AttributeSet attrs, int defStyle) {
27 super(context, attrs, defStyle);
28 }
29
30 public void setHorizontalScrollViewEx2(
31 HorizontalScrollViewEx2 horizontalScrollViewEx2) {
32 mHorizontalScrollViewEx2 horizontalScrollViewEx2;
33 }
34
35 Override
36 public boolean dispatchTouchEvent(MotionEvent event) {
37 int x (int) event.getX();
38 int y (int) event.getY();
39
40 switch (event.getAction()) {
41 case MotionEvent.ACTION_DOWN: {
42 mHorizontalScrollViewEx2.requestDisallowInterceptTouchEvent(true);
43 break;
44 }
45 case MotionEvent.ACTION_MOVE: {
46 int deltaX x - mLastX;
47 int deltaY y - mLastY;
48 Log.d(TAG, dx: deltaX dy: deltaY);
49 if (Math.abs(deltaX) Math.abs(deltaY)) {
50 mHorizontalScrollViewEx2.requestDisallowInterceptTouchEvent(false);
51 }
52 break;
53 }
54 case MotionEvent.ACTION_UP: {
55 break;
56 }
57 default:
58 break;
59 }
60
61 mLastX x;
62 mLastY y;
63 return super.dispatchTouchEvent(event);
64 }
65
66 } void requestDisallowInterceptTouchEventboolean disallowIntercept 这个方法的入参一个boolean 变量用来表示是否需要调用onInterceptTouchEvent来判断是否拦截. 该标记如果为True就如它的字面意思一样---不允许调用onInterceptTouchEvent()结果就是所有的父类方法都不会进行拦截而把事件传递给子View. 该方法属于ViewGroup 并且是个递归方法也就是说一旦调用后所有父类的disallowIntercept都会设置成True。即当前View的所有父类View都不会调用自身的onInterceptTouchEvent()进行拦截。 该标记如果为False就如它的字面意思一样---允许调用onInterceptTouchEvent()结果就是父类可以拦截事件。 接下来来到Listview的Item布局content_list_item.xml如下 1 ?xml version1.0 encodingutf-8?2 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android3 android:layout_widthmatch_parent4 android:layout_height50dp5 android:gravitycenter_vertical6 android:orientationvertical 7 8 TextView9 android:idid/name
10 android:layout_widthwrap_content
11 android:layout_heightwrap_content
12 android:textTextView /
13
14 /LinearLayout 6最终项目如下 7部署程序到手机上如下 3. 示例源码下载 转载于:https://www.cnblogs.com/hebao0514/p/5700730.html