繁体   English   中英

如何在ListView数组适配器上正确实现可过滤

[英]How to properly implement filterable on listview array adapter

我正在开发一个便笺应用程序,我需要在实现listview便笺标题的可搜索功能方面获得帮助。 我有一个数组适配器类,该类在其中扩展了filterable,还有一个Note类,用于对内容进行序列化。 现在,我已经在工具栏上实现了搜索栏,但是每当我输入字母时,列表项就消失了,此后我得到一个错误。

主要活动

 public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
       inflater.inflate(R.menu.menu_main, menu);
        SearchManager searchManager =
                (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setMaxWidth(Integer.MAX_VALUE);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                ArrayAdapter<String> arrayAdapter = (ArrayAdapter<String>) mListNotes.getAdapter();
                arrayAdapter.getFilter().filter(newText);
                return false;
            }
        });

NoteAdapter.java

    public class NoteAdapter extends ArrayAdapter<Note> implements Filterable{
    public static final int WRAP_CONTENT_LENGTH = 50;
    public ArrayList<Note> notes;
    public NoteAdapter(Context context, int resource, List<Note> objects) {
        super(context, resource, objects);

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if(convertView == null) {
            convertView = LayoutInflater.from(getContext())
                    .inflate(R.layout.view_note_item, null);
        }

        Note note = getItem(position);

        if(note != null) {
            TextView title = (TextView) convertView.findViewById(R.id.list_note_title);
            TextView date = (TextView) convertView.findViewById(R.id.list_note_date);
            TextView content = (TextView) convertView.findViewById(R.id.list_note_content_preview);

            title.setText(note.getTitle());
            date.setText(note.getDateTimeFormatted(getContext()));

            //correctly show preview of the content (not more than 50 char or more than one line!)
            int toWrap = WRAP_CONTENT_LENGTH;
            int lineBreakIndex = note.getContent().indexOf('\n');
            //not an elegant series of if statements...needs to be cleaned up!
            if(note.getContent().length() > WRAP_CONTENT_LENGTH || lineBreakIndex < WRAP_CONTENT_LENGTH) {
                if(lineBreakIndex < WRAP_CONTENT_LENGTH) {
                    toWrap = lineBreakIndex;
                }
                if(toWrap > 0) {
                    content.setText(note.getContent().substring(0, toWrap) + "...");
                } else {
                    content.setText(note.getContent());
                }
            } else { //if less than 50 chars...leave it as is :P
                content.setText(note.getContent());
            }
        }

        return convertView;
    }
    Filter filter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            ArrayList<Note> myList = new ArrayList<>();
            if (constraint !=null && notes!= null) {
                int length = notes.size();
                int i = 0;
                while (i<length) {
                    Note item = notes.get(i);
                    myList.add(item);
                    i++;
                }
                filterResults.values = myList;
                filterResults.count = myList.size();
            }
            return null;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
notes = (ArrayList<Note>) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }

        }

    };
public Filter getFilter(){
    return filter;
}
}

Note.java

public class Note implements Serializable {
    private long mDateTime; //creation time of the note
    private String mTitle; //title of the note
    private String mContent; //content of the note

    public Note(long dateInMillis, String title, String content) {
        mDateTime = dateInMillis;
        mTitle = title;
        mContent = content;
    }

    public void setDateTime(long dateTime) {
        mDateTime = dateTime;
    }

    public void setTitle(String title) {
        mTitle = title;
    }

    public void setContent(String content) {
        mContent = content;
    }

    public long getDateTime() {
        return mDateTime;
    }

    /**
     * Get date time as a formatted string
     * @param context The context is used to convert the string to user set locale
     * @return String containing the date and time of the creation of the note
     */
    public String getDateTimeFormatted(Context context) {
        SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy                                           HH:mm:ss"
                , context.getResources().getConfiguration().locale);
        formatter.setTimeZone(TimeZone.getDefault());
        return formatter.format(new Date(mDateTime));
    }

    public String getTitle() {
        return mTitle;
    }

    public String getContent() {
        return mContent;
    }
}

日志猫

java.lang.NullPointerException: Attempt to read from field 'int android.widget.Filter$FilterResults.count' on a null object reference
                                                                         at com.app.ben.notetaker.NoteAdapter$1.publishResults(NoteAdapter.java:82)
                                                                         at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                         at android.os.Looper.loop(Looper.java:154)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

我需要在逻辑中包括哪些内容以正确过滤listview项目的标题?

当您应该返回filterResults时,总是从performFiltering()返回null 这在NoteAdapter.java 可能还有其他事情发生,但从这里开始。

编辑:它看起来也不像您在任何地方设置notes ,因此将没有任何内容可以过滤。 您似乎也缺少其他功能,但是也许您没有发布所有内容。

是带有自定义筛选的自定义适配器的示例,看起来像它具有所有功能。 您可以以此为指导。

我希望这有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM