This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?

(25个答案)


上个月关闭。





例外:

E / AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.justdoit, PID: 11200
java.lang.ArrayIndexOutOfBoundsException: length = 11; index = -1
at java.util.ArrayList.get(ArrayList.java: 439)
at com.example.justdoit.DashboardActivity$DashboardAdapter$2$1$1.onClick(DashboardActivity.java: 173)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java: 167)
at android.os.Handler.dispatchMessage(Handler.java: 106)
at android.os.Looper.loop(Looper.java: 164)
at android.app.ActivityThread.main(ActivityThread.java: 6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java: 438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java: 807)


代码:

public class DashboardActivity extends AppCompatActivity {
  DBHandler dbHandler;
  DashboardActivity activity;
  Toolbar dashboard_toolbar;
  RecyclerView rv_dashboard;
  FloatingActionButton fab_dashboard;
  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dashboard);
    dashboard_toolbar=findViewById(R.id.dashboard_toolbar);
    rv_dashboard=findViewById(R.id.rv_dashboard);
    fab_dashboard=findViewById(R.id.fab_dashboard);
    getSupportActionBar(dashboard_toolbar);
    setTitle("Dashboard");
    activity=this;
    dbHandler=new DBHandler(activity);
    rv_dashboard.setLayoutManager(new LinearLayoutManager(activity));
    fab_dashboard.setOnClickListener(new View.OnClickListener() {
      @Override public void onClick(View v) {
        AlertDialog.Builder dialog=new AlertDialog.Builder(activity);
        dialog.setTitle("Add ToDo");
        View view=getLayoutInflater().inflate(R.layout.dialog_dashboard, null);
        final EditText toDoName=view.findViewById(R.id.ev_todo);
        dialog.setView(view);
        dialog.setPositiveButton("Add", new DialogInterface.OnClickListener() {
          @Override public void onClick(DialogInterface dialogInterface, int i) {
            if (toDoName.getText().toString().length() > 0) {
              ToDo toDo=new ToDo();
              toDo.setName(toDoName.getText().toString());
              dbHandler.addToDo(toDo);
              refreshList();
            }
          }
        }
        );
        dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
          @Override public void onClick(DialogInterface dialogInterface, int i) {}
        }
        );
        dialog.show();
      }
    }
    );
  }
  private void getSupportActionBar(Toolbar dashboard_toolbar) {}
  @Override protected void onResume() {
    refreshList();
    super.onResume();
  }
  public void updateToDo(final ToDo toDo) {
    AlertDialog.Builder dialog=new AlertDialog.Builder(activity);
    dialog.setTitle("Update ToDo");
    View view=getLayoutInflater().inflate(R.layout.dialog_dashboard, null);
    final EditText toDoName=view.findViewById(R.id.ev_todo);
    toDoName.setText(toDo.getName());
    dialog.setView(view);
    dialog.setPositiveButton("Update", new DialogInterface.OnClickListener() {
      @Override public void onClick(DialogInterface dialogInterface, int i) {
        if (toDoName.getText().toString().length() > 0) {
          toDo.setName(toDoName.getText().toString());
          dbHandler.updateToDo(toDo);
          refreshList();
        }
      }
    }
    );
    dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
      @Override public void onClick(DialogInterface dialogInterface, int i) {}
    }
    );
    dialog.show();
  }
  public void refreshList() {
    rv_dashboard.setAdapter(new DashboardAdapter(activity, dbHandler.getToDos()));
  }
  class DashboardAdapter extends RecyclerView.Adapter < DashboardAdapter.ViewHolder> {
    ArrayList < ToDo>list;
    DashboardActivity activity;
    DashboardAdapter(DashboardActivity activity, ArrayList < ToDo > list) {
      this.list=list;
      this.activity=activity;
      Log.d("DashboardAdapter", "DashboardAdapter");
      Log.d("DashboardAdapter", "list : " + list.size());
    }
    @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
      return new ViewHolder(LayoutInflater.from(activity).inflate(R.layout.rv_child_dashboard, viewGroup, false));
    }
    @Override public void onBindViewHolder(@NonNull final ViewHolder holder, final int i) {
      holder.toDoName.setText(list.get(i).getName());
      holder.toDoName.setOnClickListener(new View.OnClickListener() {
        @Override public void onClick(View view) {
          Intent intent=new Intent(activity, ItemActivity.class);
          intent.putExtra(INTENT_TODO_ID, list.get(i).getId());
          intent.putExtra(INTENT_TODO_NAME, list.get(i).getName());
          activity.startActivity(intent);
        }
      }
      );
      holder.menu.setOnClickListener(new View.OnClickListener() {
        @Override public void onClick(View view) {
          PopupMenu popup=new PopupMenu(activity, holder.menu);
          popup.inflate(R.menu.dashboard_child);
          popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override public boolean onMenuItemClick(MenuItem menuItem) {
              switch (menuItem.getItemId()) {
                case R.id.menu_edit: {
                  activity.updateToDo(list.get(i));
                  break;
                }
                case R.id.menu_delete: {
                  AlertDialog.Builder dialog=new AlertDialog.Builder(activity);
                  dialog.setTitle("Are you sure");
                  dialog.setMessage("Do you want to delete this task ?");
                  dialog.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
                    @Override public void onClick(DialogInterface dialogInterface, int i) {
                      activity.dbHandler.deleteToDo(list.get(i).getId());
                      activity.refreshList();
                    }
                  }
                  );
                  dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override public void onClick(DialogInterface dialogInterface, int i) {}
                  }
                  );
                  dialog.show();
                }
                case R.id.menu_mark_as_completed: {
                  activity.dbHandler.updateToDoItemCompletedStatus(list.get(i).getId(), true);
                  break;
                }
                case R.id.menu_reset: {
                  activity.dbHandler.updateToDoItemCompletedStatus(list.get(i).getId(), false);
                  break;
                }
              }
              return true;
            }
          }
          );
          popup.show();
        }
      }
      );
    }
    @Override public int getItemCount() {
      return list.size();
    }
    class ViewHolder extends RecyclerView.ViewHolder {
      TextView toDoName;
      ImageView menu;
      ViewHolder(View v) {
        super(v);
        toDoName=v.findViewById(R.id.tv_todo_name);
        menu=v.findViewById(R.id.iv_menu);
      }
    }
  }
}

