当前位置: 首页 > 知识库问答 >
问题:

搜索适配器onbind方法中的IndexOutofBounexception?

华睿识
2023-03-14

当我开始搜索/筛选recyclerview列表结果时,我就会从搜索适配器中的onBind方法获取IndexOutofBoundsException。这里有个例外:

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 0(offset:0).state:25 android.support.v7.widget.RecyclerView{3247b3d VFED..... ......ID 0,0-1440,5550 #7f090216 app:id/search_guests_recycler_view}, adapter:com.myapp.ui.registervisitor.searchGuests.SearchGuestListAdapter@2433f32, layout:android.support.v7.widget.LinearLayoutManager@68f5483, context:com.myapp.ui.registervisitor.searchGuests.SearchGuestActivity@843713
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5923)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
        at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
        at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
        at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
        at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
        at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924)
        at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3336)
        at android.view.View.measure(View.java:24545)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
        at android.view.View.measure(View.java:24545)
        at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1414)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.widget.ScrollView.onMeasure(ScrollView.java:452)
        at android.view.View.measure(View.java:24545)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:24545)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:733)
        at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:805)
        at android.view.View.measure(View.java:24545)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:733)
        at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:805)
        at android.view.View.measure(View.java:24545)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:24545)
        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
        at android.view.View.measure(View.java:24545)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
        at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
        at android.view.View.measure(View.java:24545)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6828)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
        at android.view.View.measure(View.java:24545)

我在网上试了几篇文章,但没有成功。我尝试的一些文章是:RecolyerView适配器onBind方法和RecolyerView:Inconsistency Detected。无效的物料位置

此问题的适配器代码位于:https://pastebin.com/vxswwmis

和相应的活动代码进行筛选:

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                mSearchGuestListAdapter.getFilter().filter(query);

                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                mSearchGuestListAdapter.getFilter().filter(newText);
                mSearchGuestListAdapter.notifyDataSetChanged();
                mSearchGuestListAdapter.setFilter(newText);

                if(mSearchGuestListAdapter.getItemCount() == 0){


                    String sourceString = "No match found for <b>" + newText + "</b> ";
                    mNoMatchTextView.setText(Html.fromHtml(sourceString));
                } else {
                    mEmptyRelativeLayout.setVisibility(View.GONE);
                    mRecyclerView.setVisibility(View.VISIBLE);
                }
                return false;
            }
        });

如果需要,乐意分享任何其他细节。有什么办法解决这个问题吗?

下面是我的整个活动代码:https://pastebin.com/5qdn4yh9

这是调用API的presenter类:https://pastebin.com/ygipgn8z

这是一个json示例:https://pastebin.com/82r1zbhp

下面是调用recyclerview的xml代码:https://pastebin.com/z3qxpksl“search_guests_recycler_view”

共有1个答案

梁成双
2023-03-14

代码中有多个因素可能导致适配器中的不一致性。

要了解Filter类的工作原理,您应该注意到,根据官方文档:

通过调用过滤器(java.lang.CharSequence)或过滤器(java.lang.CharSequence,Android.Widget.filter.FilterListener)执行的过滤操作是异步执行的。当调用这些方法时,筛选请求会被发布到请求队列中,并在以后进行处理。对这些方法之一的任何调用都将取消任何先前未执行的筛选请求。

@Override
public Filter getFilter() {
    // WRONG: Return new instance of Filter every time getFilter() is called
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            // Perform filtering...
            return anything;
        }

        @Override
        protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
            // Update and Notify adapter...
        }
    };
}

替换为:

private final Filter filter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
        // Perform filtering...
        return anything;
    }

    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        // Update and Notify adapter...
    }
};

@Override
public Filter getFilter() {
    // CORRECT: Always use the same Filter instance.
    return this.filter;
}

performFiltering()方法在后台线程中执行。在这里,您可以做一个很长的工作,从数据库中读取数据,甚至在需要时发出webservice同步请求。

但是,如果在这里更改适配器列表,将导致屏幕上显示的RecyclerView与适配器列表的内容不一致。相反,您必须构建一个将使用FilterResults返回的临时列表。

@Override
protected FilterResults performFiltering(CharSequence charSequence) {
    // Here is Background Thread, never alter adapter list in this method
    String charString = charSequence.toString();
    List<RegisterGuestList.Guest> filteredList = new ArrayList<>();

    if (charString.isEmpty()) {
        filteredList.addAll(mSearchGuestListResponseList);
    } else {
        ... // fill filteredList as you did previously
    }

    FilterResults filterResults = new FilterResults();
    filterResults.values = filteredList;
    filterResults.count = filteredList.size(); // count is optional
    return filterResults;
}

@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
    // Here is Main Thread, safe to update list and notify adapter
    mSearchGuestListResponseListFiltered = (ArrayList<RegisterGuestList.Guest>) filterResults.values;
    searchText = charSequence.toString();
    notifyDataSetChanged();
}
@Override
public boolean onQueryTextChange(String newText) {
    mSearchGuestListAdapter.getFilter().filter(newText, new Filter.FilterListener() {
        @Override
        public void onFilterComplete(int count) {
            if (count == 0) {
                // Show empty view...
            } else {
                // Show recyclerView...
            }
        }
    });

    // Don't call notifyDataSetChanged() or setFilter() here!
    // Adaper will notified by publishResults() method
    // mSearchGuestListAdapter.setFilter(newText);
    // mSearchGuestListAdapter.notifyDataSetChanged();

    return false;
}
 类似资料:
  • 在我的主要活动中,我有三个循环利用的观点。 其中一个在底部工作表中,它是主要的(默认情况下,底部工作表是打开以显示这个),在其适配器的onbind方法中,我做了一个onClickListener,以便当用户单击其中的项目时,我想要, 我想回到主活动类来设置To Start一个方法,它的滚动是关闭底表并为下一个回收视图设置数据(当底表关闭时会出现) ......这里的问题是如何从onBind方法的L

  • 我正在我的应用程序中集成可搜索的旋转器。下面是我的代码 Xml文件 Man.java 当我运行上面的代码时,我得到的输出如下图所示。自定义arraylist数据不显示它是打印java每个项目旋转器输出的垃圾值

  • 我正在尝试在ndroid ListView上应用搜索,但它对我不起作用,这里是我尝试的代码。 下面是Users类

  • 大家好,根据搜索框中的conatiner图像在这里!我只是想问当用户在搜索框中键入一个名称时,应该显示特定的字段。我把我的视图。JSP代码也在这里吗?? vuew.jsp<%@page import=“com.privery.servicebuilder.service.blobdesolocalserviceutil”%><%@taglib uri=“http://java.sun.com/po

  • 问题内容: 我看了以下网站: ListView示例 其中描述了如何在使用默认适配器的列表视图中实现搜索功能,并且效果很好。 如何修改它,以便可以将其用于列表视图的自定义适配器? 部分代码为: 问题答案: 您需要覆盖适配器内部的getFilter并返回您创建的新的customFilter对象。看到这个答案: 编辑:

  • public void onBindViewHolder(@非空票据持有人,int位置){ 我试图查看所有可以帮助我设置文本的参考资料,但找不到一个,还有其他选择吗??