欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

在android中ScrollView嵌套ScrollView解决方案

程序员文章站 2023-12-04 10:42:28
大家好,众所周知,android里两个相同方向的scrollview是不能嵌套的,那要是有这样的需求怎么办?(这个需求一般都是不懂android的人提出来的)难道就真的不能...
大家好,众所周知,android里两个相同方向的scrollview是不能嵌套的,那要是有这样的需求怎么办?(这个需求一般都是不懂android的人提出来的)

难道就真的不能嵌套吗?当然可以,只要你再写一个scrollview,在里面做点脚,它就支持嵌套了。
目前做的这个只支持两个scrollview嵌套,两个以上还有待改进,能套两个就已经能满足很多需求了,呵呵,另外现在只做了纵向scrollview的支持,横向的还没来的急做哦。
效果截图
在android中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);
}
}