我必须在scrollview中显示一个viewpager(pager行中图像下方的图像和文本)。我正在从网上下载图像,文本并在寻呼机行中显示。我在srollview中包含了viewpager以支持横向模式。
<com.xxx.myapp.android.ui.CustomScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fadingEdge="none"
android:fillViewport="true"
android:gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="800dp"
android:layout_gravity="top"
android:layout_marginTop="10dp" />
</LinearLayout>
</com.xxx.myapp.android.ui.CustomScrollView>
这是CustomScrollView。问题是如何根据子高度设置视图寻呼机高度,以便我可以滚动屏幕直到视图寻呼机项目结束。如果我将view pager height设置为wrapcontent,则viewpager中不会显示任何内容。如果我设置了800dp,那么我可以看到寻呼机项目,但屏幕上有不必要的滚动。我不希望我的滚动视图滚动超出寻呼机儿童的高度。请帮我。
答案 0 :(得分:23)
要修复viewpager的高度,我们可以自定义viewpager类。
public class WrapContentViewPager extends ViewPager {
private int mCurrentPagePosition = 0;
public WrapContentViewPager(Context context) {
super(context);
}
public WrapContentViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
View child = getChildAt(mCurrentPagePosition);
if (child != null) {
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
}
} catch (Exception e) {
e.printStackTrace();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void reMeasureCurrentPage(int position) {
mCurrentPagePosition = position;
requestLayout();
}
}
这个reMeasureCurrentPage应该在viewpager上调用onPageSelected callback.and CustomScrollView是父视图。
答案 1 :(得分:9)
mViewPager = new ViewPager(mContext) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
View view = getChildAt(this.getCurrentItem());
if (view != null) {
view.measure(widthMeasureSpec, heightMeasureSpec);
}
setMeasuredDimension(getMeasuredWidth(), measureHeight(heightMeasureSpec, view));
}
private int measureHeight(int measureSpec, View view) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
// set the height from the base view if available
if (view != null) {
result = view.getMeasuredHeight();
}
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
};
答案 2 :(得分:4)
试试这种方式
<com.xxx.myapp.android.ui.CustomScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:fadingEdge="none"
android:fillViewport="true"
android:gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
android:layout_marginTop="10dp" />
</LinearLayout>
</com.xxx.myapp.android.ui.CustomScrollView>
答案 3 :(得分:0)
这是最好,最简单的解决方案:
1)在您自定义的ViewPager类中-
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var heightMeasureSpec = heightMeasureSpec
val mode = MeasureSpec.getMode(heightMeasureSpec)
// Unspecified means that the ViewPager is in a ScrollView WRAP_CONTENT.
// At Most means that the ViewPager is not in a ScrollView WRAP_CONTENT.
if (mode == MeasureSpec.UNSPECIFIED || mode == MeasureSpec.AT_MOST) {
// super has to be called in the beginning so the child views can be initialized.
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
var height = 0
for (i in 0 until childCount) {
val child = getChildAt(i)
child.measure(
widthMeasureSpec,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
)
val h = child.measuredHeight
if (h > height) height = h
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
}
// super has to be called again so the new specs are treated as exact measurements
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
2)在将适配器设置为ViewPager时-
val viewPagerAdapter = ViewPagerAdapter(fragmentList, supportFragmentManager)
view_pager.adapter = viewPagerAdapter
view_pager.measure(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT)`
view_pager.currentItem = 0
答案 4 :(得分:-1)
将您的寻呼机行包装在CustomScrollView中,而不是将寻呼机包装在CustomScrollview中。并且不要像Piyush Gupath评论的那样修复Viewpager的高度。使用wrapcontent。