gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 06:40:19 29 4
gpt4 key购买 nike

一旦我开始搜索/过滤我的 recyclerview 列表结果,我就会不断从搜索适配器中的 onBind 方法中获取 IndexOutofBoundsException。这是异常(exception):

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)

我在网上尝试了几篇文章,但没有成功。我试过的一些文章是:RecyclerView Adapter onBind methodRecyclerView: Inconsistency detected. Invalid item position

我针对此问题的适配器代码位于: https://pastebin.com/VxsWWMiS

和相应的过滤 Activity 代码:

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;
}
});

如果需要,很乐意分享任何其他详细信息。有什么解决办法吗?

这是我的整个 Activity 代码:https://pastebin.com/5qDN4yh9

这是调用 API 的演示器类:https://pastebin.com/YGiPGn8Z

这是模型类:https://pastebin.com/WCkPFnvU

这是一个 json 样本:https://pastebin.com/82R1zBHP

这是调用 recyclerview 的 xml 代码:https://pastebin.com/Z3QxPkSL “search_guests_recycler_view”

最佳答案

您的代码中有多种注意事项可能会导致您的适配器出现这种不一致。

要了解 Filter 类的工作原理,您应该注意,根据 official documentation :

Filtering operations performed by calling filter(java.lang.CharSequence) or filter(java.lang.CharSequence, android.widget.Filter.FilterListener) are performed asynchronously. When these methods are called, a filtering request is posted in a request queue and processed later. Any call to one of these methods will cancel any previous non-executed filtering request.


1。使用 Filter 的单个实例

Filter 类执行后台任务,其中调用了 performFiltering() 方法。为避免在键入时重叠过滤器,您应该避免使用过滤器的多个实例。在您的 SearchGuestListAdapter 类中:

不正确:

@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;
}

2。你不应该修改 performFiltering() 中的适配器变量

performFiltering() 方法在后台线程中执行。在这里你可以做一个长时间的工作,从数据库中读取数据,如果你需要的话,甚至可以发出一个 web 服务同步请求。

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

使用以下结构修复 performFiltering():

@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();
}

3。使用 FilterListener 在过滤器完成时获得通知。

SearchGuestActivityonQueryTextChange() 中,您希望检查适配器列表大小以显示或隐藏空 View 。由于 Filter 在后台线程中工作,您必须使用 FilterListener 执行过滤器调用检查空列表。

删除 SearchGuestListAdapter 的 setFilter() 方法,并使用以下结构修复 SearchGuestActivity 的 onQueryTextChange():

@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;
}

关于java - 搜索适配器 onbind 方法中的 IndexOutofBounexception?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58570090/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com