Android 在ScrollView中是否可以有一个ViewPager?

Android 在ScrollView中是否可以有一个ViewPager?,android,scrollview,android-viewpager,Android,Scrollview,Android Viewpager,我试图在滚动视图中使用查看页面,但是查看页面没有出现。如果我删除滚动视图,则查看页面显示良好 我创建了一个简单的测试项目,包括以下内容: main.xml布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_wi

我试图在
滚动视图
中使用
查看页面
,但是
查看页面
没有出现。如果我删除
滚动视图
,则
查看页面
显示良好

我创建了一个简单的测试项目,包括以下内容:

main.xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <android.support.v4.view.ViewPager
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent"
            android:id="@+id/viewpager" />

    </ScrollView>
</LinearLayout>

谢谢你的时间。

你为什么要这么做?如果需要的话,更自然的方法是将每个页面包装在一个
滚动视图中


我需要将
android:fillViewport=“true”
添加到ScrollView元素。

是的,可以在ScrollView中使用viewpager

使用下面的代码,您将实现您的目标,我在我的代码中也做了同样的事情

 public class WrapContentHeightViewPager extends ViewPager {

    public WrapContentHeightViewPager(Context context) {
        super(context);
    }

    public WrapContentHeightViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int height = 0;

        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);

            child.measure(widthMeasureSpec, View.MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

            int h = child.getMeasuredHeight();

            if (h > height) height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
 }

 @Override
 public boolean onTouch(View v, MotionEvent event) {
    int dragthreshold = 30;

    int downX = 0;

    int downY = 0;

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downX = (int) event.getRawX();

            downY = (int) event.getRawY();

            break;

        case MotionEvent.ACTION_MOVE:
            int distanceX = Math.abs((int) event.getRawX() - downX);

            int distanceY = Math.abs((int) event.getRawY() - downY);

            if (distanceY > distanceX && distanceY > dragthreshold) {
                mViewPager.getParent().requestDisallowInterceptTouchEvent(false);

                mScrollView.getParent().requestDisallowInterceptTouchEvent(true);
            } else if (distanceX > distanceY && distanceX > dragthreshold) {
                mViewPager.getParent().requestDisallowInterceptTouchEvent(true);

                mScrollView.getParent().requestDisallowInterceptTouchEvent(false);
            }

            break;
        case MotionEvent.ACTION_UP:
            mScrollView.getParent().requestDisallowInterceptTouchEvent(false);

            mViewPager.getParent().requestDisallowInterceptTouchEvent(false);

            break;
    }

    return false;
 }
public类wrapContentheightViewPage扩展了ViewPager{
公共wrapContentHeightViewPage(上下文){
超级(上下文);
}
公共WrapContentHeightViewPage(上下文、属性集属性){
超级(上下文,attrs);
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
超级测量(宽度测量、高度测量);
整数高度=0;
对于(int i=0;i高度)高度=h;
}
heightMeasureSpec=MeasureSpec.MakeMasureSpec(高度,精确测量);
超级测量(宽度测量、高度测量);
}
}
@凌驾
公共布尔onTouch(视图v,运动事件){
int dragthreshold=30;
int-downX=0;
int-downY=0;
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
downX=(int)event.getRawX();
downY=(int)event.getRawY();
打破
case MotionEvent.ACTION\u移动:
int distanceX=Math.abs((int)event.getRawX()-downX);
int distanceY=Math.abs((int)event.getRawY()-downY);
如果(距离>距离X&&distanceY>绘图阈值){
mViewPager.getParent().RequestDisallowWinterCeptTouchEvent(false);
mScrollView.getParent().RequestDisallowWinterCeptTouchEvent(true);
}else if(distanceX>distanceY&&distanceX>dragthreshold){
mViewPager.getParent().RequestDisallowWinterCeptTouchEvent(true);
mScrollView.getParent().RequestDisallowWinterCeptTouchEvent(false);
}
打破
case MotionEvent.ACTION\u UP:
mScrollView.getParent().RequestDisallowWinterCeptTouchEvent(false);
mViewPager.getParent().RequestDisallowWinterCeptTouchEvent(false);
打破
}
返回false;
}

希望这有助于某人在ScrollView中使用嵌套的ViewPager解决滚动问题。

此解决方案适用于我,具有动态内容

在xml
ScrollView
put
android:fillViewport=true
android:layout\u height=wrap\u content


在自定义ViewPager中,也可以使用android:layout\u height=wrap\u content

以防有人遇到同样的问题,当我使用下面的类时,它可以正常工作

class CustomWrapContentViewPager(cont: Context, attr: AttributeSet?) : ViewPager(cont,attr) {

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    var height = 0
    for (i in 0 until childCount) {
        val child: View = getChildAt(i)
        child.measure(
            widthMeasureSpec,
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
        )
        val h: Int = child.measuredHeight
        if (h > height) height = h
    }
    val heightMeasure = MeasureSpec.makeMeasureSpec(
        height,
        MeasureSpec.EXACTLY
    )
    super.onMeasure(widthMeasureSpec, heightMeasure)
    }
}

因为UI就是这样设计的。当您在viewpager中滚动文本时,viewpager上面有一些内容应该向上滚动,这样您就有了更多的阅读空间,但只有viewpager中的文本需要分页,viewpager之外的内容在每个页面上都是相同的,因此无需更改/page that.OK,但从您的代码和描述中很难看出这一点。那么到底是什么问题呢?当ViewPager包装在滚动视图中时,它不会出现。我只在我的问题中包含相关的代码,UI的其他部分对于想要在ScrollView中使用ViewPager没有任何影响。我投了反对票,因为这应该是一个注释,而不是一个answerHey代码攻击,谢谢你的回答。我有垂直滚动的问题吗?它根本不会滚动。你经历过那种行为吗?我这样做无法解决问题。你能分享完整的XML文档吗?解释原因@COdeAttack?@Dolphin ScrollView只用于有一个子项(例如垂直线性布局),ScrollView的默认高度基于线性布局中的内容。假设LinearLayout内部有三个30dp高度视图,那么ScrollView的高度现在是90dp。如果你放置参数表(android:fillViewport=“true”),那么它将使高度匹配/填充父对象。我运气不好:(检查这里的答案:太好了!这成功了。唯一的小问题是所有页面现在都具有相同的高度(意味着可折叠区域高度设置为具有最大高度的页面)。有什么办法可以解决这个问题吗?如果你们否决了这个答案,那么请说明原因,这样其他人就可以知道使用这个解决方案的缺点。谢谢我否决了你们的解决方案,因为如果你们在浏览页面的子视图中有不同的内容大小,你们总是得到最大的一个。为了获得更准确的解决方案对于这种类型的问题,请使用@Abhishek V:@Ricardosusadev提供的解决方案。谢谢您确定了问题,但是您可以用这些方法改进我的答案,使其成为更好的答案。因为人们通常不会阅读答案中写的所有注释。我只使用了WrapcontheightViewPager w无需覆盖即可工作。谢谢。fillViewport不是FullViewport
class CustomWrapContentViewPager(cont: Context, attr: AttributeSet?) : ViewPager(cont,attr) {

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    var height = 0
    for (i in 0 until childCount) {
        val child: View = getChildAt(i)
        child.measure(
            widthMeasureSpec,
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
        )
        val h: Int = child.measuredHeight
        if (h > height) height = h
    }
    val heightMeasure = MeasureSpec.makeMeasureSpec(
        height,
        MeasureSpec.EXACTLY
    )
    super.onMeasure(widthMeasureSpec, heightMeasure)
    }
}