在android中ScrollView嵌套ScrollView解决方案
程序员文章站
2023-12-04 10:42:28
大家好,众所周知,android里两个相同方向的scrollview是不能嵌套的,那要是有这样的需求怎么办?(这个需求一般都是不懂android的人提出来的)难道就真的不能...
大家好,众所周知,android里两个相同方向的scrollview是不能嵌套的,那要是有这样的需求怎么办?(这个需求一般都是不懂android的人提出来的)
难道就真的不能嵌套吗?当然可以,只要你再写一个scrollview,在里面做点脚,它就支持嵌套了。
目前做的这个只支持两个scrollview嵌套,两个以上还有待改进,能套两个就已经能满足很多需求了,呵呵,另外现在只做了纵向scrollview的支持,横向的还没来的急做哦。
效果截图:
先上核心代码吧。代码里头我加了注释,方便大家阅读
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);
}
}
难道就真的不能嵌套吗?当然可以,只要你再写一个scrollview,在里面做点脚,它就支持嵌套了。
目前做的这个只支持两个scrollview嵌套,两个以上还有待改进,能套两个就已经能满足很多需求了,呵呵,另外现在只做了纵向scrollview的支持,横向的还没来的急做哦。
效果截图:
先上核心代码吧。代码里头我加了注释,方便大家阅读
复制代码 代码如下:
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);
}
}
推荐阅读
-
在android中ScrollView嵌套ScrollView解决方案
-
探讨:如何在ScrollView中嵌套ListView
-
Android ScrollView 下嵌套 ListView 或 GridView出现问题解决办法
-
Android之ScrollView嵌套ListView和GridView冲突的解决方法
-
Android笔记之:在ScrollView中嵌套ListView的方法
-
Android 中ScrollView嵌套GridView,ListView的实例
-
Android中ScrollView 滑到头部或尾部可伸缩放大效果
-
Android编程开发ScrollView中ViewPager无法正常滑动问题解决方法
-
Android ScrollView嵌套横向滑动控件时冲突问题
-
探讨:如何在ScrollView中嵌套ListView