1

연락처 목록을 검색 할 RecyclerView가있는 SearchView가 있습니다. 하지만 검색 결과가 잘못 나온 것 같습니다. 일부 필터링이 발생하지만 올바른 것은 아닙니다. 예를 들어 문자 "a"로 검색하면 a로 시작하는 연락처 대신 무작위로 필터링됩니다. 코드 스 니펫은 다음과 같습니다.RecyclerView 필터링 결과가 잘못된 SearchView 필터

활동 클래스

public class MembersActivity extends AppCompatActivity implements SearchView.OnQueryTextListener { 

@BindView(R.id.meetup_members_recycler_view) 
RecyclerView mRecyclerView; 

CustomContactAdapter contactAdapter; 
List<Contact> contactList = new ArrayList(); 
private SearchView mSearchView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_meetup_members); 
    ButterKnife.bind(this); 
    mSearchView = (SearchView) findViewById(R.id.action_search); 
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 

    getAllContacts(); 
} 
@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.menu_main, menu); 

    final MenuItem searchItem = menu.findItem(R.id.action_search); 
    final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); 
    searchView.setOnQueryTextListener(this); 

    return true; 
} 

private void getAllContacts() { 

    Contact contact; 

    ContentResolver contentResolver = getContentResolver(); 
    Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"); 
    if (cursor.getCount() > 0) { 
     while (cursor.moveToNext()) { 

      int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))); 
      if (hasPhoneNumber > 0) { 
       String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); 
       String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); 

       contact = new Contact(); 
       contact.setName(name); 

       Cursor phoneCursor = contentResolver.query(
         ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
         null, 
         ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", 
         new String[]{id}, 
         null); 
       if (phoneCursor.moveToNext()) { 
        String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
        contact.setMobile(phoneNumber); 
       } 

       phoneCursor.close(); 
       contactList.add(contact); 
      } 
     } 

     contactAdapter = new CustomContactAdapter(getApplicationContext(),contactList); 
     mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 
     mRecyclerView.setAdapter(contactAdapter); 
    } 
} 


@Override 
public boolean onQueryTextSubmit(String query) { 
    return false; 
} 

@Override 
public boolean onQueryTextChange(String newText) { 
    contactAdapter.getFilter().filter(newText); 
    return true; 
} 
} 

어댑터 클래스이 권리를 얻을 수 있도록 할

public class CustomContactAdapter extends RecyclerView.Adapter<CustomContactAdapter.ContactViewHolder> 
    implements CompoundButton.OnCheckedChangeListener,Filterable { 

Context mContext; 
LayoutInflater mInflater; 
private List<Contact> contactList = new ArrayList<Contact>(); 
private List<Contact> filterContactList = new ArrayList<Contact>(); 
private ContactFilter contactFilter; 

public CustomContactAdapter(Context context,List<Contact> contacts) 
{ 
    mInflater = LayoutInflater.from(context); 
    mContext = context; 
    this.contactList = contacts; 
    this.filterContactList = contacts; 

} 

public static class ContactViewHolder extends RecyclerView.ViewHolder 
     implements View.OnClickListener { 
    @BindView(R.id.member_name) 
    TextView mContactName; 
    @BindView(R.id.member_mobile) 
    TextView mPhoneNumber; 
    @BindView(R.id.member_image) 
    ImageView mImage; 

    public ContactViewHolder(View view) { 
     super(view); 
     ButterKnife.bind(this, view); 
     view.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View view){ 

    } 
} 

@Override 
public CustomContactAdapter.ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View itemView = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.member_list_row, parent, false); 

    return new CustomContactAdapter.ContactViewHolder(itemView); 
} 

@Override 
public void onBindViewHolder(CustomContactAdapter.ContactViewHolder holder, int position) { 

    Contact contact = contactList.get(position); 
    holder.mContactName.setText(contact.getName()); 
    holder.mPhoneNumber.setText(contact.getMobile()); 

} 

@Override 
public int getItemCount() { 
    return filterContactList.size(); 
} 

@Override 
public Filter getFilter() { 
    if(contactFilter == null) 
     contactFilter = new ContactFilter(); 
    return contactFilter; 
} 


private class ContactFilter extends Filter { 

    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 
     FilterResults filterResults = new FilterResults(); 
     if (constraint!=null && constraint.length()>0) { 
      ArrayList<Contact> tempList = new ArrayList<Contact>(); 

      for (Contact contact : contactList) { 
       if (contact.getName().toLowerCase().contains(constraint.toString().toLowerCase())) { 
        tempList.add(contact); 
       } 
      } 

      filterResults.count = tempList.size(); 
      filterResults.values = tempList; 
      System.out.println("performFiltering:SearchFoundCount "+ tempList.size()); 
      System.out.println("performFiltering:ActualSize "+ contactList.size()); 

     } else { 
      filterResults.count = contactList.size(); 
      filterResults.values = contactList; 
     } 

     return filterResults; 
    } 

    /** 
    * Notify about filtered list to ui 
    * @param constraint text 
    * @param results filtered result 
    */ 
    @SuppressWarnings("unchecked") 
    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     filterContactList = (ArrayList<Contact>) results.values; 
     notifyDataSetChanged(); 
    } 
} 
} 

수 없습니다, 나는 실종 '바보 뭔가를 할 수있다. 감사합니다.

답변

2

내 앱에서 비슷한 일을하고있었습니다. 는 onBindViewHolder 당신이 당신을 위해 작동하는 최초의 하나 개

@Override 
public void onBindViewHolder(CustomContactAdapter.ContactViewHolder holder, int position) { 

Contact contact = filterContactList.get(position); 
... 

희망 대신 필터링 된 목록을 사용해야합니다. :)

+0

감사합니다. 내게 어리석은 실수였습니다 ... 다시 한 번 감사드립니다. – user2695433

1

검색 결과를 캐릭터와 함께 시작하고 싶다면 FilterResults 메소드를 변경하십시오.

for (Contact contact : contactList) { 
      if (contact.getName().toLowerCase().startsWith(constraint.toString().toLowerCase())) { 
       tempList.add(contact); 
      } 
     } 
0

이것은 또한 작동 할 수 있습니다. 다음 코드를 변경하십시오.