2017-12-31 23 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; 
} 

내가 정의 어댑터를 만든사용자 정의 어댑터는

}

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(); 
    } 
} 

은} 중 하나의 ListView를 위해 사용되는 내 활동들. 이 사용자 정의 어댑터는 onStart() 메소드에서 작성됩니다. 또한이 ListView의 각 항목에 대해 별도의 레이아웃 파일이 있습니다. 응용 프로그램은 파이어베이스를 사용하여 데이터베이스에 정보를 성공적으로 저장하지만이 정보를 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> 

ListView에의 항목에 대한 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을 반환하므로 여기서 예외를 신중하게 처리해야합니다.

나머지 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) { 

     } 
    }); 
}