Viewpager与动力高度不工作(总使用第一个片段的高度) [英] Viewpager with dynamic height not working (always use the first fragment's height)

查看:137
本文介绍了Viewpager与动力高度不工作(总使用第一个片段的高度)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照和<一href="http://stackoverflow.com/questions/8394681/android-i-am-unable-to-have-viewpager-wrap-content">that答案,我还发现链接。

I have followed this and that answers, i also found this link.

我用这些资源做试验和放大器;错误。现在,我的自定义 ViewPager 成功地测量它的内容,,但只有第一个显示的。仅供参考,我的 ViewPager 包含一些复杂的看法,如 ExpendableListView - 这就是为什么没有一个code。在这些资源工作完美,我需要通过自己修改code。

I use those resources to do trial & errors. Now my custom ViewPager successfully measure its content, but only the first one displayed. FYI, my ViewPager holds some complex views, like ExpendableListView - thats why none of the code in those resources working perfectly, i need to modify the code by myself.

我有4个片段(内容),所以我用 pager.setOffscreenPageLimit(3);

I have 4 fragments (content), so i use pager.setOffscreenPageLimit(3);

这是我的自定义 ViewPager

public class CustomViewPager extends ViewPager{

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

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

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

        boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST;

        final View tab = getChildAt(0);
        int width = getMeasuredWidth();
        int tabHeight = tab.getMeasuredHeight();

        if (wrapHeight) {
            // Keep the current measured width.
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
        }

        int fragmentHeight = measureFragment(((Fragment) getAdapter().instantiateItem(this, getCurrentItem())).getView());
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(tabHeight + fragmentHeight + (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()), MeasureSpec.AT_MOST);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public int measureFragment(View view) {
        if (view == null)
            return 0;

        view.measure(0, 0);
        return view.getMeasuredHeight();
    }
}

这是我的 CustomPagerTabStrip

int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
android.view.ViewGroup.LayoutParams params =  getLayoutParams();
params.height = getMeasuredHeight();

这是我的XML:

And this is my XML :

        <RelativeLayout
            android:id="@+id/relativePager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <com.xxx.yyy.util.CustomViewPager
                android:id="@+id/detailPager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

                <com.xxx.yyy.util.CustomPagerTabStrip
                    android:id="@+id/detailTab"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#161C28"
                    android:textColor="#FFFFFF" />
            </com.xxx.yyy.util.CustomViewPager>

        </RelativeLayout>

情况的例子:

如果第一个碎片的身高是100像素,那么所有其他的碎片会留在100px的。 因此,如果在第二片段的高度是130px,它将被削减为100px

If the first fragment's height is 100px, then all of other fragments will stay on 100px. So if the second fragment's height is 130px, it will be cut to 100px.

当我试图调试 onMeasure 我的 CustomViewPager 总是叫4次创建活动时,但它们都只能读取第一个片段。该 onMeasure 永远获取调用后再次,即使当我改变(幻灯片左,右/)从一个片段等。

When i tried to debug, the onMeasure on my CustomViewPager always called 4 times when the Activity is created, but all of them only read the first fragment. The onMeasure never getting called again after that, even when i change (slide left/right) from one fragment to other.

请帮我了,我已经spended很多时间让这件事的工作。 只要问我,如果你需要更多的信息,感谢您的时间。

Please help me out, i have spended lot of hours to get this thing working. Just ask me if you need more information, Thanks for your time.

推荐答案

大火喜发现了一些东西用满了,下面的解决方案是为我工作。

它包括一个自定义的滚动视图和自定义视图寻呼机。其目的自定义视图寻呼机是它的计算动态地根据其儿童身高的高度,其hieght设为初始包装内容和滚动视图目的就是处理触摸事件,如果用户滚动屏幕垂直方向也不会通过触摸甚至滚动并且因此用户能够滚动页面。

Hi Blaze found some thing use full, following solution is working for me.

Its include a custom scroll view and custom view pager. The purpose custom view pager is its calculate the height dynamically according to its children's height, its hieght is set to wrap content initially and the purpose of scroll view is handling the touch event , if the users scrolls the screen vertically it will not pass the touch even to scroll and thus user is able to scroll the page.

自定义滚动视图

public class CustomScrollView extends ScrollView {

private GestureDetector mGestureDetector;

public CustomScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    mGestureDetector = new GestureDetector(context, new YScrollDetector());
    setFadingEdgeLength(0);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return super.onInterceptTouchEvent(ev)
            && mGestureDetector.onTouchEvent(ev);
}

// Return false if we're scrolling in the x direction
class YScrollDetector extends SimpleOnGestureListener {
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
            float distanceX, float distanceY) {
        return (Math.abs(distanceY) > Math.abs(distanceX));
    }
}

}

自定义视图寻呼机

public class CustomPager extends ViewPager{

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

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

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

    boolean wrapHeight = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST;

    final View tab = getChildAt(0);
    int width = getMeasuredWidth();
    int tabHeight = tab.getMeasuredHeight();

    if (wrapHeight) {
        // Keep the current measured width.
        widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
    }

    int fragmentHeight = measureFragment(((Fragment) getAdapter().instantiateItem(this, getCurrentItem())).getView());
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(tabHeight + fragmentHeight + (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()), MeasureSpec.AT_MOST);

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public int measureFragment(View view) {
    if (view == null)
        return 0;

    view.measure(0, 0);
    return view.getMeasuredHeight();
}

}

布局文件

<com.example.demo2.activity.widget.CustomScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        style="@style/text"
        android:text="Text 1" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 2" />


        <com.example.demo2.activity.widget.CustomPager
          android:id="@+id/myViewPager"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 4" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 5" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 6" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 7" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 8" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 9" />

    <View style="@style/text_divider" />

    <TextView
        style="@style/text"
        android:text="Text 10" />
</LinearLayout>

活动

public class MainActivity extends FragmentActivity {



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    MyPagerAdapter pageAdapter = new MyPagerAdapter(getSupportFragmentManager());
    ViewPager pager = (ViewPager)findViewById(R.id.myViewPager);
    pager.setAdapter(pageAdapter);

}



}

片段适配器

用不同高度的片段加入到viewpager,FragmentBlue,绿等只是片段用于添加到您可以使用自己的片段viewpager,有一点要记住的是它们的外部布局应该是在我的情况下,我用眼线一样对于所有的布局

fragments with different heights are added to the viewpager, FragmentBlue,Green etc are just fragments used to add to the viewpager you can use your own fragments, one thing to remember is their outer layout should be same in my case I used liner layout for all

public class MyPagerAdapter extends FragmentPagerAdapter {

private List<Fragment> fragments;

public MyPagerAdapter(FragmentManager fm) {
    super(fm);
    this.fragments = new ArrayList<Fragment>();
    fragments.add(new FragmentBlue());
    fragments.add(new FragmentGreen());
    fragments.add(new FragmentPink());
    fragments.add(new FragmentRed());
}

@Override
public Fragment getItem(int position) {
    return fragments.get(position);
}

@Override
public int getCount() {
    return fragments.size();
}
 }

这篇关于Viewpager与动力高度不工作(总使用第一个片段的高度)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