设置Listview行的颜色时自定义适配器中的空指针异常

时间:2013-11-14 09:33:25

标签: android listview android-listview custom-adapter

我想实现一个待办事项列表应用程序。我有三个活动:一个主要活动,一个添加活动和一个编辑活动。在我的主要活动中,有一个添加按钮和一个列表视图,显示待办事项。单击“添加”按钮时,将执行添加活动。在此活动中,有一个任务的edittext,一个datepicker和一个优先级的微调器。单击确定按钮后,所有这些输入的值将作为一行发送到主活动的列表视图。并且,当单击此列表上的项目时,将执行编辑活动,用户可以更改值。另外一个细节是,每次待办事项根据他们的优先级排序,我会根据截止日期给他们不同的颜色。但是,我不知道如何为此安排自定义适配器。我的自定义适配器类提供空指针异常。任何人都可以帮我解释如何重新安排我的自定义适配器类?提前谢谢。

主要活动:

public class MainActivity extends Activity {

protected static final String main = "mainTask";
private ToDoItemAdapter listAdapter;
ArrayList<String> listString;
ArrayList<ToDoItem> listItems;

private int pos;

public static final int ADD_TASKS = 1;
public static final int EDIT_TASKS = 2;

Button button;
ListView listView;

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

    if(savedInstanceState == null || !savedInstanceState.containsKey("key"))
    {
        listString = new ArrayList<String>();
        listItems = new ArrayList<ToDoItem>();
    }
    else
    {
        listString = savedInstanceState.getStringArrayList("datas");
        listItems = savedInstanceState.getParcelableArrayList("key");
    }

    initUI();
    setListener();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

private void initUI() {

    getViewReferences();
    initializeToDoList();

}

private void setListener() {
    // TODO Auto-generated method stub
    button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent addTaskIntent = new Intent(MainActivity.this, AddActivity.class);
            startActivityForResult(addTaskIntent, ADD_TASKS);
        }
    });

    listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stub
            pos = arg2;
            String sentTask = listItems.get(pos).getTask();
            String sentDate = listItems.get(pos).getDeadline();
            String sentPriority = listItems.get(pos).getPriority();
            String sentStatus =  listItems.get(pos).getStatus();
            ArrayList<String> sentDatas = new ArrayList<String>();
            sentDatas.add(sentTask);
            sentDatas.add(sentDate);
            sentDatas.add(sentPriority);
            sentDatas.add(sentStatus);
            Intent editTaskIntent = new Intent(MainActivity.this, EditingTask.class);
            editTaskIntent.putExtra("mainTask", sentDatas);
            startActivityForResult(editTaskIntent, EDIT_TASKS);
        }
    });

}

