2017-08-09 42 views
0

我正在開發一個筆記應用程序,我需要幫助實現listview的筆記標題的可搜索功能。我有一個數組適配器類,它在其中擴展了可過濾性,還有一個用於序列化內容的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項目的標題?

+0

我認爲你需要在適配器上實現Filterable –

回答

0

如果您應該返回filterResults,您總是會從performFiltering()返回null。這是在NoteAdapter.java。可能還有其他事情正在進行,但從這裏開始。

編輯:它也不像你在任何地方設置notes,所以將沒有任何過濾。你似乎也缺少一些其他功能,但也許你沒有發佈一切。

Here是自定義過濾器的示例,它看起來像它具有所有部分。你可以用它作爲指導。

我希望這會有所幫助。

相關問題