具有动态高度的 Viewpager 不起作用(始终使用第一个片段的高度)

2024-03-25

我已关注this https://stackoverflow.com/questions/9313554/measuring-a-viewpager and that https://stackoverflow.com/questions/8394681/android-i-am-unable-to-have-viewpager-wrap-content答案,我也找到了this http://www.henning.ms/2013/09/09/viewpager-that-simply-dont-measure-up/ link.

我使用这些资源来进行试验和错误。现在我的习惯ViewPager成功测量其含量,但只显示第一个。仅供参考,我的ViewPager持有一些复杂的观点,比如ExpendableListView- 这就是为什么这些资源中的代码都不能完美运行,我需要自己修改代码。

我有 4 个片段(内容),所以我使用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:

        <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 像素,则所有其他片段将保持在 100 像素。 因此,如果第二个片段的高度为 130px,它将被剪切为 100px。

当我尝试调试时, the onMeasure on my CustomViewPager总是调用 4 次Activity已创建,但它们都只读取第一个片段。这onMeasure never之后再次被调用,即使我从一个片段更改(向左/向右滑动)到另一个片段也是如此。

请帮助我,我花了很多时间来让这个东西工作。 如果您需要更多信息,请询问我,感谢您的宝贵时间。


您好,Blaze 发现有些东西已完全使用,以下解决方案对我有用。

它包括自定义滚动视图和自定义视图寻呼机。自定义视图分页器的目的是根据其子项的高度动态计算高度,其高度最初设置为包裹内容,滚动视图的目的是处理触摸事件,如果用户垂直滚动屏幕,则不会传递触摸甚至滚动,因此用户可以滚动页面。

自定义滚动视图

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>

Activity

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,Green等只是用于添加到viewpager的片段,您可以使用自己的片段,要记住的一件事是它们的外部布局在我的情况下应该相同,我对所有片段都使用了衬垫布局

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();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有动态高度的 Viewpager 不起作用(始终使用第一个片段的高度) 的相关文章

