在我在Android 5.1.1上运行的Android应用中,我使用带有Toolbar
的{{1}}布局,下面是TabLayout
。所有这些都放在ViewPager
中。
CoordinatorLayout
的第一页是ViewPager
个RecyclerView
个项目。
我的问题是我的CardView
不断调整大小,以便裁剪ViewPager
个列表项。
我的主要布局看起来基本上是这样的:
CardView
我的<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.design.widget.CoordinatorLayout>
提供的第一个片段如下:
ViewPager
这会呈现如下内容:
当我点击布局中的按钮时,我使用<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.RecyclerView
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"/>
</FrameLayout>
来调用另一个活动,当我回到我的活动时有时突然我的列表被裁剪,所以只有第一个项目的一半是可见的:
在startActivityForResult
中水平滑动到另一个寻呼机然后返回后,问题就消失了,所以看起来似乎没有正确触发重新布局。按HOME然后恢复我的活动并不能解决问题。请注意,即使我没有以任何方式修改我的布局,也会发生这种情况,我只是从startActivityForResult调用返回。是的,它只发生有时 ......我没有运行的后台线程可以解释明显的随机行为。
起初我以为是ViewPager
缩小了,但是使用HierarchyViewer我发现它实际上是整个RecyclerView
缩小到原始高度的一半左右。
我尝试了各种黑客来解决这个问题,包括在我的整个视图中调用ViewPager
和invalidate()
,但似乎没有任何帮助(尽管刷到另一个页面并再次修复它)。此外,那些不是我想要采用的解决方案...然后我尝试将我的ViewPager高度更改为requestLayout()
,这实际上解决了这个特定的问题;返回我的活动后,wrap_content
中的第一个项目永远不会被裁剪,我可以向下滚动到其他项目。但是,现在我的列表的最后一项是始终裁剪,如此截图中可以看到列表一直滚动到底部:
由于我现在处于一个我不明白正在发生的事情的地步,我需要一些帮助。我应该将什么用作我的ViewPager的layout_height,以及 - 首先 - 为什么?对我来说,RecyclerView
是有道理的,但我该如何思考呢?使用match_parent
时我的观点被裁剪是否有合理的理由,或者我实际上遇到match_parent
,ViewPager
和/或RecyclerView
中的错误?如何确保我的CoordinatorLayout
始终填充AppBar下方的整个屏幕区域,并且我的ViewPager
可以垂直滚动以正确呈现所有RecyclerView
个列表项?
答案 0 :(得分:4)
事实证明,这几乎肯定是CoordinatorLayout
中的错误,甚至更可能是AppBarLayout$ScrollingViewBehavior
中的错误。为了创建MCVE,我意识到我的子活动在屏幕上有一个导致ViewPager缩小的IME - 当我的活动在onActivityResult
之后恢复时,ViewPager
是由于IME减少了屏幕空间而缩小了,但是,尽管IME不再显示和事实CoordinatorLayout
确实已扩展,但它从未再次扩展
在调试并逐步完成onLayout
和onMeasure
的{{1}}和CoordinatorLayout
之后,我现在相当确定ViewPager
没有正确传播此更改给孩子们的大小。
我发现我可以修复&#34;通过在我的CoordinatorLayout
上调用requestLayout
来解决问题,但只有在呼叫被充分延迟(10毫秒无效,100毫秒大多数的时间)时才会出现问题:
ViewPager
这显然不是一个强大的解决方案,但经过调查后发现我可能甚至不需要protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mViewPager.requestLayout();
}
}, 100);
}
,因为我没有真正的高级滚动行为。因此,我的解决方案是简单地使用CoordinatorLayout
或LinearLayout
作为我的根视图组。简单,简单,无需复杂化。
RelativeLayout
但是我会尝试将其压缩成一个简单的示例并向Google提交错误。
至于我应该使用<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
的高度,我原来使用的ViewPager
似乎仍然合理。 match_parent
解决问题(但导致其他问题)的事实可能仅仅是由于错误导致的不一致。
答案 1 :(得分:3)
使用较旧版本的支持库时,我遇到了类似的问题。
请参阅以下相关问题:
https://code.google.com/p/android/issues/detail?id=176406 https://code.google.com/p/android/issues/detail?id=176187
在撰写本文时,请确保您使用的是最新的Support library
版本23.1。
答案 2 :(得分:0)
在您的片段中,只需删除frameLayout并使recyclelerView为父...我希望它能够正常工作:
<android.support.v7.widget.RecyclerView
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp">
<android.support.v7.widget.RecyclerView/>