大家好,众所周知,android 里两个相同方向的ScrollView是不能嵌套的,那要是有这样的需求怎么办?(这个需求一般都是不懂android的人提出来的)
难道就真的不能嵌套吗? 当然可以,只要你再写一个ScrollView,在里面做点脚,它就支持嵌套了。
目前做的这个只支持两个ScrollView嵌套,两个以上还有待改进,能套两个就已经能满足很多需求了,呵呵,另外现在只做了纵向scrollview的支持,横向的还没来的急做哦。
效果截图:
先上核心代码吧。代码里头我加了注释,方便大家阅读
难道就真的不能嵌套吗? 当然可以,只要你再写一个ScrollView,在里面做点脚,它就支持嵌套了。
目前做的这个只支持两个ScrollView嵌套,两个以上还有待改进,能套两个就已经能满足很多需求了,呵呵,另外现在只做了纵向scrollview的支持,横向的还没来的急做哦。
效果截图:
先上核心代码吧。代码里头我加了注释,方便大家阅读
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
package
com.sun.shine.study.innerscrollview.view;
import
android.content.Context;
import
android.util.AttributeSet;
import
android.view.MotionEvent;
import
android.view.View;
import
android.widget.ScrollView;
public
class
InnerScrollView
extends
ScrollView {
/**
*/
public
ScrollView parentScrollView;
public
InnerScrollView(Context context, AttributeSet attrs) {
super
(context, attrs);
}
private
int
lastScrollDelta =
0
;
public
void
resume() {
overScrollBy(
0
, -lastScrollDelta,
0
, getScrollY(),
0
, getScrollRange(),
0
,
0
,
true
);
lastScrollDelta =
0
;
}
int
mTop =
10
;
/**
* 将targetView滚到最顶端
*/
public
void
scrollTo(View targetView) {
int
oldScrollY = getScrollY();
int
top = targetView.getTop() - mTop;
int
delatY = top - oldScrollY;
lastScrollDelta = delatY;
overScrollBy(
0
, delatY,
0
, getScrollY(),
0
, getScrollRange(),
0
,
0
,
true
);
}
private
int
getScrollRange() {
int
scrollRange =
0
;
if
(getChildCount() >
0
) {
View child = getChildAt(
0
);
scrollRange = Math.max(
0
, child.getHeight() - (getHeight()));
}
return
scrollRange;
}
int
currentY;
@Override
public
boolean
onInterceptTouchEvent(MotionEvent ev) {
if
(parentScrollView ==
null
) {
return
super
.onInterceptTouchEvent(ev);
}
else
{
if
(ev.getAction() == MotionEvent.ACTION_DOWN) {
// 将父scrollview的滚动事件拦截
currentY = (
int
)ev.getY();
setParentScrollAble(
false
);
return
super
.onInterceptTouchEvent(ev);
}
else
if
(ev.getAction() == MotionEvent.ACTION_UP) {
// 把滚动事件恢复给父Scrollview
setParentScrollAble(
true
);
}
else
if
(ev.getAction() == MotionEvent.ACTION_MOVE) {
}
}
return
super
.onInterceptTouchEvent(ev);
}
@Override
public
boolean
onTouchEvent(MotionEvent ev) {
View child = getChildAt(
0
);
if
(parentScrollView !=
null
) {
if
(ev.getAction() == MotionEvent.ACTION_MOVE) {
int
height = child.getMeasuredHeight();
height = height - getMeasuredHeight();
// System.out.println("height=" + height);
int
scrollY = getScrollY();
// System.out.println("scrollY" + scrollY);
int
y = (
int
)ev.getY();
// 手指向下滑动
if
(currentY < y) {
if
(scrollY <=
0
) {
// 如果向下滑动到头,就把滚动交给父Scrollview
setParentScrollAble(
true
);
return
false
;
}
else
{
setParentScrollAble(
false
);
}
}
else
if
(currentY > y) {
if
(scrollY >= height) {
// 如果向上滑动到头,就把滚动交给父Scrollview
setParentScrollAble(
true
);
return
false
;
}
else
{
setParentScrollAble(
false
);
}
}
currentY = y;
}
}
return
super
.onTouchEvent(ev);
}
/**
* 是否把滚动事件交给父scrollview
*
* @param flag
*/
private
void
setParentScrollAble(
boolean
flag) {
parentScrollView.requestDisallowInterceptTouchEvent(!flag);
}
}
|