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解决滚动问题。此解决方案适用于我,具有动态内容
在xmlScrollView
putandroid: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)
}
}