У меня есть простая настройка приложения, в которой пользователь может искать название продукта или артикул, и оттуда он автоматически меняет представление переработчика при изменении запроса. Однако, если текст меняется слишком быстро, приложение вылетает.
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 0(offset:0).state:128 android.support.v7.widget.RecyclerView
Я уже пытался запустить его в потоке пользовательского интерфейса, в том же потоке, что и представление, и сжать область просмотра до чего-то гораздо более простого, но это все равно не работает. Интересно, что эта ошибка не возникает в ландшафтном режиме.
Вот код моего фильтра:
public Filter getFilter(){
return new Filter(){
@Override
protected FilterResults performFiltering(CharSequence charSequence){
String searchString = charSequence.toString();
if(searchString.isEmpty()){
filteredProducts.clear();
}
else{
List<Product> filteredList = new ArrayList<>();
Log.d("Product List Size","" + ProductUtil.allProducts.size());
for(Product product : ProductUtil.allProducts){
if(product.getName().toLowerCase().contains(searchString.toLowerCase())){
filteredList.add(product);
}
else if(product.getCategory().toLowerCase().contains(searchString.toLowerCase())){
filteredList.add(product);
}
else if(product.getSku().toLowerCase().contains(searchString.toLowerCase())){
filteredList.add(product);
}
else if(product.getSku().toLowerCase().replace("-", "").contains(searchString.toLowerCase())){
filteredList.add(product);
}
}
filteredProducts = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredProducts;
return filterResults;
}
@Override
protected void publishResults(CharSequence sequence, FilterResults filterResults){
notifyDataSetChanged();
}
};
}
В альбомной ориентации это работает нормально, и фильтр меняется, как только изменяется запрос на поиск. Однако в портретной ориентации, если текст меняется слишком быстро, он терпит неудачу.
EDIT:
Вот весь код адаптера:
import android.arch.persistence.room.Room;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import java.util.ArrayList;
import java.util.List;
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> implements Filterable {
private List<Product> filteredProducts;
private LayoutInflater mInflater;
private Database database;
private Context context;
private String pi_ip;
public boolean isClickable = true;
public ProductAdapter(Context context){
mInflater = LayoutInflater.from(context);
this.context = context;
filteredProducts = new ArrayList<>();
database = Room.databaseBuilder(context, Database.class, "Settings_DB").allowMainThreadQueries().fallbackToDestructiveMigration().build();
try{
Settings ipsetting = database.settingInterface().getSetting("pi_ip");
pi_ip = ipsetting.getSettingValue();}
catch (Exception e){
pi_ip = "127.0.0.1";
}
}
public void newProducts(){
filteredProducts.clear();
for(Product product : ProductUtil.allProducts){
if(product.isNewProduct()){
filteredProducts.add(product);
}
}
notifyDataSetChanged();
}
public void bestSellers(){
filteredProducts.clear();
for(Product product : ProductUtil.allProducts){
if(product.isBestSeller()){
filteredProducts.add(product);
}
}
notifyDataSetChanged();
}
@Override
public ProductViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View mItemView = mInflater.inflate(R.layout.product, parent, false);
return new ProductViewHolder(mItemView, this);
}
@Override
public void onBindViewHolder(@NonNull ProductViewHolder holder, final int position) {
final Product mCurrent = filteredProducts.get(position);
holder.productName.setText(mCurrent.getName());
if(mCurrent.getShotCount() > 0){
holder.productPrice.setText(mCurrent.getShotCount() + " Shot");
}
else{
holder.productPrice.setText("");
}
holder.productSKU.setText(mCurrent.getSku());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isClickable) {
Intent intent = new Intent(context, VideoPlayer.class);
intent.putExtra("item", mCurrent.getSku().toLowerCase().replace("-",""));
context.startActivity(intent);
}
}
});
}
@Override
public int getItemCount() {
return filteredProducts.size();
}
class ProductViewHolder extends RecyclerView.ViewHolder{
public final TextView productName;
final ProductAdapter mAdapter;
public final TextView productPrice;
public final TextView productSKU;
public ProductViewHolder(View itemView, ProductAdapter adapter){
super(itemView);
productName = itemView.findViewById(R.id.categoryName);
this.mAdapter = adapter;
productPrice = itemView.findViewById(R.id.productPrice);
productSKU = itemView.findViewById(R.id.productSKU);
}
}
@Override
public Filter getFilter(){
return new Filter(){
@Override
protected FilterResults performFiltering(CharSequence charSequence){
String searchString = charSequence.toString();
if(searchString.isEmpty()){
filteredProducts.clear();
}
else{
List<Product> filteredList = new ArrayList<>();
Log.d("Product List Size","" + ProductUtil.allProducts.size());
for(Product product : ProductUtil.allProducts){
if(product.getName().toLowerCase().contains(searchString.toLowerCase())){
filteredList.add(product);
}
else if(product.getCategory().toLowerCase().contains(searchString.toLowerCase())){
filteredList.add(product);
}
else if(product.getSku().toLowerCase().contains(searchString.toLowerCase())){
filteredList.add(product);
}
else if(product.getSku().toLowerCase().replace("-", "").contains(searchString.toLowerCase())){
filteredList.add(product);
}
}
filteredProducts = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredProducts;
return filterResults;
}
@Override
protected void publishResults(CharSequence sequence, FilterResults filterResults){
notifyDataSetChanged();
}
};
}
}