Intereting Posts
Как получить значение, хранящееся в ArrayList <HashMap <ключ, значение >>? Как изменить шрифт Навигационный заголовок ящика и ScrollingActivity? Категория предпочтений андроида Android OutOfMemoryError в строке SetContentView SQLite-запрос SQLiteLog (1) нет такой колонки: Поддерживают ли DEX и Dalvik совместимость с двоичными файлами Java? ClassNotFoundException, но я могу найти этот класс в классах.dex Невозможно найти символьную переменную GoogleAuthUtil после обновления до сервисов Google Play 9.0.0 Ошибка плагина после обновления Android Studio 2.1 Доступ к GPS не работает. Приложение использует сеть для получения местоположения Как отладить контрольные тесты в Android Studio? Как я могу проверить, видно ли вид или нет в Android? Остановить CollapsingToolbar от сбрасывания после того, как NestedScrollView закончил контент для прокрутки Как наиболее легко удалять данные приложений Android после обновления / обновления? Проблема с быстрым прокруткой с помощью ListAdapter и SectionIndexer

Множественный выбор Searchable ListView

OK У меня есть множественный выбор ListView, который отлично работает. Я проверяю флажки для контактов (хранящихся в String []) и могу вернуть значения в порядке. Потому что у некоторых людей есть куча контактов, которые я хотел создать в виде панели поиска, например, для телефонной книги Android. Я создал EditText и выровнял его над моим списком. Я нашел код фильтрации здесь, на StackOverflow, и он отлично работает.

Моя проблема:

Когда вы отфильтровываете имя someones, и вы выбираете имя, когда вы либо переходите из EditText, либо продолжаете вводить текст, правильная позиция выбранного вами имени не сохраняется. Например, если я начну набирать «Адам» и перейду к «Аде» и выберем его, если я вернусь к типу в «Кэрол», любая позиция «Ада» была выбрана. Он собирает место, в котором «Адам» находился от щелчка (скажем 2), и когда список восстанавливается, проверяет эту позицию (2), даже если Адама больше нет. Мне нужен способ для сбора имени. Затем, когда список будет восстановлен или снова просмотрен, NAME Adam проверяется, а не POSITION Adam ранее. У меня нет абсолютно никаких идей, кроме создания множества массивов, и я могу действительно помочь. Ниже приведен код, который я использую:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.contacts_list); myListView = (ListView)findViewById(android.R.id.list); search_EditText = (EditText) findViewById(R.id.search_EditText); search_EditText.addTextChangedListener(filterTextWatcher); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, ContactsList); setListAdapter(adapter); myListView.setItemsCanFocus(false); getListView().setChoiceMode(2); myListView.setTextFilterEnabled(true); myListView.setFastScrollEnabled(true); myListView.invalidate(); } private TextWatcher filterTextWatcher = new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } }; 

Я никогда не получал лучшего метода, чем тот, который я приведу ниже. Я больше не использую этот код, и если есть лучшее решение, я надеюсь, что кто-то его разместил где-то.

В результате я создал ArrayList для хранения выбранных имен. Если имя выбрано, имя вставляется в ArrayList , и если оно не отмечено, оно выставляется из списка. Когда afterTextChanged , список перебирается и имена проверяются, если они в настоящее время указаны в адаптере. Когда вы закончите процесс выбора и хотите продолжить, я EditText чтобы очистить фильтр, поэтому заполняет полный список в ListView и устанавливает все выбранные контакты, если они существуют в ArrayList.

