多次输入Activity时出现IndexOutOfBoundsException问题

时间:2019-01-06 17:48:05

标签: android exception arraylist android-adapter indexoutofboundsexception

我有一个问题,当我第一次通过单击MainActivity中的按钮进入FinalListActivity时,一切正常。但是,当我返回MainActivity并再次尝试输入时,它将引发异常:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.listazakupow, PID: 5147
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
    at java.util.ArrayList.get(ArrayList.java:308)
    at app.listazakupow.Adapters.FinalListAdapter.onBindViewHolder(FinalListAdapter.java:44)
    at app.listazakupow.Adapters.FinalListAdapter.onBindViewHolder(FinalListAdapter.java:16)
    at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
    at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
    at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)

我知道Adapter类中的int ArrayList有问题,但是我不知道该怎么办。就是这个片段:

holder.imageView.setImageResource(imagesIndex.get(position));

我能帮助我吗?在我的代码下面:

FinalListActivity

public class FinalListActivity extends AppCompatActivity {
private ArrayList<String> finalListArrayList;
private ArrayList<Integer> imagesIndex;
private RecyclerView recyclerView;
private TextView textView1, textView2, textView3;
private FinalListAdapter myAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private AppDatabase appDatabase;
private static final String DATABASE_NAME = "images_base";

@SuppressLint({"WrongViewCast", "SetTextI18n"})
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_finallist);
    Intent intent = getIntent();
    finalListArrayList = intent.getStringArrayListExtra("productList");
    imagesIndex = intent.getIntegerArrayListExtra("imagesList");
    appDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, DATABASE_NAME).fallbackToDestructiveMigration().build();
    recyclerView = findViewById(R.id.recycler_view1);
    mLayoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(mLayoutManager);
    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            for(String s:finalListArrayList) {
                String category = appDatabase.daoAccess().getCategoryByKeyword(s);
                String imagePath = appDatabase.daoAccess().getImagePathForCategory(category);
                int id;
                if(imagePath!=null) {
                    id = getApplicationContext().getResources().getIdentifier(imagePath, "drawable", getPackageName());
                }
                else{
                    id = getApplicationContext().getResources().getIdentifier("app_logo_black", "drawable", getPackageName());
                }
                imagesIndex.add(id);
            }
            System.out.println("FinalListArrayListSize is:" + finalListArrayList.size()+" imageIndexList is: "+imagesIndex.size());
        }
    });
    myAdapter = new FinalListAdapter(finalListArrayList, imagesIndex, recyclerView);
    recyclerView.setAdapter(myAdapter);
    myAdapter.notifyDataSetChanged();
    textView1 = findViewById(R.id.textView1);
    textView2 = findViewById(R.id.textView2);
    textView3 = findViewById(R.id.textView3);
    textView1.setText("Amount of products: " + finalListArrayList.size());
}
@Override
protected void onResume(){
    super.onResume();
    System.out.println("FinalListArrayListSize is:" + finalListArrayList.size()+" imageIndexList is: "+imagesIndex.size());
}
}

FinalListAdapter

public class FinalListAdapter extends 
RecyclerView.Adapter<FinalListAdapter.MyViewHolder> {
private ArrayList<String> mDataset;
private ArrayList<Integer> imagesIndex;
private ArrayList<FinalListItem> finalListItems;
private RecyclerView recyclerView;
public FinalListAdapter(ArrayList<String> mDataset,ArrayList<Integer> imagesIndex, RecyclerView recyclerView) {
    this.mDataset = mDataset;
    this.imagesIndex = imagesIndex;
    this.recyclerView = recyclerView;
    finalListItems = new ArrayList<>();
    for (String a : mDataset) {
        finalListItems.add(new FinalListItem(a, false));
    }
}
public ArrayList<Integer> getImagesIndex(){
    return imagesIndex;
}
@Override
public long getItemId(int position) {
    return position;
}
@Override
public int getItemViewType(int position) {
    return 0;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
    holder.final_list_TextView1.setText(finalListItems.get(position).getName());
    holder.imageView.setImageResource(imagesIndex.get(position));
    holder.checkBox.setOnCheckedChangeListener(null);
    holder.checkBox.setBackgroundResource(R.drawable.listitem_white);

    if(finalListItems.get(position).isChecked){
        holder.linearLayout.setBackgroundResource(R.drawable.listitem_green);
        holder.checkBox.setChecked(true);
    }
    else{
        holder.linearLayout.setBackgroundResource(R.drawable.listitem_white);
        holder.checkBox.setChecked(false);
    }
    holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            int currentPosition = holder.getAdapterPosition();
            if(isChecked){
                    FinalListItem finalItemBefore = finalListItems.get(currentPosition);
                    FinalListItem finalItemAfter = new FinalListItem(finalItemBefore.getName(), true);
                    finalListItems.remove(finalItemBefore);
                    finalListItems.add(finalItemAfter);
                    recyclerView.scrollToPosition(0);
                    holder.linearLayout.setBackgroundResource(R.drawable.listitem_green);
                    notifyItemMoved(currentPosition, getItemCount() - 1);

            }
            else{
                finalListItems.get(currentPosition).setChecked(false);
                notifyItemChanged(currentPosition);
            }
        }
    });
}
@Override
public int getItemCount() {
    return finalListItems.size();
}

private class FinalListItem {
    private String name;
    private boolean isChecked;

    public FinalListItem(String name, boolean isChecked) {
        this.name = name;
        this.isChecked = isChecked;
    }

    public void setChecked(boolean isChecked) {
        this.isChecked = isChecked;
    }

    public String getName() {
        return name;
    }
}

public class MyViewHolder extends RecyclerView.ViewHolder {
    final private TextView final_list_TextView1;
    final private CheckBox checkBox;
    final private LinearLayout linearLayout;
    final private ImageView imageView;

    public MyViewHolder(View view) {
        super(view);
        final_list_TextView1 = view.findViewById(R.id.final_list_TextView1);
        checkBox =  view.findViewById(R.id.checkBox1);
        linearLayout = view.findViewById(R.id.linearLayout1);
        imageView = view.findViewById(R.id.item_image);
    }
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.finallist_list_layout, parent, false);
    return new MyViewHolder(view);
}
}

1 个答案:

答案 0 :(得分:1)

是,代码行:

holder.imageView.setImageResource(imagesIndex.get(position));

导致错误。

为什么?因为position的值与ArrayList“ imagesIndex”中任何值的索引无关。从position获得的值onBindViewHolder指向RecyclerView中的行,这意味着在构造函数中生成的ArrayList“ finalListItems”。