2017-12-31 25 views
0
public class ExerciseList extends ArrayAdapter<Exercise> { 
private Activity context; 
List<Exercise> exercises; 

public ExerciseList(Activity context, List<Exercise> exercises) { 
    super(context, R.layout.layout_exercise_list, exercises); 
    this.context = context; 
    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); 

    Exercise exercise = exercises.get(position); 
    nameTextView.setText(exercise.getName()); 
    setsTextView.setText(String.valueOf(exercise.getSets())); 
    repsTextView.setText(String.valueOf(exercise.getReps())); 
    restTextView.setText(String.valueOf(exercise.getRestTime())); 
    return listViewItem; 
} 

}ONSTART(に使用されるカスタム・アダプタ)が、アプリケーションがクラッシュリストビューに

public class WorkoutActivity extends AppCompatActivity { 

EditText exerciseNameET; 
EditText setsET; 
EditText repsET; 
EditText restTimeET; 
Button addButton; 

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"); 

    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); 
    exerciseList = findViewById(R.id.exerciseList); 

    exercises = new ArrayList<>(); 

    addButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      addExercise(); 
     } 
    }); 
} 

@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); 
       exercises.add(exercise); 
      } 
      ExerciseList exerciseAdapter = new ExerciseList(WorkoutActivity.this, exercises); 
      exerciseList.setAdapter(exerciseAdapter); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 
} 

private void addExercise() { 
    String name = exerciseNameET.getText().toString(); 
    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 = new Exercise(id,name,sets,reps,restTime); 
     dbExercises.child(id).setValue(exercise); 
     exerciseNameET.setText(""); 
     setsET.setText(""); 
     repsET.setText(""); 
     restTimeET.setText(""); 
    } else { 
     Toast.makeText(this, "Invalid fields. Please complete the missing fields.", Toast.LENGTH_LONG).show(); 
    } 
} 

}

の項目を追加するときIのいずれかのリストビューのために使用されるカスタム・アダプタを作成しました私の活動。このカスタムアダプタは、onStart()メソッドで作成されます。私はまた、このListViewの各項目のための別々のレイアウトファイルを持っています。このアプリケーションはFirebaseを使用し、情報をデータベースに正常に保存しますが、この同じ情報をListViewに表示しようとするとアプリケーションがクラッシュします。私は多くのチュートリアルと私の教授のラボソリューションに従ってきましたが、私のアプリがクラッシュする理由はまだ分かりません。主な活動のためのXMLファイルは以下に含まれている:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context="com.josh2.mygains.WorkoutActivity"> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <EditText 
     android:id="@+id/exerciseNameET" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:ems="10" 
     android:hint="Exercise name" 
     android:inputType="textPersonName" /> 

    <EditText 
     android:id="@+id/setsET" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:ems="10" 
     android:hint="Number of sets" 
     android:inputType="textPersonName" /> 

    <EditText 
     android:id="@+id/repsET" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:ems="10" 
     android:hint="Number of reps" 
     android:inputType="textPersonName" /> 

    <EditText 
     android:id="@+id/restTimeET" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:ems="10" 
     android:hint="Length of rest time" 
     android:inputType="textPersonName" /> 

    <Button 
     android:id="@+id/addButton" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="Add" /> 

    <ScrollView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <ListView 
      android:id="@+id/exerciseList" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" /> 
    </ScrollView> 
</LinearLayout> 

リストビューの項目のためのXMLファイルは、以下の発見された:

<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 

<TextView 
    android:id="@+id/nameTextView" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="20sp" /> 

<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" /> 

+1

logcat –

+1

あなたのエラーログを投稿してください。これとは別に、ExerciseList(CustomAdapter)の非常に間違った実装を見ることができます。新しい項目が追加されるたびに新しいアダプタオブジェクトを作成しています。グローバルアダプタオブジェクトを作成してから、変更を反映させるためにadapter.notifyDataSetChanged()を呼び出すだけです。毎回新しいアダプターをセットする必要はありません。 – mark922

答えて

0

アダプタのコードがあります可能なヌルポインタ例外についてはminefieldを参照してください。 String.valueOf(null)はNullPointerExceptionを返しますので、ここで例外を注意深く処理する必要があります。

if(exercise!=null && exercise.getSets()!=null){ 
    setsTextView.setText(String.valueOf(exercise.getSets())); 
} 

残りの2つのセッターについても同様の手順を適用します。

さらに、カスタムアダプターでデータ更新を処理した方法は標準ではありません。 onCreateでアダプタを起動する必要があります。これは、リストが更新されるたびにアダプタを初期化する必要がないためです。あなたは、単にデータベースの後にあなたのデータリストを更新し、あなたのアダプタでリストたびにデータが更新され

public void updateExerciseList(List<Exercise> exercises) { 
this.exercises = exercises; 

}

を更新できるように

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_workout); 

    dbExercises = FirebaseDatabase.getInstance().getReference("exercises"); 

    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); 
    exerciseList = findViewById(R.id.exerciseList); 

    exercises = new ArrayList<>(); 
    ExerciseList exerciseAdapter = new ExerciseList(WorkoutActivity.this, 
          exercises); 
    exerciseList.setAdapter(exerciseAdapter); 

    addButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      addExercise(); 
     } 
    }); 
} 

とカスタムアダプタにupdateExerciseList方法を保ちます更新されました

@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); 
       exercises.add(exercise); 
      } 
      exerciseAdapter.updateExerciseList(exercises); 
      exerciseAdapter.setNotifyDataSetChanged(); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 
} 
関連する問題