我收到空指针异常 - 错误,因为我查看器找不到任何Checkbox。 有谁知道我如何解决这个问题?
这是得到错误的行: viewHolder.getCheckBox()。setChecked(Exercise.isChecked()); (用箭头向下标记)
XML EditWorkout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Spinner
android:id="@+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/mainListView"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_weight="0"
android:gravity="bottom">
<Button
android:id="@+id/button_EditWorkout_Save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save"/>
<Button
android:id="@+id/button_Workout_Cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"/>
</LinearLayout>
</LinearLayout>
XML Simplerow.xml
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/rowTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textSize="16sp" />
<CheckBox android:id="@+id/CheckBox01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentRight="true"
android:layout_marginRight="6sp"
android:focusable="false" />
</RelativeLayout>
Java EditWorkout:
public class EditWorkout extends SherlockActivity implements OnItemSelectedListener
{
private ListView mainListView;
private ArrayAdapter<Exercise> listAdapter;
private String workoutName;
ArrayList<Exercise> exerciseList = new ArrayList<Exercise>();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = getIntent();
workoutName = intent.getStringExtra(ListWorkoutActivity.WORKOUT_NAME);
setContentView(R.layout.editworkout);
// Find the ListView resource.
mainListView = (ListView) findViewById( R.id.mainListView );
// When item is tapped, toggle checked properties of CheckBox and Exercise.
mainListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick( AdapterView<?> parent, View item, int position, long id)
{
Exercise Exercise = listAdapter.getItem( position );
Exercise.toogleChecked();
ExerciseViewHolder viewHolder = (ExerciseViewHolder) item.getTag();
-----> viewHolder.getCheckBox().setChecked( Exercise.isChecked() <------ );
}//End of onItemClick
});//End of Listener
// Since we don't have a database we manually put in exercises
//Could use a Arraylist directly but we use a String since we will load
//String-Arrays from the database we use a String-array here
if(exerciseList.isEmpty())
{
exerciseList.add(new Exercise("pushup"));
exerciseList.add(new Exercise("sit-up"));
exerciseList.add(new Exercise("sit-up"));
exerciseList.add(new Exercise("sit-up"));
exerciseList.add(new Exercise("sit-up"));
}
// Set our custom Arrayadapter as the ListView's adapter.
listAdapter = new ExerciseArrayAdapter(this, exerciseList);
mainListView.setAdapter( listAdapter );
}
Java练习:
public class Exercise
{
private String name = "" ;
private boolean checked = false ;
/**
* */
public Exercise( String name ) {
this.name = name ;
}
public Exercise( String name, boolean checked ) {
this.name = name ;
this.checked = checked ;
}
public String getName() {
return name;
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public String toString() {
return name ;
}
public void toogleChecked() {
checked = !checked ;
}
}
Java ExerciseViewHolder:
公共类ExerciseViewHolder { private CheckBox checkBox; 私有TextView textView;
/** * Creates a new holder with the given name and a checkbox * The name is the name of the exercise */ public ExerciseViewHolder( TextView textView, CheckBox checkBox ) { this.checkBox = checkBox; this.textView = textView; } /** * Gets the checkbox of the holder * @return the holders checkbox. */ public CheckBox getCheckBox() { return checkBox; } /** * Gets the name of the holder * @return the holders name */ public TextView getTextView() { return textView; } }
public class ExerciseArrayAdapter extends ArrayAdapter<Exercise> {
private LayoutInflater inflater;
public ExerciseArrayAdapter( Context context, List<Exercise> exerciseList )
{
super( context, R.layout.simplerow, R.id.rowTextView, exerciseList );
// Cache the LayoutInflate to avoid asking for a new one each time.
inflater = LayoutInflater.from(context);
}
/**Since we display other things than a TextView we need to Override a getView-method.
* This method is the one that got the focus on the screen and is returning the View
* when the user clicks on a exercise.
* @param position The place where the user clicks refereed as an Int.
* @param convertView The view, each view will be represented as an simplerow
* with an textfield and a checkbox.
* @return View*/
public View getView(int position, View convertView)
{
// Exercise to display
Exercise exercise = (Exercise) this.getItem( position );
Log.v("Convertview", String.valueOf(position));
//What each view contains.
CheckBox checkBox;
TextView textView;
//If the view doesn't exist, we create a new row view. Initially
//the screen is filled up, when the screen is full the convertView
// is not null and will there after go to the else-statement
if ( convertView == null)
{
convertView = inflater.inflate(R.layout.simplerow, null);
// Find the child views.
textView = (TextView) convertView.findViewById( R.id.rowTextView );
checkBox = (CheckBox) convertView.findViewById( R.id.CheckBox01 );
// Optimization: Tag the row with it's child views, so we don't have to
// call findViewById() later when we reuse the row in our else case.
convertView.setTag( new ExerciseViewHolder(textView,checkBox) );
// If CheckBox is toggled, update the Exercise it is tagged with.
checkBox.setOnClickListener( new View.OnClickListener()
{
/** When the user click on a exercise, the checkbox
* for the exercise is getting unchecked or checked
* @param v The view the user clicks on, this view will
* refeer to a exercise since the view contains
* a exercise.
* */
public void onClick(View v)
{
CheckBox cb = (CheckBox) v;
Exercise exercise = (Exercise) cb.getTag();
exercise.setChecked( cb.isChecked() );
}
});
}
//Is used when the user are scrolling down or up to list existing views but now the
//the elements in the highest view with another element if the user scroll up or
//the lowest view if the user scroll down.
else
{
// Because we use a ViewHolder, we avoid having to call findViewById().
ExerciseViewHolder viewHolder = (ExerciseViewHolder) convertView.getTag();
checkBox = viewHolder.getCheckBox();
textView = viewHolder.getTextView();
}
// Tag the CheckBox with the Exercise it is displaying, so that we can
// access the Exercise in onClick() when the CheckBox is clicked.
checkBox.setTag( exercise );
// Display Exercise
checkBox.setChecked( exercise.isChecked() );
textView.setText( exercise.getName() );
return convertView;
}
}