简体   繁体   English

Android TV在BrowseFragment中重新加载数据

[英]Android TV reloading data in BrowseFragment

I am writing an Android TV app and have bumped into this issue. 我正在编写一个Android TV应用程序并遇到了这个问题。 I have to replace all the rows in BrowseFragment with new ones on receiving an Event. 我必须在接收事件时用新的行替换BrowseFragment中的所有行。 What i've tried: 我尝试过的:

mRowsAdapter.clear();
...
mRowsAdapter.add(add new rows here);

Where mRowsAdapter is the ArrayObjectAdapter with ListRow items. 其中mRowsAdapter是带有ListRow项的ArrayObjectAdapter。 Also tried this approach: 也试过这种方法:

mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
setAdapter(mRowsAdapter);
mRowsAdapter.add(add new rows here);

And the solutions from this question . 这个问题的解决方案。 Neither of them works. 它们都不起作用。 I keep getting IOBE. 我一直在接受IOBE。 Here are the logs: 这是日志:

                               java.lang.IndexOutOfBoundsException: Index: 7, Size: 0
                                   at java.util.ArrayList.get(ArrayList.java:411)
                                   at android.support.v17.leanback.widget.ArrayObjectAdapter.get(ArrayObjectAdapter.java:56)
                                   at android.support.v17.leanback.app.ListRowDataAdapter.get(ListRowDataAdapter.java:65)
                                   at android.support.v17.leanback.widget.ItemBridgeAdapter.getItemViewType(ItemBridgeAdapter.java:248)
                                   at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5046)
                                   at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5172)
                                   at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5153)
                                   at android.support.v17.leanback.widget.GridLayoutManager.getViewForPosition(GridLayoutManager.java:971)
                                   at android.support.v17.leanback.widget.GridLayoutManager$2.createItem(GridLayoutManager.java:1464)
                                   at android.support.v17.leanback.widget.SingleRow.appendVisibleItems(SingleRow.java:111)
                                   at android.support.v17.leanback.widget.Grid.appendVisibleItems(Grid.java:371)
                                   at android.support.v17.leanback.widget.GridLayoutManager.appendVisibleItems(GridLayoutManager.java:1702)
                                   at android.support.v17.leanback.widget.GridLayoutManager.fastRelayout(GridLayoutManager.java:1764)
                                   at android.support.v17.leanback.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:1888)
                                   at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3374)
                                   at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3183)
                                   at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3627)
                                   at android.view.View.layout(View.java:17519)
                                   at android.view.ViewGroup.layout(ViewGroup.java:5612)
                                   at android.support.v17.leanback.widget.ScaleFrameLayout.onLayout(ScaleFrameLayout.java:172)
                                   at android.view.View.layout(View.java:17519)
                                   at android.view.ViewGroup.layout(ViewGroup.java:5612)
                                   at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                   at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                   at android.view.View.layout(View.java:17519)
                                   at android.view.ViewGroup.layout(ViewGroup.java:5612)
                                   at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                   at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                   at android.view.View.layout(View.java:17519)
                                   at android.view.ViewGroup.layout(ViewGroup.java:5612)
                                   at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                   at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                   at android.view.View.layout(View.java:17519)
                                   at android.view.ViewGroup.layout(ViewGroup.java:5612)
                                   at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                   at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                   at android.view.View.layout(View.java:17519)
                                   at android.view.ViewGroup.layout(ViewGroup.java:5612)
                                   at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
                                   at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
                                   at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
                                   at android.view.View.layout(View.java:17519)
                                   at android.view.ViewGroup.layout(ViewGroup.java:5612)
                                   at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                   at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                   at com.android.internal.policy.DecorView.onLayout(DecorView.java:724)
                                   at android.view.View.layout(View.java:17519)
                                   at android.view.ViewGroup.layout(ViewGroup.java:5612)
                                   at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2342)
                                   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2069)
                                   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1246)
                                   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6301)
                                   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
                                   at android.view.Choreographer.doCallbacks(Choreographer.java:683)
                                   at android.view.Choreographer.doFrame(Choreographer.java:619)
