我有一个简单的应用程序设置,用户可以在其中搜索产品名称或sku,然后从那里可以根据查询更改自动更改recyclerview。但是,如果文本更改太快,则应用程序将崩溃。
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 0(offset:0).state:128 android.support.v7.widget.RecyclerView
我已经尝试过在UI线程和与视图相同的线程上运行它,并将viewholder缩小到更简单的方式,但是仍然无法正常工作。有趣的是,在横向模式下不会发生此错误。
这是我的过滤器的代码:
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();
}
};
}
在横向模式下,此方法可以很好地工作,并且只要搜索查询发生更改,过滤器就会更改。但是在纵向模式下,如果文字更改太快,它将失败。
编辑: 这是整个适配器代码:
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();
}
};
}
}