如何过滤ArrayAdapter?

时间:2014-01-15 15:39:09

标签: java android android-listview android-arrayadapter

我正在制作一个家庭作业计划器应用程序,我正在寻找一种方法来只显示包含Task对象的ArrayList中的某些元素。用户单击课程标题列表中的课程后,应显示与该课程相关的任务列表。目前,无论选择哪个课程,它都会显示所有任务的列表。每个Task对象在名为mBelongsToCourse的字段中存储它所属的过程。我希望能够过滤我在TaskAdapter中使用的所有任务的ArrayList,只显示属于特定课程的任务,但我的所有尝试都没有结果。

下面是我的TaskListFragment类,其中包含TaskAdapter:

public class TaskListFragment extends ListFragment {

private ArrayList<Task> 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 >= 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<Task> {

    public TaskAdapter(ArrayList<Task> 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;
    }


}
}

非常感谢任何帮助。

编辑:我遵循了Ravind Maurya和Embattled Swag的建议并更新了我的TaskAdapter:

private class TaskAdapter extends ArrayAdapter<Task> implements Filterable {

    private ArrayList<Task> taskList;
    private Filter taskFilter;

    public TaskAdapter(ArrayList<Task> 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<Task> newTaskList = new ArrayList<Task>();
                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<Task>)results.values;
                notifyDataSetChanged();
            }

        }
    }

}

现在我遇到的问题是我不知道在哪里调用.getFilter()。filter(courseName)来过滤ArrayList。

1 个答案:

答案 0 :(得分:0)

昨天我按照这个例子直接提出了一个固体过滤器:http://www.survivingwithandroid.com/2012/10/android-listview-custom-filter-and.html

然而;此示例不包括您使用退格键的情况,因此列表视图必须重新填充。您可以在此处关注通用过滤器的实际源代码(它位于底部...基本上您只需创建一个副本,然后减少其中一个列表的项目):http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/ArrayAdapter.java#ArrayAdapter.0mOriginalValues