***DBHandler:*** public class DBHandler extends SQLiteOpenHelper {
  public DBHandler(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
  }
  @Override public void onCreate(SQLiteDatabase db) {
    String createToDoTable=" CREATE TABLE "+TABLE_TODO+" ("+COL_ID+" integer PRIMARY KEY AUTOINCREMENT,"+COL_CREATED_AT+" datetime DEFAULT CURRENT_TIMESTAMP,"+COL_NAME+" varchar)";
    String createToDoItemTable=" CREATE TABLE "+TABLE_TODO_ITEM+" ("+COL_ID+" integer PRIMARY KEY AUTOINCREMENT,"+COL_CREATED_AT+" datetime DEFAULT CURRENT_TIMESTAMP,"+COL_TODO_ID+" integer,"+COL_ITEM_NAME+" varchar,"+COL_IS_COMPLETED+" integer)";
    db.execSQL(createToDoTable);
    db.execSQL(createToDoItemTable);
  }
  @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {}
  boolean addToDo(ToDo todo) {
    SQLiteDatabase db=getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put(COL_NAME, todo.getName());
    long result=db.insert(TABLE_TODO, null, cv);
    return result !=-1;
  }
  void updateToDo(ToDo todo) {
    SQLiteDatabase db=getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put(COL_NAME, todo.getName());
    db.update(TABLE_TODO, cv, COL_ID + "=?", new String[] {
      String.valueOf(todo.getId())
    }
    );
  }
  void deleteToDo(Long todoId) {
    SQLiteDatabase db=getWritableDatabase();
    db.delete(TABLE_TODO_ITEM, COL_TODO_ID + "=?", new String[] {
      String.valueOf(todoId)
    }
    );
    db.delete(TABLE_TODO, COL_ID + "=?", new String[] {
      String.valueOf(todoId)
    }
    );
  }
  void updateToDoItemCompletedStatus(Long todoId, Boolean isCompleted) {
    SQLiteDatabase db=getWritableDatabase();
    Cursor queryResult=db.rawQuery(" SELECT * FROM " + TABLE_TODO_ITEM +" WHERE " + COL_TODO_ID + "="+ todoId, null);
    if (queryResult.moveToFirst()) {
      do {
        ToDoItem item=new ToDoItem();
        item.setId(queryResult.getLong(queryResult.getColumnIndex(COL_ID)));
        item.setToDoId(queryResult.getLong(queryResult.getColumnIndex(COL_TODO_ID)));
        item.setItemName(queryResult.getString(queryResult.getColumnIndex(COL_ITEM_NAME)));
        item.setCompleted(isCompleted);
        updateToDoItem(item);
      }
      while (queryResult.moveToNext());
    }
    queryResult.close();
  }
  public void updateToDoItem(ToDoItem item) {
    SQLiteDatabase db=getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put(COL_ITEM_NAME, item.getItemName());
    cv.put(COL_TODO_ID, item.getToDoId());
    cv.put(COL_IS_COMPLETED, item.isCompleted());
    db.update(TABLE_TODO_ITEM, cv, COL_ID + "=?", new String [] {
      String.valueOf(item.getId())
    }
    );
  }
  ArrayList<ToDo>getToDos() {
    ArrayList<ToDo>result=new ArrayList<>();
    SQLiteDatabase db=getReadableDatabase();
    Cursor queryResult=db.rawQuery(" SELECT * from " + TABLE_TODO, null);
    if(queryResult.moveToFirst()) {
      do {
        ToDo todo=new ToDo();
        todo.setId(queryResult.getLong(queryResult.getColumnIndex(COL_ID)));
        todo.setName(queryResult.getString(queryResult.getColumnIndex(COL_NAME)));
        result.add(todo);
      }
      while(queryResult.moveToNext());
    }
    queryResult.close();
    return result;
  }
  public boolean addToDoItem(ToDoItem item) {
    SQLiteDatabase db=getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put(COL_ITEM_NAME, item.getItemName());
    cv.put(COL_TODO_ID, item.getToDoId());
    cv.put(COL_IS_COMPLETED, item.isCompleted());
    long result=db.insert(TABLE_TODO_ITEM, null, cv);
    return result!=-1;
  }
  public void deleteToDoItem(long itemId) {
    SQLiteDatabase db=getWritableDatabase();
    db.delete(TABLE_TODO_ITEM, COL_ID + "=?", new String[] {
      String.valueOf(itemId)
    }
    );
  }
  public ArrayList<ToDoItem>getToDoItems(long todoId) {
    ArrayList<ToDoItem>result=new ArrayList<>();
    SQLiteDatabase db=getReadableDatabase();
    Cursor queryResult=db.rawQuery("SELECT * FROM " + TABLE_TODO_ITEM + " WHERE " + COL_TODO_ID + "=" + todoId, null);
    if (queryResult.moveToFirst()) {
      do {
        ToDoItem item=new ToDoItem();
        item.setId(queryResult.getLong(queryResult.getColumnIndex(COL_ID)));
        item.setToDoId(queryResult.getLong(queryResult.getColumnIndex(COL_TODO_ID)));
        item.setItemName(queryResult.getString(queryResult.getColumnIndex(COL_ITEM_NAME)));
        item.setCompleted(queryResult.getInt(queryResult.getColumnIndex(COL_IS_COMPLETED))==1);
        result.add(item);
      }
      while (queryResult.moveToNext());
    }
    queryResult.close();
    return result;
  }
}


