2016-07-20 8 views
1

私は各行にチェックボックスを持ったリストビューを持っています。リストビューで検索するために、セーチビューを実装しました。問題は、リストビューを検索し、改造リストからアイテムXを選択すると、検索ビューからテキストが削除されます。アイテムXの位置がチェックされた元のリストが表示されます。チェックボックスと検索の実装を持つリストビューを表示

例 - 、b、c .... z。

iがリスト上の5個の商品を見ることができます。私はZを見て、それを確認して

B C D E

次いでZを検索します。次にZを削除してA-Eをもう一度見て、Aをチェックします。

これが私のメインです:

public class AddRoomatesScreen extends Activity implements AdapterView.OnItemClickListener,SearchView.OnQueryTextListener { 
SharedPreferences preferences; 
List<String> nameList = new ArrayList<String>(); 
List<String> phoneList = new ArrayList<String>(); 
MyAdapter adapter; 
Button btnSelect; 
String apartmentnumber; 
SearchView searchView; 
ArrayList<Contact> contactList = new ArrayList<>(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.add_roomate); 
    preferences = getSharedPreferences("appData", 0); 
    int apartmentNumber = preferences.getInt("apartmentNumber", 0); 
    apartmentnumber = Integer.toString(apartmentNumber); 
    getAllContacts(this.getContentResolver()); 
    ListView lv = (ListView) findViewById(R.id.lv); 
    adapter = new MyAdapter(nameList,contactList); 
    lv.setAdapter(adapter); 
    lv.setOnItemClickListener(this); 
    lv.setItemsCanFocus(false); 
    lv.setTextFilterEnabled(true); 
    searchView = (SearchView) findViewById(R.id.search_view); 
    searchView.setOnQueryTextListener(this); 
    // adding 
    btnSelect = (Button) findViewById(R.id.addSelectedContacts); 
    btnSelect.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      for(int i = 0; i<adapter.mCheckStates.size(); i++){ 
       Contact contact = (adapter.contactsListCopy.get(adapter.mCheckStates.keyAt(i))); 
       new addRoommate().execute(apartmentnumber, contact.getPhoneNumber()); 
      } 
      preferences = getSharedPreferences("appData", 0); 
      SharedPreferences.Editor editor = preferences.edit(); 
      editor.putBoolean("roomatesLoadedFromDB", false); 
      editor.apply(); 
     } 
    }); 


} 

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

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

@Override 
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
    // TODO Auto-generated method stub 
    adapter.toggle(arg2); 
} 

public void getAllContacts(ContentResolver cr) { 

    Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); 
    while (phones.moveToNext()) { 
     String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 
     String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
     nameList.add(name); 
     phoneList.add(phoneNumber); 
     contactList.add(new Contact(name,phoneNumber)); 
    } 

    phones.close(); 
} 

これは私のアダプタです:

class MyAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener,Filterable { 
    private SparseBooleanArray mCheckStates; 
    LayoutInflater mInflater; 
    TextView tv; 
    CheckBox cb; 
    ValueFilter filter; 
    ArrayList<Contact> contactsList; 
    ArrayList<Contact> contactsListCopy; 

    MyAdapter(List<String> nameList , ArrayList<Contact> contactsList) { 
     mCheckStates = new SparseBooleanArray(contactsList.size()); 
     mInflater = (LayoutInflater) AddRoomatesScreen.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     this.contactsList = contactsList; 
     this.contactsListCopy = this.contactsList; 
     getFilter(); 
    } 

    @Override 
    public int getCount() { 
     return contactsListCopy.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return contactsListCopy.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return 0; 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     // TODO Auto-generated method stub 
     View vi = convertView; 
     if (convertView == null) 
      vi = mInflater.inflate(R.layout.contact_list_item, null); 
     TextView tv = (TextView) vi.findViewById(R.id.textView3); 

     cb = (CheckBox) vi.findViewById(R.id.checkBox); 
     Contact contact = contactsListCopy.get(position); 
     tv.setText(contact.getName()); 
     cb.setTag(position); 
     cb.setChecked(mCheckStates.get(position, false)); 
     cb.setOnCheckedChangeListener(this); 

     return vi; 
    } 

    public boolean isChecked(int position) { 
     return mCheckStates.get(position, false); 
    } 

    public void setChecked(int position, boolean isChecked) { 
     mCheckStates.put(position, isChecked); 
     notifyDataSetChanged(); 
    } 

    public void toggle(int position) { 
     setChecked(position, !isChecked(position)); 
    } 

