我在ListView中有一个具有自定义适配器的复选框。复选框最初是不可见的,但是当用户单击“添加”按钮将项目添加到ListView时,我想将其中的一定数量设置为可见。可见的复选框的数量取决于用户输入,例如,如果用户键入多个集合为5,则将有5个可用于ListView项目的复选框。我在自定义适配器类中有一个名为showCheckBoxes()的方法,并在数据库中发生数据更改时在主活动中调用它。我在自定义适配器类中实例化了我的复选框,但是如果我在主活动的onStart()中调用showCheckboxes(),我会得到setVisibility()方法的空指针异常。如果我在自定义适配器类的getView()中调用showCheckBoxes(),应用程序运行时没有错误,但复选框仍然不可见。
logcat的:
01-10 12:52:58.711 11470-11470/com.josh2.mygains E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.josh2.mygains, PID: 11470
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.CheckBox.setVisibility(int)' on a null object reference
at com.josh2.mygains.ExerciseList.showCheckBoxes(ExerciseList.java:91)
at com.josh2.mygains.WorkoutActivity$3.onDataChange(WorkoutActivity.java:102)
at com.google.android.gms.internal.to.zza(Unknown Source:13)
at com.google.android.gms.internal.vj.zzHX(Unknown Source:2)
at com.google.android.gms.internal.vp.run(Unknown Source:65)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6809)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
自定义适配器类(尝试通过在getView()中调用showCheckBoxes()来设置可见复选框):
public class ExerciseList extends ArrayAdapter<Exercise> {
private Activity context;
List<Exercise> exercises;
private CheckBox checkBox1;
private CheckBox checkBox2;
private CheckBox checkBox3;
private CheckBox checkBox4;
private CheckBox checkBox5;
private CheckBox checkBox6;
public ExerciseList(Activity context, List<Exercise> exercises) {
super(context, R.layout.layout_exercise_list, exercises);
this.context = context;
this.exercises = exercises;
}
public void updateExerciseList(List<Exercise> exercises) {
this.exercises = exercises;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View listViewItem = inflater.inflate(R.layout.layout_exercise_list, null, true);
TextView nameTextView = listViewItem.findViewById(R.id.nameTextView);
TextView setsTextView = listViewItem.findViewById(R.id.setsTextView);
TextView repsTextView = listViewItem.findViewById(R.id.repsTextView);
TextView restTextView = listViewItem.findViewById(R.id.restTextView);
checkBox1 = listViewItem.findViewById(R.id.checkBox1);
checkBox2 = listViewItem.findViewById(R.id.checkBox2);
checkBox3 = listViewItem.findViewById(R.id.checkBox3);
checkBox4 = listViewItem.findViewById(R.id.checkBox4);
checkBox5 = listViewItem.findViewById(R.id.checkBox5);
checkBox6 = listViewItem.findViewById(R.id.checkBox6);
Exercise exercise = exercises.get(position);
if(exercise != null && exercise.getName() != null) {
nameTextView.setText(exercise.getName());
}
if(exercise != null) {
setsTextView.setText("Sets: " + String.valueOf(exercise.getSets()));
}
if(exercise != null) {
repsTextView.setText("Reps: " + String.valueOf(exercise.getReps()));
}
if(exercise != null) {
restTextView.setText("Rest time: " + String.valueOf(exercise.getRestTime()) + " mins");
}
try {
int sets = Integer.parseInt(setsTextView.getText().toString());
showCheckBoxes(sets);
} catch(NumberFormatException e) {
e.printStackTrace();
}
return listViewItem;
}
public void showCheckBoxes(int sets) {
if(sets == 1) {
checkBox1.setVisibility(View.VISIBLE);
} else if(sets == 2) {
checkBox1.setVisibility(View.VISIBLE);
checkBox2.setVisibility(View.VISIBLE);
} else if(sets == 3) {
checkBox1.setVisibility(View.VISIBLE);
checkBox2.setVisibility(View.VISIBLE);
checkBox3.setVisibility(View.VISIBLE);
} else if(sets == 4) {
checkBox1.setVisibility(View.VISIBLE);
checkBox2.setVisibility(View.VISIBLE);
checkBox3.setVisibility(View.VISIBLE);
checkBox4.setVisibility(View.VISIBLE);
} else if(sets == 5) {
checkBox1.setVisibility(View.VISIBLE);
checkBox2.setVisibility(View.VISIBLE);
checkBox3.setVisibility(View.VISIBLE);
checkBox4.setVisibility(View.VISIBLE);
checkBox5.setVisibility(View.VISIBLE);
} else if(sets == 6) {
checkBox1.setVisibility(View.VISIBLE);
checkBox2.setVisibility(View.VISIBLE);
checkBox3.setVisibility(View.VISIBLE);
checkBox4.setVisibility(View.VISIBLE);
checkBox5.setVisibility(View.VISIBLE);
checkBox6.setVisibility(View.VISIBLE);
} /*else {
Toast.makeText(WorkoutActivity.this, "Please enter an amount of sets between 1 and 6.", Toast.LENGTH_LONG).show();
}*/
}
}
主要活动(尝试通过在onStart()中调用showCheckBoxes()设置可见复选框):
public class WorkoutActivity extends AppCompatActivity {
String day;
TextView workoutDayTV;
EditText exerciseNameET;
EditText setsET;
EditText repsET;
EditText restTimeET;
Button addButton;
ExerciseList exerciseAdapter;
ArrayList<Exercise> exercises;
ListView exerciseList;
DatabaseReference dbExercises;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_workout);
dbExercises = FirebaseDatabase.getInstance().getReference("exercises");
Intent intent = getIntent();
day = intent.getStringExtra("day");
exerciseNameET = findViewById(R.id.exerciseNameET);
setsET = findViewById(R.id.setsET);
repsET = findViewById(R.id.repsET);
restTimeET = findViewById(R.id.restTimeET);
addButton = findViewById(R.id.addButton);
workoutDayTV = findViewById(R.id.workoutDayTV);
exerciseList = findViewById(R.id.exerciseList);
exercises = new ArrayList<>();
exerciseAdapter = new ExerciseList(WorkoutActivity.this, exercises);
exerciseList.setAdapter(exerciseAdapter);
workoutDayTV.setText(day + " Workout Schedule");
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addExercise();
}
});
exerciseList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long l) {
Exercise exercise = exercises.get(position);
showExerciseDialog(exercise, exercise.getId(), exercise.getName());
return true;
}
});
}
@Override
protected void onStart() {
super.onStart();
dbExercises.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
exercises.clear();
for(DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Exercise exercise = postSnapshot.getValue(Exercise.class);
if(day.equals(exercise.getDay())) {
exercises.add(exercise);
try {
exerciseAdapter.showCheckBoxes(exercise.getSets());
} catch(NumberFormatException e) {
e.printStackTrace();
}
}
}
exerciseAdapter.updateExerciseList(exercises);
exerciseAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void addExercise() {
String name = exerciseNameET.getText().toString();
try {
int sets = Integer.parseInt(setsET.getText().toString());
int reps = Integer.parseInt(repsET.getText().toString());
int restTime = Integer.parseInt(restTimeET.getText().toString());
if((!TextUtils.isEmpty(name)) && (!TextUtils.isEmpty(setsET.getText().toString())) && (!TextUtils.isEmpty(repsET.getText().toString())) && (!TextUtils.isEmpty(restTimeET.getText().toString()))) {
String id = dbExercises.push().getKey();
Exercise exercise = null;
if(day.equals("Monday")) {
exercise = new Exercise(id,name,sets,reps,restTime,"Monday");
} else if(day.equals("Tuesday")) {
exercise = new Exercise(id,name,sets,reps,restTime,"Tuesday");
} else if(day.equals("Wednesday")) {
exercise = new Exercise(id,name,sets,reps,restTime,"Wednesday");
} else if(day.equals("Thursday")) {
exercise = new Exercise(id,name,sets,reps,restTime,"Thursday");
} else if(day.equals("Friday")) {
exercise = new Exercise(id,name,sets,reps,restTime,"Friday");
} else if(day.equals("Saturday")) {
exercise = new Exercise(id,name,sets,reps,restTime,"Saturday");
} else if(day.equals("Sunday")) {
exercise = new Exercise(id,name,sets,reps,restTime,"Sunday");
}
dbExercises.child(id).setValue(exercise);
exerciseNameET.setText("");
setsET.setText("");
repsET.setText("");
restTimeET.setText("");
}
} catch(NumberFormatException e) {
Toast.makeText(this, "All fields are required. Please complete the missing fields.", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
private void updateExercise(String id, String name, int sets, int reps, int restTime, String day) {
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("exercises").child(id);
Exercise exercise = new Exercise(id, name, sets, reps, restTime, day);
dbRef.setValue(exercise);
}
private boolean deleteExercise(String id) {
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("exercises").child(id);
dbRef.removeValue();
return true;
}
private void showExerciseDialog(final Exercise exercise, final String id, String name) {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View dialogView = inflater.inflate(R.layout.exercise_dialog, null);
dialog.setView(dialogView);
final EditText exerciseNameET = dialogView.findViewById(R.id.exerciseNameET);
final EditText setsET = dialogView.findViewById(R.id.setsET);
final EditText repsET = dialogView.findViewById(R.id.repsET);
final EditText restTimeET = dialogView.findViewById(R.id.restTimeET);
Button updateButton = dialogView.findViewById(R.id.updateButton);
Button deleteButton = dialogView.findViewById(R.id.deleteButton);
dialog.setTitle(name);
dialog.setMessage("Update or delete this exercise.");
final AlertDialog alertDialog = dialog.create();
alertDialog.show();
updateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name = exerciseNameET.getText().toString();
try {
int sets = Integer.parseInt(setsET.getText().toString());
int reps = Integer.parseInt(repsET.getText().toString());
int restTime = Integer.parseInt(restTimeET.getText().toString());
if((!TextUtils.isEmpty(name)) && (!TextUtils.isEmpty(setsET.getText().toString())) && (!TextUtils.isEmpty(repsET.getText().toString())) && (!TextUtils.isEmpty(restTimeET.getText().toString()))) {
updateExercise(id,name,sets,reps,restTime,exercise.getDay());
alertDialog.dismiss();
}
} catch(NumberFormatException e) {
Toast.makeText(getApplicationContext(), "All fields are required. Please complete the missing fields.", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deleteExercise(id);
alertDialog.dismiss();
}
});
}
}
列表视图项XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:orientation="vertical">
<TextView
android:id="@+id/nameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="23sp" />
<TextView
android:id="@+id/setsTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp" />
<TextView
android:id="@+id/repsTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp" />
<TextView
android:id="@+id/restTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.25"
android:orientation="vertical">
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set 1"
android:visibility="invisible" />
<CheckBox
android:id="@+id/checkBox2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set 2"
android:visibility="invisible" />
<CheckBox
android:id="@+id/checkBox3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set 3"
android:visibility="invisible" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.25"
android:orientation="vertical">
<CheckBox
android:id="@+id/checkBox4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set 4"
android:visibility="invisible" />
<CheckBox
android:id="@+id/checkBox5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set 5"
android:visibility="invisible" />
<CheckBox
android:id="@+id/checkBox6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set 6"
android:visibility="invisible" />
</LinearLayout>