Обратите внимание: я использую настраиваемый адаптер для списка контактов, в котором указаны только имена списков, поэтому это решение может запутаться, если вы используете другие типы данных, и я рассматриваю этот метод как взломанное решение:

 /** Used for filter **/ private TextWatcher filterTextWatcher = new TextWatcher() { public void beforeTextChanged(CharSequence s, int start, int count, int after) { ListView listview = getListView(); SparseBooleanArray checked = listview.getCheckedItemPositions(); for (int i = 0; i < ContactsList.length; i++) { if (checked.get(i) == true) { Object o = getListAdapter().getItem(i); String name = o.toString(); // if the arraylist does not contain the name, add it if (selected.contains(name)){ // Do Nothing } else { selected.add(name); } } } } //<-- End of beforeTextChanged public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } //<-- End of onTextChanged public void afterTextChanged(Editable s) { ListView listview = getListView(); // Uncheck everything: for (int i = 0; i < listview.getCount(); i++){ listview.setItemChecked(i, false); } adapter.getFilter().filter(s, new Filter.FilterListener() { public void onFilterComplete(int count) { adapter.notifyDataSetChanged(); ListView listview = getListView(); for (int i = 0; i < adapter.getCount(); i ++) { // if the current (filtered) // listview you are viewing has the name included in the list, // check the box Object o = getListAdapter().getItem(i); String name = o.toString(); if (selected.contains(name)) { listview.setItemChecked(i, true); } else { listview.setItemChecked(i, false); } } } }); } //<-- End of afterTextChanged }; //<-- End of TextWatcher 

Вы не хотите использовать индексы при использовании фильтров, потому что индекс 1 может быть чем-то одним ListView , и это может быть другой элемент ListView при изменении фильтра.

Вы можете создать проект андроида и добавить эти файлы:

Рез / layout-> list_row.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#3c3c3c" android:orientation="horizontal" android:padding="8dp" > <ImageView android:id="@+id/contactimage" android:layout_width="48dp" android:layout_height="48dp" android:layout_marginRight="8dp" android:background="@drawable/ic_launcher" android:contentDescription="@string/app_name" android:scaleType="centerInside" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_toLeftOf="@+id/contactcheck" android:layout_toRightOf="@+id/contactimage" > <TextView android:id="@+id/contactname" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:text="Contact Name" android:textColor="#000" android:textIsSelectable="false" android:textSize="18dp" android:textStyle="bold" /> <TextView android:id="@+id/contactno" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/contactname" android:singleLine="true" android:text="09876543210" android:textColor="#2689e0" android:textIsSelectable="false" android:textSize="14dp" /> </RelativeLayout> <CheckBox android:id="@+id/contactcheck" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerInParent="true" android:layout_marginLeft="8dp" /> </RelativeLayout> 

Рез / layout-> activity_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:id="@+id/input_search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerInParent="true" android:hint="Search Contacts" android:textSize="18dp" /> <LinearLayout android:id="@+id/data_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/ok_button" android:layout_below="@+id/input_search" android:gravity="center|top" android:orientation="vertical" /> <Button android:id="@+id/ok_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerInParent="true" android:text=" OK " android:textSize="18dp" /> <RelativeLayout android:id="@+id/pbcontainer" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#55000000" android:clickable="true" android:visibility="gone" > <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /> </RelativeLayout> </RelativeLayout> 

ContactObject.java

 package com.multiselectlistexample; public class ContactObject { private String contactName; private String contactNo; private String image; private boolean selected; public String getName() { return contactName; } public void setName(String contactName) { this.contactName = contactName; } public String getNumber() { return contactNo; } public void setNumber(String contactNo) { this.contactNo = contactNo; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public boolean isSelected() { return selected; } public void setSelected(boolean selected) { this.selected = selected; } } 

ContactsListClass.java

 package com.multiselectlistexample; import java.util.ArrayList; public class ContactsListClass { public static final ArrayList<ContactObject> phoneList = new ArrayList<ContactObject>(); } 

ContactsAdapter.java

 package com.multiselectlistexample; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; import java.util.Locale; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.provider.ContactsContract.Contacts; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.TextView; public class ContactsAdapter extends BaseAdapter { Context mContext; LayoutInflater inflater; private List<ContactObject> mainDataList = null; private ArrayList<ContactObject> arraylist; public ContactsAdapter(Context context, List<ContactObject> mainDataList) { mContext = context; this.mainDataList = mainDataList; inflater = LayoutInflater.from(mContext); this.arraylist = new ArrayList<ContactObject>(); this.arraylist.addAll(mainDataList); } static class ViewHolder { protected TextView name; protected TextView number; protected CheckBox check; protected ImageView image; } @Override public int getCount() { return mainDataList.size(); } @Override public ContactObject getItem(int position) { return mainDataList.get(position); } @Override public long getItemId(int position) { return position; } public View getView(final int position, View view, ViewGroup parent) { final ViewHolder holder; if (view == null) { holder = new ViewHolder(); view = inflater.inflate(R.layout.list_row, null); holder.name = (TextView) view.findViewById(R.id.contactname); holder.number = (TextView) view.findViewById(R.id.contactno); holder.check = (CheckBox) view.findViewById(R.id.contactcheck); holder.image = (ImageView) view.findViewById(R.id.contactimage); view.setTag(holder); view.setTag(R.id.contactname, holder.name); view.setTag(R.id.contactno, holder.number); view.setTag(R.id.contactcheck, holder.check); holder.check .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton vw, boolean isChecked) { int getPosition = (Integer) vw.getTag(); mainDataList.get(getPosition).setSelected( vw.isChecked()); } }); } else { holder = (ViewHolder) view.getTag(); } holder.check.setTag(position); holder.name.setText(mainDataList.get(position).getName()); holder.number.setText(mainDataList.get(position).getNumber()); if(getByteContactPhoto(mainDataList.get(position).getImage())==null){ holder.image.setImageResource(R.drawable.ic_launcher); }else{ holder.image.setImageBitmap(getByteContactPhoto(mainDataList.get(position).getImage())); } holder.check.setChecked(mainDataList.get(position).isSelected()); return view; } public void filter(String charText) { charText = charText.toLowerCase(Locale.getDefault()); mainDataList.clear(); if (charText.length() == 0) { mainDataList.addAll(arraylist); } else { for (ContactObject wp : arraylist) { if (wp.getName().toLowerCase(Locale.getDefault()) .contains(charText)) { mainDataList.add(wp); } } } notifyDataSetChanged(); } public Bitmap getByteContactPhoto(String contactId) { Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(contactId)); Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY); Cursor cursor = mContext.getContentResolver().query(photoUri, new String[] {Contacts.Photo.DATA15}, null, null, null); if (cursor == null) { return null; } try { if (cursor.moveToFirst()) { byte[] data = cursor.getBlob(0); if (data != null) { return BitmapFactory.decodeStream( new ByteArrayInputStream(data)); } } } finally { cursor.close(); } return null; } } 

