-1

I want to implement a to-do list application. I have three activities: one main activity, one adding activity and one editing activity. In my main activity there is a add button and a listview that shows the to-do items. When I click add button, adding activity is executed. In this activity,there is an edittext for the task, a datepicker and a spinner for priority level. When ok button is clicked, all these entered values are sent to main activity's listview as a line. And, when click an item on this list, editing activity is executed and user can change the values. One more additional detail is that, each time todo items are sorted according to their priorities and i will give them different colors according to deadlines. However, i don't know how can i arrange a custom adapter for this. My custom adapter class gives a null pointer exception. Can anyone help me about how should rearrange my custom adapter class? Thank you in advance.

Main activity:

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

}

}

My custom adapter class:

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

Main 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];
    }
};
}
Sanket Shah
  • 4,352
  • 3
  • 21
  • 41
cgbs
  • 83
  • 3
  • 13

3 Answers3

0

I think you should remove the for loop and replace list.getChildAt(i) with row. getView is called sereately for each row in your list when it is visible. You are triying to update all rows at once, they might not be created yet if they are not visible.

@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; 
} 
Caner
  • 57,267
  • 35
  • 174
  • 180
0

Please use this code in adapter then it will be fixed.

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;
  }
android_dev
  • 1,477
  • 12
  • 18
  • i tried it, it doesn't give error but it just add "Add!" to listview, items are lost – cgbs Nov 14 '13 at 09:52
  • In your code where your adding the data to the view your not adding any data to that view right ? add the data to that view then it will display. – android_dev Nov 14 '13 at 09:57
  • Right..here you are not adding any data in row. add it, it will be displayed – Connecting life with Android Nov 14 '13 at 10:00
  • opps you are right! Then, should i create another for loop and add each todo item to row? How can i add them? Sorry for my more questions, i'm new in android and i don't know how to use a custom adapter – cgbs Nov 14 '13 at 10:03
0

your code list.getChildAt(i) returning the child of an list. Here int i goes to todoItem.size(); Since it is not possible to have as much size as todoItem has. So it might be going out of bound.

You should get parentLayout of row here and set color.