    @Override 
    public void onCheckedChanged(CompoundButton buttonView, 
           boolean isChecked) { 

     mCheckStates.put((Integer) buttonView.getTag(), isChecked); 
    } 

    @Override 
    public Filter getFilter() { 
     if (filter == null){ 
      filter = new ValueFilter(); 
     } 
      return filter; 

    } 

     private class ValueFilter extends Filter { 


      @Override 
      protected FilterResults performFiltering(CharSequence constraint) { 
       FilterResults results = new FilterResults(); 

       if (constraint != null && constraint.length() > 0) { 
        ArrayList<Contact> temp = new ArrayList<Contact>(); 
        for (int i = 0; i < contactList.size(); i++) { 
         Contact c = contactList.get(i); 
         if ((c.getName().toString()) 
           .contains(constraint.toString())) { 
          temp.add(c); 
         } 
        } 
        results.count = temp.size(); 
        results.values = temp; 
       } else { 
        results.count = contactList.size(); 
        results.values = contactList; 
       } 
       return results; 

      } 

      @Override 
      protected void publishResults(CharSequence constraint, FilterResults results) { 
       contactsListCopy = (ArrayList<Contact>) results.values; 
       notifyDataSetChanged(); 

      } 
     } 


} 

これは私のモデルである:

public class Contact{ 
    private String phoneNumber; 
    private String name; 

    public Contact(String name , String phoneNumber){ 
     this.phoneNumber = phoneNumber; 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 
    public String getPhoneNumber() { 
     return phoneNumber; 
    } 

} 

答えて

3

はEDIT:

あなたが使用することができますあなたの一意のIDとしてカーソルからのID。

このコードは、もともと以下に掲載されたコードと同じです。

あなたの連絡先クラスにIDを追加します。

public class Contact{ 
    private long id; 
    private String phoneNumber; 
    private String name; 

    public Contact(long id, String name , String phoneNumber) { 
     this.id = id; 
     this.phoneNumber = phoneNumber; 
     this.name = name; 
    } 

    public long getId() { 
     return id; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getPhoneNumber() { 
     return phoneNumber; 
    } 

} 

これはあなたがカーソルからIDを取得する方法である:アダプターの変更で

public void getAllContacts(ContentResolver cr) { 

    Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); 
    while (phones.moveToNext()) { 
     long id = phones.getLong(phones.getColumnIndex(ContactsContract.Data._ID)); 
     String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); 
     String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); 
     nameList.add(name); 
     phoneList.add(phoneNumber); 
     contactList.add(new Contact(id, name, phoneNumber)); 
    } 

    phones.close(); 
} 

あなたmCheckStatesへ:

private LongSparseArray<Boolean> mCheckStates; 

以下の元の回答の一部がlongの種類に合わせて変更されましたidのためにed。


問題は、それが濾過されるようごmCheckStatesブールマップはcontactsListCopyと同期して保持されていないということです。 Zは今項目0であるので、あなたはZ上で濾過

  • あなたは、あなたが全体のリストを再表示するにチェックとして、位置0をセットZ、
  • をチェックします。今、Aは位置0であるため、チェックされているように表示されます。

チェックされた位置を追跡する代わりに、チェックされた連絡先を追跡する必要があります。これを行うには、連絡先レコードから一意のIDを使用する必要があります。

ここにあなたが作るために必要な変更です:

はアダプタが一意のIDを使用してください:

@Override 
    public long getItemId(int position) { 
     return contactsListCopy.get(position).getId(); 
    } 

は、今すぐあなたの活動が位置するのではなく、一意のIDを使用しています

@Override 
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 
     adapter.toggle(arg3); 
    } 

アダプタgetView()では、このチェックボックスのIDを使用する必要があります。

cb.setTag(contact.getId()); 
    cb.setChecked(mCheckStates.get(contact.getId(), false)); 

私は混乱を避けるために、いくつかの他の方法を変更します

public boolean isChecked(long id) { 
     return mCheckStates.get(id, false); 
    } 

    public void setChecked(long id, boolean isChecked) { 
     mCheckStates.put(id, isChecked); 
     notifyDataSetChanged(); 
    } 

    public void toggle(long id) { 
     setChecked(id, !isChecked(id)); 
    } 
+0

はい、私はユニークID –

+0

グレートを持っています!更新された答え。 –

+0

私の一意のIDは文字列であり、あなたの解決策は機能しませんでした。私がしたことは、メインアクティビティではint id = 0です。私がリストを初期化するとき、コンストラクタに渡してから1を増分しますが、それは良い解決策ではないと思います。あなたはより良い解決策を持っていますか? –

関連する問題