随机推荐

  • Code First 实体框架多对多关系

    谁能指出我哪里错了 我创建了两个简单的类 具有多对多的关系 工作正常 所有表都已正确填充 除了当我尝试检索任何学生课程时 什么都没有返回 public partial class Student public Student Courses
  • 如何使用 DataBinding Framework MVVM 在 EditText 上设置错误

    我正在使用 Android 数据绑定框架 我假设有一个用于登录表单的 EditText 用户名如下
  • 如何在 popper-js 中显示箭头

    我正在尝试使用popper js https popper js org index html 但我很难阅读文档并让事情正常运行 我似乎无法理解arrow显示 指向引用元素的三角形 下面的代码缩小了我想要做的事情 弹出器显示并定位在内容加载
  • csv 模块返回第一列的 BOM

    我有一个 csv 文件 格式如下 type type mapping style style mapping Count Residential Residential Antique Antique 109 Antique Residen
  • Azure Key Vault - 编程创建

    如何在 NET Core 应用程序中使用 C 以编程方式创建 Azure KeyVault 我看过之后写入和读取密钥库的示例 它是配置的 但不是在创建 kv 本身时进行的 使用方法VaultsOperationsExtensions Cre
  • 滚动顶部动画后滚动/滚动条锁定

    我有一些链接到页面内特定部分 使用主题标签 的锚点 以及滚动到文档窗口顶部或底部的锚点 html body animate scrollTop document height 2000 但是 一旦动画和滚动到达目的地并完成 文档滚动和滚动条
  • 多选编辑表单选定值

    在 Laravel 4 中遇到一个问题时 在 联系人 模型编辑表单中 我可以获得所有字段的当前值 除了用于与另一个模型 公司 建立关系的多重选择的字段值 这是一种多对多的关系 我正在获取公司列表 但即使存在关系 也没有选择任何公司 这是我的
  • 如何解决WPF表单调整大小-控件滞后和黑色背景?

    我有一个非常简单的 WPF 窗口 其中唯一的东西是一个右对齐按钮 当我通过拖动左边界来调整窗口大小时 按钮会跳很多次 自己尝试一下 来回拖动左侧边界 此外 在调整大小期间 黑色背景会暂时暴露 In this https stackoverf
  • RSpec+Capybara 请求规范 w/JS 不起作用

    使用 Javascript 时我无法使请求规范正常工作 我的规格pass如果我在没有 Javascript 的情况下运行它们 页面构建为可以使用或不使用 JS 具体来说 当我进行如下断言时 规范会失败Post should have 1 r
  • 如何在pycharm中将部分文件(帅哥)提交到git

    我是 Eclipse PyDev EGit 的重度用户 希望切换到 PyCharm 在 Eclipse 中 我可以选择仅将文件的某些块 行添加到 git 索引 与使用相同git add p从航站楼 我发现通过 GUI 执行此操作更快 并且我
  • 如何将现有的嵌套存储库(已在子目录中签出)作为子模块添加到父 Git 存储库?

    如果我从工作 父 目录创建初始提交 但存在具有独立签出的 git 存储库的子目录 会发生什么情况 我只是做了git add 但这给我带来了一个奇怪的情况 即具有嵌套 Git 存储库的子目录未注册为父存储库的子模块 那么 在初始 git ad
  • 如何在R中生成偏态正态分布的随机数?

    我正在尝试生成 1000 组 130 个随机数 这些随机数符合以下数字的偏态正态分布 10 4 9 3 6 8 4 8 5 7 5 8 4 5 3 4 2 0 3 0 4 4 1 6 9 5 9 2 5 2 2 8 3 2 4 4 2 1
  • linux shell 终止信号 SIGKILL && KILL

    我刚刚写了一个shell脚本来控制模块的启动和停止 一切看起来都很正常 直到我发现停止命令导致了意想不到的结果 我使用命令kill s SIGKILL gpid杀死一组进程 我用 bin sh像这样运行命令 bin sh c kill s
  • 使用联合类型进行对象字面量分配时,打字稿类型丢失

    我预计以下代码会出现错误 但对于打字稿来说完全没问题 你能告诉我为什么吗 export interface Type1 command number export interface Type2 children string export
  • 使用 javascript 检查 url 内容类型

    为了节省服务器资源 我正在寻找一种使用 javascript 检索给定 url 的内容类型的方法 它不应仅从标题下载 URL 的完整内容 javascript 有限制吗 使用 head 请求进行 Ajax 调用 var url window
  • 为什么 Blazor 应用在​​任何页面重新加载时都会显示错误

    我正在使用 Blazor 技术开展项目 我有时需要使用一些 JS 代码 并且需要在每个页面中包含不同的 js 文件 据我所知 唯一的方法是使用 JS 函数和 Blazor JS 调用添加它 所以我所做的是 在 Host razor 中 fu
  • web.config 位置中的 IIS 动态 IP 限制

    我正在尝试使用IIS 动态 IP 限制 https www iis net downloads microsoft dynamic ip restrictions限制来自同一 IP 的请求 我已经运行了该模块 并且如果我从 IIS UI 编
  • 在 JMS 序列化器中排除 null 属性

    我使用的 XML API 可以选择仅检索部分响应 这导致生成的对象有很多NULL属性 如果使用此功能 有没有办法真正跳过NULL特性 我尝试实施排除策略 shouldSkipProperty PropertyMetadata propert
  • XMPP:未读消息计数

    我正在尝试通过以下功能为我的网络应用程序实现聊天 当用户登录时 他应该看到许多未读消息 这既是离线消息又是 未见 我将在下一步中解释 未见 当用户位于应用程序中的任何位置但在聊天窗口上时 应该通知他有新消息 消息应标记为 未读 并且必须添加
  • 具有动态高度的 Viewpager 不起作用(始终使用第一个片段的高度)

    我已关注this https stackoverflow com questions 9313554 measuring a viewpager and that https stackoverflow com questions 8394