com.cloudify E/AndroidRuntime:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
                                   at android.os.Handler.handleCallback(Handler.java:751)
                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                   at android.os.Looper.loop(Looper.java:154)
                                   at android.app.ActivityThread.main(ActivityThread.java:6077)
                                   at java.lang.reflect.Method.invoke(Native Method)
                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Please help. 请帮忙。 Thank you. 谢谢。

Youre getting a index out of bounds because the internal array of objects in the adapter is trying to use its own size to determine where to add the items. 您获得的索引超出范围,因为适配器中的内部对象数组正在尝试使用自己的大小来确定添加项目的位置。

When you call .add() its internally doing this - 当你调用.add()时,它会在内部执行此操作 -

/**
 * Adds an item to the end of the list.
 *
 * @param item The item to add to the end of the list.
 */
public void add(Object item) {
    add(mItems.size(), item);
}
/**
 * Inserts an item into this list at the specified index.
 *
 * @param index The index at which the item should be inserted.
 * @param item The item to insert into the list.
 */
public void add(int index, Object item) {
    mItems.add(index, item);
    notifyItemRangeInserted(index, 1);
}

that means that some how you calling clear is temporarily leaving something out of whack and the internal index is off of what it actually is and the arraylist poops an IOBE. 这意味着你调用clear的一些方法暂时会让一些东西失控并且内部索引与实际内容完全不同而且arraylist支持IOBE。 Maybe try using add(0, yourArray) instead. 也许尝试使用add(0,yourArray)。

EDIT: 编辑:

try adding some kind of validation before you add your objects. 尝试在添加对象之前添加某种验证。 Something like: 就像是:

if((myAdapter.size() - 1) > indexImTryingToAddAt)
{
    myAdapter.addAll(indexImTryingToAddAt, arrayOfObjects);
}
else
{
    Log.d("index is larger than current adapter", indexImTryingToAddAt+"");
}

Try to do this: 尝试这样做:

mRowsAdapter.clear();
    mRowsAdapter.add(add new rows here);
    mRowsAdapter.notifyArrayItemRangeChanged(0, mRowsAdapter.size());

The way i solved a similar issue: 我解决类似问题的方式:

You cannot put an object with a set index into ArrayObjectAdapter, if the Array is empty. 如果Array为空,则不能将具有set索引的对象放入ArrayObjectAdapter。

https://developer.android.com/reference/android/support/v17/leanback/widget/ArrayObjectAdapter https://developer.android.com/reference/android/support/v17/leanback/widget/ArrayObjectAdapter

void add (int index, Object item) void add(int index,Object item)

Inserts an item into this adapter at the specified index. 在指定索引处将项插入此适配器。 If the index is > size() an exception will be thrown. 如果索引是> size(),则抛出异常。

I don't know how sleek my solution is, but you can do the following: 我不知道我的解决方案有多么圆滑,但您可以执行以下操作:

Fill the Array with "dummy" objects 使用“虚拟”对象填充数组

mRowsAdapter.add(0, new ListRow(new HeaderItem(""), new ArrayObjectAdapter()));
mRowsAdapter.add(1, new ListRow(new HeaderItem(""), new ArrayObjectAdapter()));
mRowsAdapter.add(2, new ListRow(new HeaderItem(""), new ArrayObjectAdapter()));

and when you callbacks are done, replace them: 当回调完成后,替换它们:

mRowsAdapter.replace(0, new ListRow(new HeaderItem("List1"), list1));
mRowsAdapter.replace(1, new ListRow(new HeaderItem("List2"), list2));
mRowsAdapter.replace(2, new ListRow(new HeaderItem("List3"), list3));

This way you can also add the an item counter into the HeaderItem: 这样您还可以将项计数器添加到HeaderItem中:

mRowsAdapter.replace(2, new ListRow(new HeaderItem("List3 (" + list3.size() + ")"), list3));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM