为什么我的 activity 在尝试搜索回收站视图时会崩溃?
Why does my activity crash when trying to search recycler view?
我遇到了一个问题,我想在回收站视图加载时显示一个循环加载进度条,并且只在完全加载时显示回收站视图,因为当我在回收站视图中搜索项目时崩溃给我错误:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 1(offset:1).state:8077 androidx.recyclerview.widget.RecyclerView{e6252d0 VFED....
避免崩溃的唯一方法是等待大约 4 秒并滚动一点直到它完全加载。并且 activity 只有在它可以明显显示回收视图时才会打开,这也会给它带来延迟。
那么我该如何解决这个错误,也许是在它完全加载后才显示回收视图和搜索栏?
private void getAllStocks() {
try {
String[] nasdaqLine;
String[] nyseLine;
while ((nasdaqLine = nasdaqReader.readNext()) != null){
nasdaqSymbol = nasdaqLine[0];
nasdaqFullName = nasdaqLine[1];
sector = nasdaqLine[5];
industry = nasdaqLine[6];
stocksList.add(new StocksList(nasdaqSymbol, nasdaqFullName, sector, industry));
}
while ((nyseLine = nyseReader.readNext()) != null){
nyseSymbol = nyseLine[0];
nyseFullName = nyseLine[1];
stocksList.add(new StocksList(nyseSymbol, "", nyseFullName, null));
}
} catch (IOException e) {
e.printStackTrace();
}
}
这就是我填充回收站视图的方式。
getAllStocks();
layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
adapter = new StocksListAdapter(stocksList);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
if (stocksList.size() == 8893) {
adapter.notifyDataSetChanged();
circularProgressBar.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
这就是我尝试仅在它完全加载后才显示它的方式,但 activity 仅在它可以明显显示回收站视图后才打开。
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String Key = charSequence.toString();
if (Key.isEmpty()){
stocksListFilterd = stocksList;
} else {
ArrayList<StocksList> listFiltered = new ArrayList<>();
for (StocksList stock : stocksList){
if (stock.getFullName().toLowerCase().contains(Key.toLowerCase()) || stock.getSymbol().toLowerCase().contains(Key.toLowerCase())
|| stock.getSector().toLowerCase().contains(Key.toLowerCase())){
listFiltered.add(stock);
}
}
stocksListFilterd = listFiltered;
}
FilterResults filterResults = new FilterResults();
filterResults.values = stocksListFilterd;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
stocksListFilterd = (ArrayList<StocksList>) filterResults.values;
notifyDataSetChanged();
}
};
}
这是我适配器中的过滤器 class
您尝试在 RecyclerView 中显示的数据是否有可能在其他地方的不同线程中被修改?这可能会解释您看到的 Inconsistency detected
错误消息。
如果您通过搜索过滤 RecyclerView 中的数据,请确保之后调用 notifyDataSetChanged()
以刷新 RecyclerView 中的数据。
你没有显示你在哪里调用 getFilter()
,但它似乎没有在 publishResults()
方法中使用 notifyDataSetChanged()
。根据您的代码结构,尝试调用 notifyDataSetChanged()
,其中 return 来自 return filterResults
.
的数据
想出了如何修复另一个视频的错误,它几乎只是一个更简单的过滤器重写
在我填充回收站视图的地方,我所做的就是添加这个
while ((nyseLine = nyseReader.readNext()) != null){
nyseSymbol = nyseLine[0];
nyseFullName = nyseLine[1];
stocksList.add(new StocksList(nyseSymbol, "", nyseFullName, null));
}
//I added this to set the adapter and show the list immediately after
//loading
adapter = new StocksListAdapter(stocksList);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
然后我在 The SAME activity 中创建了这个方法,而不是在适配器 class
中
private void Filter(String searched) {
for (StocksList stock : stocksList ){
if (stock.getSymbol().toLowerCase().equals(searched)){
//created new array list for the filter
filteredList.add(stock);
}
}
recyclerView.setAdapter(new StocksListAdapter(filteredList));
adapter.notifyDataSetChanged();
}
这是 OnCreate class editText 侦听器
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
searchStocks.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
//Moved the the stuff to afterTextChanged not onTextChanged
@Override
public void afterTextChanged(Editable editable) {
filteredList.clear();
if (editable.toString().isEmpty()){
recyclerView.setAdapter(new StocksListAdapter(stocksList));
adapter.notifyDataSetChanged();
} else {
Filter(editable.toString());
}
}
});
我很确定错误是我在一个方法中设置了所有回收器视图值,如 recyclerview.setAdapter(new StocksListAdapter(stocksList)
,我在 oncreate 方法中调用了 once
当它需要用新的过滤列表更新适配器时 adapter.notifyDataSetChanged()
无法访问并且没有做任何事情。
因此在适配器 class 内部,它来回处理不一致的列表,因此崩溃。不过这只是我的猜测,@shagberg 的评论真的很有帮助。
P.S 将来遇到此问题的任何其他人:检查您的 notifyDataSetChanged()
调用,确保它们不在 Filter
调用或其他数据更改方法之后,因为如果它在错误的地方它崩溃了。
我遇到了一个问题,我想在回收站视图加载时显示一个循环加载进度条,并且只在完全加载时显示回收站视图,因为当我在回收站视图中搜索项目时崩溃给我错误:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 1(offset:1).state:8077 androidx.recyclerview.widget.RecyclerView{e6252d0 VFED....
避免崩溃的唯一方法是等待大约 4 秒并滚动一点直到它完全加载。并且 activity 只有在它可以明显显示回收视图时才会打开,这也会给它带来延迟。
那么我该如何解决这个错误,也许是在它完全加载后才显示回收视图和搜索栏?
private void getAllStocks() {
try {
String[] nasdaqLine;
String[] nyseLine;
while ((nasdaqLine = nasdaqReader.readNext()) != null){
nasdaqSymbol = nasdaqLine[0];
nasdaqFullName = nasdaqLine[1];
sector = nasdaqLine[5];
industry = nasdaqLine[6];
stocksList.add(new StocksList(nasdaqSymbol, nasdaqFullName, sector, industry));
}
while ((nyseLine = nyseReader.readNext()) != null){
nyseSymbol = nyseLine[0];
nyseFullName = nyseLine[1];
stocksList.add(new StocksList(nyseSymbol, "", nyseFullName, null));
}
} catch (IOException e) {
e.printStackTrace();
}
}
这就是我填充回收站视图的方式。
getAllStocks();
layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
adapter = new StocksListAdapter(stocksList);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
if (stocksList.size() == 8893) {
adapter.notifyDataSetChanged();
circularProgressBar.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
这就是我尝试仅在它完全加载后才显示它的方式,但 activity 仅在它可以明显显示回收站视图后才打开。
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String Key = charSequence.toString();
if (Key.isEmpty()){
stocksListFilterd = stocksList;
} else {
ArrayList<StocksList> listFiltered = new ArrayList<>();
for (StocksList stock : stocksList){
if (stock.getFullName().toLowerCase().contains(Key.toLowerCase()) || stock.getSymbol().toLowerCase().contains(Key.toLowerCase())
|| stock.getSector().toLowerCase().contains(Key.toLowerCase())){
listFiltered.add(stock);
}
}
stocksListFilterd = listFiltered;
}
FilterResults filterResults = new FilterResults();
filterResults.values = stocksListFilterd;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
stocksListFilterd = (ArrayList<StocksList>) filterResults.values;
notifyDataSetChanged();
}
};
}
这是我适配器中的过滤器 class
您尝试在 RecyclerView 中显示的数据是否有可能在其他地方的不同线程中被修改?这可能会解释您看到的 Inconsistency detected
错误消息。
如果您通过搜索过滤 RecyclerView 中的数据,请确保之后调用 notifyDataSetChanged()
以刷新 RecyclerView 中的数据。
你没有显示你在哪里调用 getFilter()
,但它似乎没有在 publishResults()
方法中使用 notifyDataSetChanged()
。根据您的代码结构,尝试调用 notifyDataSetChanged()
,其中 return 来自 return filterResults
.
想出了如何修复另一个视频的错误,它几乎只是一个更简单的过滤器重写
在我填充回收站视图的地方,我所做的就是添加这个
while ((nyseLine = nyseReader.readNext()) != null){
nyseSymbol = nyseLine[0];
nyseFullName = nyseLine[1];
stocksList.add(new StocksList(nyseSymbol, "", nyseFullName, null));
}
//I added this to set the adapter and show the list immediately after
//loading
adapter = new StocksListAdapter(stocksList);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
然后我在 The SAME activity 中创建了这个方法,而不是在适配器 class
中 private void Filter(String searched) {
for (StocksList stock : stocksList ){
if (stock.getSymbol().toLowerCase().equals(searched)){
//created new array list for the filter
filteredList.add(stock);
}
}
recyclerView.setAdapter(new StocksListAdapter(filteredList));
adapter.notifyDataSetChanged();
}
这是 OnCreate class editText 侦听器
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
searchStocks.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
//Moved the the stuff to afterTextChanged not onTextChanged
@Override
public void afterTextChanged(Editable editable) {
filteredList.clear();
if (editable.toString().isEmpty()){
recyclerView.setAdapter(new StocksListAdapter(stocksList));
adapter.notifyDataSetChanged();
} else {
Filter(editable.toString());
}
}
});
我很确定错误是我在一个方法中设置了所有回收器视图值,如 recyclerview.setAdapter(new StocksListAdapter(stocksList)
,我在 oncreate 方法中调用了 once
当它需要用新的过滤列表更新适配器时 adapter.notifyDataSetChanged()
无法访问并且没有做任何事情。
因此在适配器 class 内部,它来回处理不一致的列表,因此崩溃。不过这只是我的猜测,@shagberg 的评论真的很有帮助。
P.S 将来遇到此问题的任何其他人:检查您的 notifyDataSetChanged()
调用,确保它们不在 Filter
调用或其他数据更改方法之后,因为如果它在错误的地方它崩溃了。