私はメモアプリケーションで作業しています。私はリストビューの注釈タイトルの検索可能な機能を実装するのに助けが必要です。私はfilterableを拡張する配列アダプタクラスと、コンテンツを直列化するNoteクラスも持っています。 今のところ、ツールバーに検索バーが実装されていますが、文字を入力するたびにリスト項目が消えてしまい、後でエラーが表示されます。listview配列アダプタでフィルタリングを正しく実装する方法
主な活動
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)
リストビュー項目のタイトルを適切にフィルタリングするために、私のロジックに含める必要があるものは何ですか?
私は、あなたのアダプターにFilterableを実装する必要があると思います –