MainActivity.java

 package com.multiselectlistexample; import java.util.Collections; import java.util.Comparator; import java.util.Locale; import android.app.Activity; import android.content.Context; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.Toast; public class MainActivity extends Activity { Context context = null; ContactsAdapter objAdapter; ListView lv = null; EditText edtSearch = null; LinearLayout llContainer = null; Button btnOK = null; RelativeLayout rlPBContainer = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = this; setContentView(R.layout.activity_main); rlPBContainer = (RelativeLayout) findViewById(R.id.pbcontainer); edtSearch = (EditText) findViewById(R.id.input_search); llContainer = (LinearLayout) findViewById(R.id.data_container); btnOK = (Button) findViewById(R.id.ok_button); btnOK.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub getSelectedContacts(); } }); edtSearch.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { // When user changed the Text String text = edtSearch.getText().toString() .toLowerCase(Locale.getDefault()); objAdapter.filter(text); } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void afterTextChanged(Editable arg0) { // TODO Auto-generated method stub } }); addContactsInList(); } private void getSelectedContacts() { // TODO Auto-generated method stub StringBuffer sb = new StringBuffer(); for (ContactObject bean : ContactsListClass.phoneList) { if (bean.isSelected()) { sb.append(bean.getName()); sb.append(","); } } String s = sb.toString().trim(); if (TextUtils.isEmpty(s)) { Toast.makeText(context, "Select atleast one Contact", Toast.LENGTH_SHORT).show(); } else { s = s.substring(0, s.length() - 1); Toast.makeText(context, "Selected Contacts : " + s, Toast.LENGTH_SHORT).show(); } } private void addContactsInList() { // TODO Auto-generated method stub Thread thread = new Thread() { @Override public void run() { showPB(); try { Cursor phones = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); try { ContactsListClass.phoneList.clear(); } catch (Exception e) { } while (phones.moveToNext()) { String phoneName = phones .getString(phones .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); String phoneNumber = phones .getString(phones .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); String phoneImage = phones .getString(phones .getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID)); ContactObject cp = new ContactObject(); cp.setName(phoneName); cp.setNumber(phoneNumber); cp.setImage(phoneImage); ContactsListClass.phoneList.add(cp); } phones.close(); lv = new ListView(context); lv.setLayoutParams(new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub llContainer.addView(lv); } }); Collections.sort(ContactsListClass.phoneList, new Comparator<ContactObject>() { @Override public int compare(ContactObject lhs, ContactObject rhs) { return lhs.getName().compareTo( rhs.getName()); } }); objAdapter = new ContactsAdapter(MainActivity.this, ContactsListClass.phoneList); lv.setAdapter(objAdapter); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { CheckBox chk = (CheckBox) view .findViewById(R.id.contactcheck); ContactObject bean = ContactsListClass.phoneList .get(position); if (bean.isSelected()) { bean.setSelected(false); chk.setChecked(false); } else { bean.setSelected(true); chk.setChecked(true); } } }); } catch (Exception e) { e.printStackTrace(); } hidePB(); } }; thread.start(); } void showPB() { runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub rlPBContainer.setVisibility(View.VISIBLE); edtSearch.setVisibility(View.GONE); btnOK.setVisibility(View.GONE); } }); } void hidePB() { runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub rlPBContainer.setVisibility(View.GONE); edtSearch.setVisibility(View.VISIBLE); btnOK.setVisibility(View.VISIBLE); } }); } } 

AndroidManifest.xml

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.multiselectlistexample" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>