android view嵌套,在android中ScrollView嵌套ScrollView解决方案

本文介绍了一种解决方案,如何在Android中绕过限制,让两个同向的ScrollView得以嵌套。通过自定义InnerScrollView组件,通过监听和处理事件,实现了子ScrollView的独立滚动和与父ScrollView的交互。适用于复杂布局需求,已支持纵向滚动,横向支持仍在开发中。
摘要由CSDN通过智能技术生成

大家好,众所周知,android里两个相同方向的ScrollView是不能嵌套的,那要是有这样的需求怎么办?(这个需求一般都是不懂android的人提出来的)

难道就真的不能嵌套吗?当然可以,只要你再写一个ScrollView,在里面做点脚,它就支持嵌套了。

目前做的这个只支持两个ScrollView嵌套,两个以上还有待改进,能套两个就已经能满足很多需求了,呵呵,另外现在只做了纵向scrollview的支持,横向的还没来的急做哦。

效果截图:

3f82e2748c53b0b2aca254c074d8082d.gif 

先上核心代码吧。代码里头我加了注释,方便大家阅读

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);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值