title: How to filter ArrayAdapter?
body: <p>I'm working on a homework planner app, and I'm looking for a way to display only certain elements in an ArrayList that holds Task objects. After the user clicks on a course from a list of course titles, the list of tasks that pertain to that course should be displayed. Currently, it shows a list of all tasks, no matter which course has been selected. Each Task object stores the course that it belongs to, in a field called mBelongsToCourse. I would like to be able to filter the ArrayList of all tasks that is used in my TaskAdapter to only show the tasks which belong to a specific course, but all my attempts have been fruitless. </p>
  
  <p>Below is my TaskListFragment Class, which includes the TaskAdapter:</p>
  
  <pre><code>public class TaskListFragment extends ListFragment {
  
  private ArrayList&lt;Task&gt; mTasks;
  private  static String courseName;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setHasOptionsMenu(true);
      courseName = getActivity().getIntent().getStringExtra("name");
      getActivity().setTitle(courseName);
      mTasks = TaskLab.get(getActivity()).getTasks();
  
      TaskAdapter adapter = new TaskAdapter(mTasks);
      setListAdapter(adapter);
  }
  
  
  @Override
  public void onListItemClick(ListView l, View v, int position, long id) {
      //Get the Task from the adapter
      Task t = ((TaskAdapter)getListAdapter()).getItem(position);
  
      // Start TaskActivity for this task
      Intent i = new Intent(getActivity(), TaskActivity.class);
      i.putExtra(TaskFragment.EXTRA_TASK_ID, t.getId());
      startActivity(i);
  }
  
  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
      super.onCreateOptionsMenu(menu, inflater);
      inflater.inflate(R.menu.fragment_task_list, menu);
  } 
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
      switch (item.getItemId()) {
      case R.id.menu_item_new_task:
          Task task = new Task();
          task.setBelongsToCourse(courseName);
          TaskLab.get(getActivity()).addTask(task);
          Intent i = new Intent(getActivity(), TaskActivity.class);
          i.putExtra(TaskFragment.EXTRA_TASK_ID, task.getId());
          //i.putExtra("cn", task.getBelongsToCourse());
          startActivityForResult(i, 0);
          return true;
      default:
          return super.onOptionsItemSelected(item);
      }
  }
  
  @Override
  public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
      getActivity().getMenuInflater().inflate(R.menu.task_list_item_context, menu);
  }
  
  
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup parent,
          Bundle savedInstanceState) {
      View v = super.onCreateView(inflater, parent, savedInstanceState);
      ListView listView = (ListView)v.findViewById(android.R.id.list);
      listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
  
      listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
  
          public void onItemCheckedStateChanged(ActionMode mode, int position,
                  long id, boolean checked) {
              // Required, but not used in this implementation
          }
  
          // ActionMode.Callback methods
          public boolean onCreateActionMode(ActionMode mode, Menu menu) {
              MenuInflater inflater = mode.getMenuInflater();
              inflater.inflate(R.menu.task_list_item_context, menu);
              return true;
          }
  
          public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
              return false;
              // Required, but not used in this implementation
          }
          public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
              switch (item.getItemId()) {
              case R.id.menu_item_delete_task:
                  TaskAdapter adapter = (TaskAdapter)getListAdapter();
                  TaskLab taskLab = TaskLab.get(getActivity());
                  for (int i = adapter.getCount() - 1; i &gt;= 0; i--) {
                      if (getListView().isItemChecked(i)) {   
                          taskLab.deleteTask(adapter.getItem(i));
                      }
                  }
                  mode.finish();
                  adapter.notifyDataSetChanged();
                  return true;
              default:
                  return false;
              }
          }
  
          public void onDestroyActionMode(ActionMode mode) {
              // Required, but not used in this implementation
          }
      });
      return v;
  }
  
  @Override
  public boolean onContextItemSelected(MenuItem item) {
      AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
      int position = info.position;
      TaskAdapter adapter = (TaskAdapter)getListAdapter();
      Task task = adapter.getItem(position);
  
      switch (item.getItemId()) {
      case R.id.menu_item_delete_task:
          TaskLab.get(getActivity()).deleteTask(task);
          adapter.notifyDataSetChanged();
          return true;
      }
      return super.onContextItemSelected(item);
  }
  
  
  @Override
  public void onResume() {
      super.onResume();
      ((TaskAdapter)getListAdapter()).notifyDataSetChanged();
  }
  
  private class TaskAdapter extends ArrayAdapter&lt;Task&gt; {
  
      public TaskAdapter(ArrayList&lt;Task&gt; tasks) {
          super(getActivity(), 0, tasks);
      }
  
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          // If we weren't given a view, inflate one
          if (convertView == null) {
              convertView = getActivity().getLayoutInflater()
                      .inflate(R.layout.list_item_task, null);
          }
  
          // Configure the view for this Task
          Task t = getItem(position);
  
          TextView titleTextView =
                  (TextView)convertView.findViewById(R.id.task_list_item_titleTextView);
          titleTextView.setText(t.getTitle());
          TextView dateTextView =
                  (TextView)convertView.findViewById(R.id.task_list_item_dateTextView);
          dateTextView.setText(t.getDate().toString());
          CheckBox completedCheckBox =
                  (CheckBox)convertView.findViewById(R.id.task_list_item_completedCheckBox);
          completedCheckBox.setChecked(t.isCompleted());
          return convertView;
      }
  
  
  }
  }
  </code></pre>
  
  <p>Any help would be greatly appreciated.</p>
  
  <p>EDIT: I've followed the advice of Ravind Maurya and Embattled Swag and updated my TaskAdapter:</p>
  
  <pre><code>private class TaskAdapter extends ArrayAdapter&lt;Task&gt; implements Filterable {
  
      private ArrayList&lt;Task&gt; taskList;
      private Filter taskFilter;
  
      public TaskAdapter(ArrayList&lt;Task&gt; tasks) {
          super(getActivity(), 0, tasks);
          this.taskList = tasks;
      }
  
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          // If we weren't given a view, inflate one
          if (convertView == null) {
              convertView = getActivity().getLayoutInflater()
                      .inflate(R.layout.list_item_task, null);
          }
  
          // Configure the view for this Task
          Task t = getItem(position);
  
          TextView titleTextView =
                  (TextView)convertView.findViewById(R.id.task_list_item_titleTextView);
          titleTextView.setText(t.getTitle());
          TextView dateTextView =
                  (TextView)convertView.findViewById(R.id.task_list_item_dateTextView);
          dateTextView.setText(t.getDate().toString());
          CheckBox completedCheckBox =
                  (CheckBox)convertView.findViewById(R.id.task_list_item_completedCheckBox);
          completedCheckBox.setChecked(t.isCompleted());
          return convertView;
      }
  
      @Override
      public Filter getFilter() {
          if (taskFilter == null)
              taskFilter = new TaskFilter();
  
          return taskFilter;
      }
  
      private class TaskFilter extends Filter {
  
          @Override
          protected FilterResults performFiltering (CharSequence constraint) {
              FilterResults results = new FilterResults();
              if (constraint == null | constraint.length() == 0) {
                  results.values = taskList;
                  results.count = taskList.size();
              } else {
                  ArrayList&lt;Task&gt; newTaskList = new ArrayList&lt;Task&gt;();
                  for (Task t : taskList) {
                      if (t.getBelongsToCourse().toUpperCase().startsWith(constraint.toString().toUpperCase())) {
                          newTaskList.add(t);
                      }
                  }
                  results.values = newTaskList;
                  results.count = newTaskList.size();
              } return results;
          }
  
          @SuppressWarnings("unchecked")
          @Override
          protected void publishResults(CharSequence constraint,
                  FilterResults results) {
  
              // Now we have to inform the adapter about the new list filtered
              if (results.count == 0)
                  notifyDataSetInvalidated();
              else {
                  taskList = (ArrayList&lt;Task&gt;)results.values;
                  notifyDataSetChanged();
              }
  
          }
      }
  
  }
  </code></pre>
  
  <p>Now the problem I have is I don't know where to call .getFilter().filter(courseName) in order to filter the ArrayList. </p>