这是我每次尝试从列表中删除任务时都会遇到的错误,在按继续按钮从列表中删除任务后,应用程序立即关闭。为了解决此问题,我需要做什么?

另外,我在列表中添加的项目之间的空间很大,如何更改它?

最佳答案

我在DashboardAdapter中进行了更改,请检查更新的适配器代码。

class DashboardAdapter extends RecyclerView.Adapter < DashboardAdapter.ViewHolder> {
    ArrayList < ToDo>list;
    DashboardActivity activity;
    DashboardAdapter(DashboardActivity activity, ArrayList < ToDo > list) {
      this.list=list;
      this.activity=activity;
      Log.d("DashboardAdapter", "DashboardAdapter");
      Log.d("DashboardAdapter", "list : " + list.size());
    }
    @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
      return new ViewHolder(LayoutInflater.from(activity).inflate(R.layout.rv_child_dashboard, viewGroup, false));
    }
    @Override public void onBindViewHolder(@NonNull final ViewHolder holder, final int i) {
ToDo todoModel=list.get(i);//added this line
      holder.toDoName.setText(list.get(i).getName());
      holder.toDoName.setOnClickListener(new View.OnClickListener() {
        @Override public void onClick(View view) {
          Intent intent=new Intent(activity, ItemActivity.class);
          intent.putExtra(INTENT_TODO_ID, list.get(i).getId());
          intent.putExtra(INTENT_TODO_NAME, list.get(i).getName());
          activity.startActivity(intent);
        }
      }
      );
      holder.menu.setOnClickListener(new View.OnClickListener() {
        @Override public void onClick(View view) {
          PopupMenu popup=new PopupMenu(activity, holder.menu);
          popup.inflate(R.menu.dashboard_child);
          popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override public boolean onMenuItemClick(MenuItem menuItem) {
              switch (menuItem.getItemId()) {
                case R.id.menu_edit: {
                  activity.updateToDo(list.get(i));
                  break;
                }
                case R.id.menu_delete: {
                  AlertDialog.Builder dialog=new AlertDialog.Builder(activity);
                  dialog.setTitle("Are you sure");
                  dialog.setMessage("Do you want to delete this task ?");
                  dialog.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
                    @Override public void onClick(DialogInterface dialogInterface, int i) {
                      activity.dbHandler.deleteToDo(todoModel.getId());
                      activity.refreshList();
                    }
                  }
                  );
                  dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override public void onClick(DialogInterface dialogInterface, int i) {}
                  }
                  );
                  dialog.show();
                }
                case R.id.menu_mark_as_completed: {
                  activity.dbHandler.updateToDoItemCompletedStatus(list.get(i).getId(), true);
                  break;
                }
                case R.id.menu_reset: {
                  activity.dbHandler.updateToDoItemCompletedStatus(list.get(i).getId(), false);
                  break;
                }
              }
              return true;
            }
          }
          );
          popup.show();
        }
      }
      );
    }
    @Override public int getItemCount() {
      return list.size();
    }
    class ViewHolder extends RecyclerView.ViewHolder {
      TextView toDoName;
      ImageView menu;
      ViewHolder(View v) {
        super(v);
        toDoName=v.findViewById(R.id.tv_todo_name);
        menu=v.findViewById(R.id.iv_menu);
      }
    }
  }
}

10-07 15:46