我有一个包含三个项目的ViewPager。我正在尝试将ViewPager设置为查看最右边的页面(这将是第二个元素)。这是返回一个IndexOutOfBounds异常,虽然我知道索引应该在边界内。这是确切的堆栈:
02-22 12:22:50.256: E/AndroidRuntime(384): FATAL EXCEPTION: main
02-22 12:22:50.256: E/AndroidRuntime(384): java.lang.IndexOutOfBoundsException: index=1 count=0
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addInArray(ViewGroup.java:2050)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addViewInner(ViewGroup.java:1994)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addViewInLayout(ViewGroup.java:1958)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addViewInLayout(ViewGroup.java:1939)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.ViewPager.addView(ViewPager.java:917)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.addView(ViewGroup.java:1828)
02-22 12:22:50.256: E/AndroidRuntime(384): at us.tagverse.pagertest.MasterActivity$PAdapter.instantiateItem(MasterActivity.java:518)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:110)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:649)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.ViewPager.populate(ViewPager.java:783)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1016)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.View.measure(View.java:8313)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.View.measure(View.java:8313)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.View.measure(View.java:8313)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.View.measure(View.java:8313)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewRoot.performTraversals(ViewRoot.java:839)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.os.Handler.dispatchMessage(Handler.java:99)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.os.Looper.loop(Looper.java:123)
02-22 12:22:50.256: E/AndroidRuntime(384): at android.app.ActivityThread.main(ActivityThread.java:3683)
02-22 12:22:50.256: E/AndroidRuntime(384): at java.lang.reflect.Method.invokeNative(Native Method)
02-22 12:22:50.256: E/AndroidRuntime(384): at java.lang.reflect.Method.invoke(Method.java:507)
02-22 12:22:50.256: E/AndroidRuntime(384): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-22 12:22:50.256: E/AndroidRuntime(384): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-22 12:22:50.256: E/AndroidRuntime(384): at dalvik.system.NativeStart.main(Native Method)
请注意原因是java.lang.IndexOutOfBoundsException: index=1 count=0
。这意味着页面/项目的计数为0,我请求的索引为1.这些都不是真的。以下是我调用ViewPager并请求给定页面的方式:
ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
PAdapter adapter = new PAdapter();
pager.setAdapter(adapter);
pager.setCurrentItem(2);
请注意,此调用不会产生任何错误,并且正确地将当前项设置为中间项(索引1):
ViewPager pager = (ViewPager) findViewById(R.id.ma_viewcontainer);
PAdapter adapter = new PAdapter();
pager.setAdapter(adapter);
pager.setCurrentItem(1);
我在视图寻呼机中有3个项目。这是我的完整PAdapter类,它扩展了PagerAdapter类:
private class PAdapter extends PagerAdapter implements TitleProvider {
private int COUNT = 3;
private static final int SETTINGS_ACTIVITY = 0;
private static final int MAIN_ACTIVITY = 1;
private static final int FRIEND_LIST_ACTIVITY = 2;
@Override
public int getCount() {
return COUNT;
}
@Override
public Object instantiateItem(View collection, int position) {
LinearLayout layout = new LinearLayout(getApplicationContext());
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
switch(position) {
case MAIN_ACTIVITY :
layout = (LinearLayout) inflater.inflate(R.layout.main, null, false);
initMainLayout(layout);
break;
case SETTINGS_ACTIVITY :
layout = (LinearLayout) inflater.inflate(R.layout.settings, null, false);
initSettingsLayout(layout);
break;
case FRIEND_LIST_ACTIVITY :
layout = (LinearLayout) inflater.inflate(R.layout.friend_list, null, false);
initFriendListLayout(layout);
break;
}
((ViewPager)collection).addView(layout, position);
return layout;
}
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager)collection).removeView((LinearLayout)view);
}
@Override
public boolean isViewFromObject(View v, Object o) {
return v == (LinearLayout)o;
}
@Override
public void finishUpdate(View arg0) {
//no need
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
//no need
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void startUpdate(View arg0) {
//no need
}
@Override
public String getTitle(int position) {
Resources res = getApplicationContext().getResources();
switch(position) {
case MAIN_ACTIVITY :
return res.getString(R.string.app_name);
case SETTINGS_ACTIVITY :
return res.getString(R.string.settings);
case FRIEND_LIST_ACTIVITY :
return res.getString(R.string.friend_list);
default :
return null;
}
}
}
行((ViewPager)collection).addView(layout, position);
导致崩溃。
如你所见,有三个项目。使用参数为0或1的setCurrentItem()可以正常工作,但是2会导致这个奇怪的错误。我已经没有想法来解决它......不幸的是,ViewPager似乎存在于Android的一些未知领域。如果有人对如何解决这个问题有一些了解,那将非常感激。谢谢!
编辑:根据Shereef的建议,我尝试通过collection.getChildCount()记录子计数,并得到以下结果:
02-22 15:20:42.274: E/children count(645): count: 0
02-22 15:20:42.454: E/children count(645): count: 1
02-22 15:20:42.594: E/children count(645): count: 2
这很有趣。这告诉我的是它创建一个空的PagerAdapter并一次添加一个。对于三个可见视图(中心,左侧和右侧),instantiateItem()
被调用3次。所以我在instantiateItem()
方法中添加了这段代码:
if(((ViewPager)collection).getChildCount() == 2) {
((ViewPager)collection).setCurrentItem(2);
}
因此,只有将计数设置为2才会将页面设置为2(这是一个hacky解决方案,不能完全解决问题,但值得一试)。我得到了一个类似的错误堆栈,首先指向该行:((ViewPager)collection).setCurrentItem(2);
,然后是((ViewPager)collection).addView(layout, position);
。
希望这有助于提供一些见解。
答案 0 :(得分:24)
我认为你不能做((ViewPager)collection).addView(layout, position)
。这取决于您的屏幕外页面限制,我相信默认值为1。我假设你只使用3个视图,所以你可以在你的`onCreate(或你拨打电话的任何地方)做viewPager.setOffscreenPageLimit(3);
之类的事情,以避免每次离开时每个视图都被刷新。
您将在一些教程中看到((ViewPager) collection).addView(view, 0);
中使用了instantiateItem()
。在过去几周里我和ViewPagers
工作了很多,并且使用0作为位置 - 所有时间似乎都很好。
答案 1 :(得分:7)
我看到崩溃日志,我发现它在实例化项目中崩溃了。 我完全不知道哪一行,因为我没有你的行号
但如果我是一个博彩人,我敢打赌:
((ViewPager)collection).addView(layout, position);
当集合中没有页面时,尝试在位置1添加视图时崩溃
也许检查collection.getchildcount()
(可能方法名称错误)并插入最大值(位置,计数)
即用以下位置替换位置:
count > position ? position : count
编辑:
((ViewPager)collection).addView(layout, ((ViewPager)collection).getChildCount() > position ? position : ((ViewPager)collection).getChildCount())
P.S。从我的手机发帖抱歉可怕的格式化
请注意
02-22 12:22:50.256: E/AndroidRuntime(384): at us.tagverse.pagertest.MasterActivity$PAdapter.instantiat
MasterActivity.java:518
我复制的那一行末尾的数字,然后找出它是哪一行,然后才知道哪一行发生了崩溃
编辑:P.S。关于你的解决方案
我认为您的解决方案仅在实例化实例化实例化3个页面之后设置当前项目,但即使它们未实例化,我的行也会使其工作。