private void getViewReferences() {
    // TODO Auto-generated method stub
    button = (Button) findViewById(R.id.addButton);
    listView = (ListView) findViewById(R.id.listView);
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private void initializeToDoList() {
    // TODO Auto-generated method stub
    //listItems = new ArrayList<ToDoItem>();
    //listString = new ArrayList<String>();
    listAdapter = new ToDoItemAdapter(this, R.layout.activity_main, listItems);
    listView.setAdapter(listAdapter);

    View noTaskView = findViewById(R.id.emptyToDoList);
    listView.setEmptyView(noTaskView);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    if (resultCode == Activity.RESULT_OK) {
        switch (requestCode) {
        case ADD_TASKS:
            try {
                updateToDoList(data);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
        case EDIT_TASKS:
            try {
                editToDoList(data);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;
        default:
            break;
        }
    }

    super.onActivityResult(requestCode, resultCode, data);
}

private void editToDoList(Intent data) throws ParseException {
    // TODO Auto-generated method stub
    String toDoEdited = EditingTask.edits;
    ArrayList<String> listEdited = data.getStringArrayListExtra(toDoEdited);
    if(listEdited.size() != 0)
    {
        String editedTask = listEdited.get(0);
        String editedDeadline = listEdited.get(1);
        String editedPriority = listEdited.get(2);
        String editedStatus = listEdited.get(3);

        listItems.get(pos).setTask(editedTask);
        listItems.get(pos).setDeadline(editedDeadline);
        listItems.get(pos).setPriority(editedPriority);
        listItems.get(pos).setStatus(editedStatus);
    }
    else
    {
        listItems.remove(pos);
    }
    setTheAdapter();

}


private void setTheAdapter() throws ParseException {
    // TODO Auto-generated method stub
    sortListItems(listItems);
    refreshListString(listString, listItems);
    listAdapter.notifyDataSetChanged();
}


private void updateToDoList(Intent data) throws ParseException {
    // TODO Auto-generated method stub
    String task = AddActivity.tasks;
    ArrayList<String> list = data.getStringArrayListExtra(task);
    String addedTask = list.get(0);
    String addedDeadline = list.get(1);
    String addedPriority = list.get(2);
    ToDoItem item = new ToDoItem(addedTask, addedDeadline ,"NOT DONE", addedPriority);
    listItems.add(item);
    setTheAdapter();
}

private void refreshListString(ArrayList<String> listString2,
        ArrayList<ToDoItem> listItems2) {
    listString2.clear();
    int size = listItems2.size();

    for(int i = 0; i < size; i++)
    {
        listString2.add(listItems2.get(i).toString());
    }

}

private void sortListItems(ArrayList<ToDoItem> listItems2) {

    int length = listItems2.size();
    ToDoItem myItem;
    for(int i = 0; i < length; i++)
    {
        for(int j = 1; j < (length-i); j++)
        if(listItems2.get(j-1).getPriority().compareTo(listItems2.get(j).getPriority()) < 0)
        {
            myItem = listItems2.get(j-1);
            listItems2.set(j-1, listItems2.get(j));
            listItems2.set(j, myItem);
        }
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putStringArrayList("datas", listString);
    outState.putParcelableArrayList("key", listItems);

}

}

我的自定义适配器类:

public class ToDoItemAdapter extends ArrayAdapter<ToDoItem> { 

Context context;
private int resource; 
ArrayList<ToDoItem> todoItem;

public ToDoItemAdapter(Context context, int resource, ArrayList<ToDoItem> objects) { 

    super(context, resource, objects); 
    this.context = context;
    this.resource = resource;
    this.todoItem = objects;
} 

@Override
    public ToDoItem getItem(int position) {
    return this.todoItem.get(position);
}

@Override
    public int getCount() {
    return this.todoItem.size();
}

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 

    View row;

    if (convertView == null) 
    { 
        /*todoView = new LinearLayout(getContext()); 
        String inflater = Context.LAYOUT_INFLATER_SERVICE; 
        LayoutInflater li; 
        li = (LayoutInflater)getContext().getSystemService(inflater); 
        li.inflate(resource, todoView, true); 
        */

        LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(resource, parent, false);
    } 
    else
    {
        row = convertView;
        ListView list = (ListView) row.findViewById(R.id.listView);
        int len = todoItem.size();
        for(int i = 0; i < len; i++)
        {
            String deadline = todoItem.get(i).getDeadline();
            String status = todoItem.get(i).getStatus();
            String currentDate =  findCurrentDate();
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
            Date data=null;
            try {
                data = sdf.parse(deadline);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Date current =null;
            try {
                current = sdf.parse(currentDate);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if(status.equals("DONE"))
            {
                list.getChildAt(i).setBackgroundColor(0xff00ff00);

            }
            else
            {
                if(data.compareTo(current)>0 || data.compareTo(current)==0){
                    list.getChildAt(i).setBackgroundColor(0x01060018);
                }else if(data.compareTo(current)<0){
                    list.getChildAt(i).setBackgroundColor(0x01060016);
                }
            }
        }
    }

    return row; 
} 

private String findCurrentDate() {
    // TODO Auto-generated method stub
    Calendar cal = Calendar.getInstance();
    int year = cal.get(Calendar.YEAR);
    int month = cal.get(Calendar.MONTH);
    int day = cal.get(Calendar.DAY_OF_MONTH);
    String date = day+"-"+(month+1)+"-"+year;
    return date;
}
}

主要xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" 
android:orientation="vertical">

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

<ListView 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/listView"
    ></ListView>

<TextView android:id="@+id/emptyToDoList"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1.0"
    android:gravity="center"
    android:text="@string/no_task"
    android:textColor="@color/warning" />

Logcat:

11-14 04:11:36.795: E/AndroidRuntime(1472): FATAL EXCEPTION: main
11-14 04:11:36.795: E/AndroidRuntime(1472): java.lang.NullPointerException
11-14 04:11:36.795: E/AndroidRuntime(1472):     at   com.example.enhancedtodolistapplication.ToDoItemAdapter.getView(ToDoItemAdapter.java:94)

todo item class:

public class ToDoItem implements Parcelable{

String task;
String deadline;
String status;
String priority;

public ToDoItem(String task, String deadline, String status, String priority) {
    super();
    this.task = task;
    this.deadline = deadline;
    this.status = status;
    this.priority = priority;
}

 private ToDoItem(Parcel in) {
     task = in.readString();
     deadline = in.readString();
     status = in.readString();
     priority = in.readString();
    }

public String getTask() {
    return task;
}

public void setTask(String task) {
    this.task = task;
}

public String getDeadline() {
    return deadline;
}

public void setDeadline(String deadline) {
    this.deadline = deadline;
}

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

public String getPriority() {
    return priority;
}

public void setPriority(String priority) {
    this.priority = priority;
}

@Override
public String toString() {

    return priority +  "   " + task + "   " + deadline + "   " + status;
}

@Override
public int describeContents() {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public void writeToParcel(Parcel out, int flags) {
    // TODO Auto-generated method stub

    out.writeString(task);
    out.writeString(deadline);
    out.writeString(status);
    out.writeString(priority);

}

public static final Parcelable.Creator<ToDoItem> CREATOR = new Parcelable.Creator<ToDoItem>() {
    public ToDoItem createFromParcel(Parcel in) {
        return new ToDoItem(in);
    }

    public ToDoItem[] newArray(int size) {
        return new ToDoItem[size];
    }
};
}

3 个答案:

答案 0 :(得分:0)

我认为您应该删除for循环并将list.getChildAt(i)替换为row。当列表中的每一行都可见时,getView会被单独调用。您正在试图一次更新所有行,如果它们不可见,则可能尚未创建它们。

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 

    View row;

    if (convertView == null) 
    { 
        LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(resource, parent, false);
    } 
    else
    {
        row = convertView;
    }

    String deadline = todoItem.get(i).getDeadline();
    String status = todoItem.get(i).getStatus();
    String currentDate =  findCurrentDate();
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    Date data = null;
    try {
        data = sdf.parse(deadline);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Date current = null;
    try {
        current = sdf.parse(currentDate);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    if (status.equals("DONE"))
    {
        row.setBackgroundColor(0xff00ff00);
    }
    else
    {
        if (data.compareTo(current) >= 0) {
            row.setBackgroundColor(0x01060018);
        } else if(data.compareTo(current) < 0) {
            row.setBackgroundColor(0x01060016);
        }
    }
    return row; 
} 

答案 1 :(得分:0)

请在适配器中使用此代码,然后将其修复。

public class ToDoItemAdapter extends ArrayAdapter<ToDoItem> { 

Context context;
private int resource; 
ArrayList<ToDoItem> todoItem;

 public ToDoItemAdapter(Context context, int resource, ArrayList<ToDoItem> objects) { 

super(context, resource, objects); 
this.context = context;
this.resource = resource;
this.todoItem = objects;
} 

 @Override
public ToDoItem getItem(int position) {
return this.todoItem.get(position);
 }

   @Override
public int getCount() {
return this.todoItem.size();
  }

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
// TODO Auto-generated method stub 

View row;

if (convertView == null) 
{ 
    /*todoView = new LinearLayout(getContext()); 
    String inflater = Context.LAYOUT_INFLATER_SERVICE; 
    LayoutInflater li; 
    li = (LayoutInflater)getContext().getSystemService(inflater); 
    li.inflate(resource, todoView, true); 
    */

    LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    row = inflater.inflate(resource, parent, false);
} 
else
{
    row = convertView;
    int len = todoItem.size();
    for(int i = 0; i < len; i++)
    {
        String deadline = todoItem.get(i).getDeadline();
        String status = todoItem.get(i).getStatus();
        String currentDate =  findCurrentDate();
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        Date data=null;
        try {
            data = sdf.parse(deadline);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Date current =null;
        try {
            current = sdf.parse(currentDate);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if(status.equals("DONE"))
        {
            row.getChildAt(i).setBackgroundColor(0xff00ff00);

        }
        else
        {
            if(data.compareTo(current)>0 || data.compareTo(current)==0){
                row.getChildAt(i).setBackgroundColor(0x01060018);
            }else if(data.compareTo(current)<0){
                row.getChildAt(i).setBackgroundColor(0x01060016);
            }
        }
    }
}

return row; 
 } 

private String findCurrentDate() {
// TODO Auto-generated method stub
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
String date = day+"-"+(month+1)+"-"+year;
return date;
  }

答案 2 :(得分:0)

您的代码list.getChildAt(i)返回列表的子代。这里int我去了todoItem.size();因为不可能有像todoItem那样多的大小。所以它可能会超出界限。

你应该在这里获得parentLayout的行并设置颜色。