我正在尝试显示包含4个条目的FragmentGridPagerAdapter,当视图滚动时,我想向适配器添加项目。
这是我的FragmentPagerAdapter:
public class MyPagerAdapter extends FragmentGridPagerAdapter {
private final Context _ctx;
private HashMap<Integer, Entry> _data;
public MyPagerAdapter(Context context, FragmentManager fm, HashMap<Integer, Entry> tidatals) {
super(fm);
_ctx = context;
_data = data;
}
public void addEntry(Entry entry)
{
_data.put(_data.size(), entry);
this.notifyDataSetChanged();
}
@Override
public Fragment getFragment(int i, int i2) {
CardFragment fragment = CardFragment.create("Card", _data.get(i).getPrettyText());
fragment.setCardGravity(Gravity.BOTTOM);
fragment.setExpansionEnabled(true);
return fragment;
}
@Override
public int getRowCount() {
return _data.size();
}
@Override
public int getColumnCount(int i) {
return 1;
}
}
这就是我在Main Wear Activity中向适配器添加数据的方法:
//In onCreate:
_data = new HashMap<Integer, Entry>();
_adapter = new TILPagerAdapter(this, getFragmentManager(), _data);
_pager.setAdapter(_adapter);
//When I finally get my data:
...
// Do stuff, get datas in 'data' variable
MainWear.this.runOnUiThread(new Runnable() {
@Override
public void run() {
boolean firstData = _data.isEmpty();
for(TILEntry entry : data.values())
{
_adapter.addEntry(entry);
}
if(firstData){
_pager.setAdapter(_adapter);
switchViewToResults(); // Sets pager to visible
}
}
});
当我将项目添加到适配器并调用notifyDataSetChanged()时,适配器刷新正常,但是当我滚动添加的页面时它会崩溃。
这是stacktrace:
E/InputEventReceiver﹕ Exception dispatching input event.
E/MessageQueue-JNI﹕ Exception in MessageQueue callback: handleReceiveCallback
E/MessageQueue-JNI﹕ java.lang.ArrayIndexOutOfBoundsException: length=4; index=4
at android.support.wearable.view.GridViewPager.populate(GridViewPager.java:873)
at android.support.wearable.view.GridViewPager.setCurrentItemInternal(GridViewPager.java:584)
at android.support.wearable.view.GridViewPager.handlePointerUp(GridViewPager.java:1990)
at android.support.wearable.view.GridViewPager.onTouchEvent(GridViewPager.java:1492)
at android.view.View.dispatchTouchEvent(View.java:7846)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1944)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2085)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1532)
at android.app.Activity.dispatchTouchEvent(Activity.java:2468)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2033)
at android.view.View.dispatchPointerEvent(View.java:8026)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3868)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3433)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3483)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3452)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3559)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3460)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3616)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3433)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3483)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3452)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3460)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3433)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5589)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5569)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5540)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5669)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:138)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:5026)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
D/AndroidRuntime﹕ Shutting down VM
W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xadb04d70)
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: til.wear.robineisenberg.til_wear, PID: 5808
java.lang.ArrayIndexOutOfBoundsException: length=4; index=4
at android.support.wearable.view.GridViewPager.populate(GridViewPager.java:873)
at android.support.wearable.view.GridViewPager.setCurrentItemInternal(GridViewPager.java:584)
at android.support.wearable.view.GridViewPager.handlePointerUp(GridViewPager.java:1990)
at android.support.wearable.view.GridViewPager.onTouchEvent(GridViewPager.java:1492)
at android.view.View.dispatchTouchEvent(View.java:7846)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2209)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1944)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2215)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1958)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2085)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1532)
at android.app.Activity.dispatchTouchEvent(Activity.java:2468)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2033)
at android.view.View.dispatchPointerEvent(View.java:8026)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3989)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3868)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3433)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3483)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3452)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3559)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3460)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3616)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3433)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3483)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3452)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3460)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3433)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5589)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5569)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5540)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5669)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:138)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:5026)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
在调用getFragment时,我打印了_data我的适配器的大小,调用getFragment时_data.size()的值正确为8。
在日志中,4是初始适配器大小的大小。 8是之后的期望大小。添加项目时不会崩溃,但只有在向新项目滚动卡片时才会崩溃。我究竟做错了什么?
编辑:的确,这似乎是适配器的notifyDataSetChanged函数中的一个省略。我打开了谷歌的错误报告,如果您认为需要修复它,请将其加星标记:
https://code.google.com/p/android/issues/detail?id=73846&thanks=73846&ts=1405945122
答案 0 :(得分:3)
GridViewPager.populate()
中的第873行是:
this.mRowScrollX[row] = computePageLeft(...);
在设置适配器时看起来mRowScroll
数组的长度是固定的,而在getRowCount()
被触发时未notifyDataSetChanged()
更新。实际上,如果您检查GridViewPager
课程的其余部分,您会看到它仅在setAdapter()
方法中分配:
this.mExpectedRowCount = this.mAdapter.getRowCount();
this.mRowScrollX = new int[this.mExpectedRowCount];
简而言之,我认为这是GridViewPager
中的一个错误,只要您想更新行数或列数,就可以通过再次调用setAdapter()
来规避错误。
答案 1 :(得分:1)
最新的可穿戴支持库1.1应该已经修复了这个bug,最新的Android Wear 5.0版本已经发布了。