Android ViewPager不重画内容,保留/变为空白
我们这里的ViewPager遇到了一个非常奇怪的问题。我们在每个ViewPager页面上嵌入列表,并在更新列表数据时在列表适配器和ViewPager适配器上触发notifyDataSetChanged 我们观察到的是,有时页面不更新其视图树,即保持空白,有时甚至在分页时消失。当来回翻页几次时,内容会突然重新出现。似乎Android在这里缺少视图更新。我还注意到,在使用hierarchy viewer进行调试时,选择一个视图将始终使其重新出现,这显然是因为hierarchy viewer强制所选视图重新绘制自身 但我无法通过编程实现这一点;使列表视图无效,甚至使整个视图页面无效,都没有效果 这是与compatibility-v4_r7库兼容的。我还尝试使用最新版本,因为它声称修复了许多与“查看寻呼机”相关的问题,但它让事情变得更糟(例如,手势被破坏了,因此它有时不允许我翻阅所有页面)Android ViewPager不重画内容,保留/变为空白,android,android-viewpager,Android,Android Viewpager,我们这里的ViewPager遇到了一个非常奇怪的问题。我们在每个ViewPager页面上嵌入列表,并在更新列表数据时在列表适配器和ViewPager适配器上触发notifyDataSetChanged 我们观察到的是,有时页面不更新其视图树,即保持空白,有时甚至在分页时消失。当来回翻页几次时,内容会突然重新出现。似乎Android在这里缺少视图更新。我还注意到,在使用hierarchy viewer进行调试时,选择一个视图将始终使其重新出现,这显然是因为hierarchy viewer强制所选视
是否有其他人也遇到了这些问题,或者您是否知道是什么原因导致了这些问题?ViewPager尝试在重复使用项目方面做一些巧妙的事情,但它要求您在事情发生变化时返回新的项目位置。尝试将此添加到PagerAdapter:
public int getItemPosition (Object object) { return POSITION_NONE; }
它基本上告诉ViewPager一切都已改变(并强制它重新实例化一切)。这是我脑子里唯一能想到的事情。Android支持库有一个演示活动,其中包括一个ViewPager,每个页面上都有一个ListView。你可能应该看看它的功能 在Eclipse中(使用Android开发工具r20):
New>Android示例项目
Support4Demos
Android工具>添加支持库
Fragment
,然后选择Pager
这方面的代码位于
src/com.example.android.supportv4.app/FragmentPagerSupport.java
中。祝你好运 我遇到了这个问题,也遇到了类似的问题。我甚至发现堆栈溢出
对我来说,在我视图的父视图的父视图中,有人子类化了LinearLayout
并覆盖了requestLayout()
,而没有调用super.requestLayout()
。这防止了在我的ViewPager上调用onMeasure
和onLayout
(尽管hierarchyviewer手动调用这些)。未经测量,它们将在ViewPager中显示为空白
因此,请检查您的包含视图。确保它们从视图中生成子类,不要盲目地覆盖requestLayout或任何类似的内容。我们终于找到了解决方案。显然,我们的实施遇到了两个问题:
destroyItem()
中的视图destroyItem()
中删除视图,因此我们没有将其添加到instantiateItem()
中,而是返回对应于当前位置的缓存视图查看页面的源代码
——也没有明确说明您必须这样做——但文档中说:
destroyItem()删除给定位置的页面。适配器负责从其容器中删除视图,尽管它只需确保在从finishUpdate(ViewGroup)返回时完成此操作 以及: 一个非常简单的PagerAdapter可以选择将页面视图本身用作关键对象,在创建后从InstanceItem(ViewGroup,int)返回它们,并将它们添加到父视图组中。匹配的destroyItem(ViewGroup,int,Object)实现将从父视图组中删除视图,并且isViewFromObject(View,Object)可以实现为返回视图==Object 因此,我的结论是,
ViewPager
依赖其底层适配器在instantiateItem()
/destroyItem()
中显式添加/删除其子项。也就是说,如果适配器是PagerAdapter
的子类,则子类必须实现此逻辑
旁注:请注意,如果您在
ViewPager
中使用列表,我也遇到了完全相同的问题,但实际上我在destroyItem中销毁了视图(我认为)。然而,问题是我使用viewPager.removeViewAt(index)销毁了它代码>代替了viewPager.removeView((视图)对象)代码>
mAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());
错:
@Override
public void destroyItem(ViewGroup viewPager, int position, Object object) {
viewPager.removeViewAt(position);
}
对:
@Override
public void destroyItem(ViewGroup viewPager, int position, Object object) {
viewPager.removeView((View) object);
}
也有同样的问题,这与列表视图
有关(因为如果列表为空,我的空视图显示良好)。我刚刚在有问题的列表视图上调用了requestLayout()
。现在画得很好 我也有类似的问题。我缓存视图,因为在ViewPager
中我只需要3个视图。当我向前滑动时,一切正常,但当我开始向后滑动时出现错误,它表示“我的视图已经有父视图”。解决方案是手动删除不需要的项目
@Override
public Object instantiateItem(ViewGroup container, int position) {
int localPos = position % SIZE;
TouchImageView view;
if (touchImageViews[localPos] != null) {
view = touchImageViews[localPos];
} else {
view = new TouchImageView(container.getContext());
view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
touchImageViews[localPos] = view;
}
view.setImageDrawable(mDataModel.getPhoto(position));
Log.i(IRViewPagerAdpt.class.toString(), "Add view " + view.toString() + " at pos: " + position + " " + localPos);
if (view.getParent() == null) {
((ViewPager) container).addView(view);
}
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object view) {
// ((ViewPager) container).removeView((View) view);
Log.i(IRViewPagerAdpt.class.toString(), "remove view " + view.toString() + " at pos: " + position);
}
..................
private static final int SIZE = 3;
private TouchImageView[] touchImageViews = new TouchImageView[SIZE];
我在使用ViewPager和FragmentStatePagerAdapter时遇到了同样的问题。我尝试使用一个延迟3秒的处理程序来调用invalidate()和requestLayout(),但没有成功。工作原理是按如下方式重置viewPager的背景色:
MyFragment.java
private Handler mHandler;
private Runnable mBugUpdater;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = new ViewPager(getActivity());
//...Create your adapter and set it here...
mHandler = new Handler();
mBugUpdater = new Runnable(){
@Override
public void run() {
mVp.setBackgroundColor(mItem.getBackgroundColor());
mHandler = null;
mBugUpdater = null;
}
};
mHandler.postDelayed(mBugUpdater,50);
return rootView;
}
@Override
public void onPause() {
if(mHandler != null){
//Remove the callback if it hasn't triggered yet
mHandler.removeCallbacks(mBugUpdater);
mHandler = null;
mBugUpdater = null;
}
super.onPause();
}
如果在带有FragmentPagerAdapter
的片段内设置了ViewPager
,请使用getChildFragmentManager()
而不是getSupportFragmentManager()
作为初始化FragmentPagerAdapter
的参数
mAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());
而不是
mAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
对我来说,问题又回到了空调上