Android ListView не обновляется фильтром
В моем приложении у меня есть три фрагмента с ViewPager
. один из этих фрагментов у меня есть простой Arraylist
как ListView
из списка контактов телефонов, и я пытаюсь отфильтровать его после ввода в edittext
.
но не обновляется до тех пор, пока softkeyboard
не будет видимым, и мне нужно будет скрыть клавиатуру, чтобы обновить список списков с помощью фильтрованных строк.
Например:
просмотр списка фильтров на "a":
adapter.getFilter().filter("a");
Мой адаптер:
public class AdapterContacts extends BaseAdapter implements Filterable {
private LayoutInflater inflater;
private Context context;
private List<ContactLists> categoryArrayList;
private final ArrayList<ContactLists> originalList = new ArrayList<ContactLists>();
private NameFilter filter;
public AdapterContacts(ArrayList<ContactLists> array) {
categoryArrayList = array;
}
public AdapterContacts(Context context, List<ContactLists> array) {
this.context = context;
inflater = LayoutInflater.from(this.context);
categoryArrayList = array;
originalList.addAll(array);
}
@Override
public int getCount() {
return categoryArrayList.size();
}
@Override
public ContactLists getItem(int position) {
return categoryArrayList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_contacts_list_item, null);
mViewHolder = new ViewHolder(convertView);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (ViewHolder) convertView.getTag();
}
ContactLists item = getItem(position);
mViewHolder.fillItems(this, item, position);
return convertView;
}
private static class UI extends HelperUI {
public TextView tv_person_nickname_mobile_number;
public TextView btn_invite_message;
public ImageView img_contact_image;
public ImageView imgv_user_rank;
public TextView tv_contact_name;
public LinearLayout ll_root;
public UI(View view) {
parseUi(view);
}
}
private class ViewHolder {
private UI UI;
public ViewHolder(View view) {
UI = new UI(view);
}
public void fillItems(final AdapterContacts adapter, final ContactLists item, final int position) {
UI.tv_contact_name.setText(item.getContact_name());
if (item.getStatus() == 1) {
UI.btn_invite_message.setVisibility(View.GONE);
UI.imgv_user_rank.setVisibility(View.VISIBLE);
if (item.getRank() != null || !TextUtils.isEmpty(item.getRank())) {
//Picasso.with(G.context).load(item.getRank()).into(UI.imgv_user_rank);
}
UI.tv_person_nickname_mobile_number.setText(item.getNick_name());
//UI.ll_root.setBackgroundDrawable(G.context.getResources().getDrawable(R.drawable.selector_button_actions));
if (item.getContact_image() == null || TextUtils.isEmpty(item.getContact_image())) {
Bitmap bitmap = UC.getContactPhoto(item.getMobile_number(), G.context.getContentResolver());
if (bitmap != null) {
UI.img_contact_image.setImageBitmap(bitmap);
} else {
UI.img_contact_image.setImageDrawable(G.context.getResources().getDrawable(R.drawable.no_avatar));
}
} else {
// show user avatar from web
//Picasso.with(G.context).load(item.getContact_image()).into(UI.img_contact_image);
UI.img_contact_image.setImageBitmap(BitmapFactory.decodeFile(G.dir_image + "/" + item.getContact_image()));
}
} else {
// UI.ll_root.setBackgroundDrawable(G.context.getResources().getDrawable(R.drawable.selector_invite_actions));
UI.btn_invite_message.setVisibility(View.VISIBLE);
UI.imgv_user_rank.setVisibility(View.GONE);
UI.btn_invite_message.setText(UC.getString(R.string.invite_person));
UI.btn_invite_message.setBackgroundDrawable(G.context.getResources().getDrawable(R.drawable.shape_invite_button_default));
UI.tv_person_nickname_mobile_number.setText(item.getMobile_number());
Bitmap bitmap = UC.getContactPhoto(item.getMobile_number(), G.context.getContentResolver());
if (bitmap != null) {
UI.img_contact_image.setImageBitmap(bitmap);
} else {
UI.img_contact_image.setImageDrawable(G.context.getResources().getDrawable(R.drawable.no_avatar));
}
}
}
}
@Override
public Filter getFilter() {
if (filter == null) {
filter = new NameFilter();
}
return filter;
}
public class NameFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
String searchText = constraint.toString().toLowerCase();
ArrayList<ContactLists> newList = filterListBasedOnSearchText(searchText);
results.values = newList;
results.count = newList.size();
return results;
}
private ArrayList<ContactLists> filterListBasedOnSearchText(String constraint) {
ArrayList<ContactLists> newList = new ArrayList<ContactLists>();
int l = originalList.size();
for (int i = 0; i < l; i++) {
ContactLists nameList = originalList.get(i);
if (nameList.getContact_name().toString().contains(constraint)) {
newList.add(nameList);
}
}
return newList;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
categoryArrayList = (ArrayList<ContactLists>) results.values;
notifyDataSetChanged();
}
}
}
статус софт-клавиатуры в манифесте для ActivityMain
. этот класс имеет пейджер с тремя фрагментами:
<activity android:name=".Activities.ActivityBootstrap" android:windowSoftInputMode="adjustPan" android:screenOrientation="portrait"/>
другой способ сделать Фильтр в фрагменте без возможности адаптера
edt_sample.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
String text = edt_sample.getText().toString();
filter(text);
}
});
public void filter(String charText) {
drinks.clear();
if (charText.length() == 0) {
drinks.addAll(contact_list);
} else {
for (ContactLists wp : contact_list) {
if (wp.getContact_name().contains(charText)) {
drinks.add(wp);
}
}
}
contact_list.clear();
contact_list.addAll(drinks);
adapter.notifyDataSetChanged();
}
ListView успешно фильтруется, когда я закрываю или скрываю программную клавиатуру, обновляемую элементами nw.
Ответы
Ответ 1
Вы не используете свой фильтр адаптера, как я вижу из кода, отправленного вами. Я напишу здесь пример фильтра и как его называть (сохранил все ваши имена переменных, чтобы сделать его проще).
Класс "NameFilter" внутри класса адаптера:
public class NameFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
String searchText = constraint.toString().toLowerCase();
ArrayList<ContactLists> newList = filterListBasedOnSearchText(searchText);
results.values = newList;
results.count = newList.size();
return results;
}
private ArrayList<ContactLists> filterListBasedOnSearchText(String constraint) {
ArrayList<ContactLists> newList = new ArrayList<ContactLists>();
int l = originalList.size();
for (int i = 0; i < l; i++) {
ContactLists nameList = originalList.get(i);
if (nameList.getContact_name().toString().contains(constraint)) {
newList.add(nameList);
}
}
return newList;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
categoryArrayList = (ArrayList<ContactLists>) results.values;
notifyDataSetChanged();
}
}
Реализация метода интерфейса TextWatcher в вашем фрагменте списка:
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void afterTextChanged(Editable s) {
String text = searchView.getText().toString();
NameFilter itemFilter = (NameFilter) adapter.getFilter();
itemFilter.filter(text);
}
Кроме того, некоторые наблюдения:
- Если "ContactLists" - это контакт, назовите его "Контакт", чтобы избежать путаницы.
- Я бы использовал "SearchView" вместо "EditText"
- Я не знаю, как вы получаете список контактов, но есть руководство об этом здесь (если вы не посмотрели на него уже)
Ответ 2
Это очень просто реализовать. Следуйте приведенным ниже инструкциям:
Шаг 1:
Инициализировать Edittext:
editTextVideoFolderSearch = (EditText) rootView.findViewById(R.id.editTextVideoFolderSearch);
Шаг 2:
Добавьте TextChangedListener в этот edittext. как:
editTextVideoFolderSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence t, int start, int before,
int count) {
videoDetailBeansSearch.clear();
for (int i = 0; i < videoDetailBeans_total.size(); i++) {
if (videoDetailBeans_total.get(i).getAlbum().toLowerCase()
.contains(t)) {
videoDetailBeansSearch.add(videoDetailBeans_total.get(i));
}
}
if (videoDetailBeansSearch.size() > 0) {
video_folder_gridView.setAdapter(new AlbumGridAdapter(getActivity(), videoDetailBeansSearch));
} else {
video_folder_gridView.setAdapter(new AlbumGridAdapter(getActivity(), videoDetailBeansSearch));
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
Шаг 3: вам нужно сделать разные beans для заполнения адаптера в виде списка:
private ArrayList<MediaDetailBean> videoDetailBeansSearch = new ArrayList<MediaDetailBean>();
private ArrayList<MediaDetailBean> videoDetailBeans_total = new ArrayList<MediaDetailBean>();
private ArrayList<MediaDetailBean> videoDetailBeans_delete = new ArrayList<MediaDetailBean>();
Шаг 4. Профилируйте список во время загрузки Деятельности или фрагмента:
public class GetVideoAsynctask extends AsyncTask<String, String,Object[]> {
ProgressDialog progressDialog ;
String response = "";
int offset, limit;
public GetVideoAsynctask(int offset1, int limit1) {
offset = offset1;
limit = limit1;
}
@Override
public void onPreExecute() {
progressDialog = ProgressDialog.show(getActivity(),"Loading...", "Please Wait");
}
@Override
public Object[] doInBackground(String... params) {
return AppParsing.getMediaDetails(getActivity(), AppPreferenceUtils.getChildUploadDeviceId(getActivity()),
AppPreferenceUtils.getChildRaId(getActivity()),"2", offset, limit,"3");
//// type=1 for image,2 for video,3 for audio
}
@SuppressWarnings("unchecked")
@Override
public void onPostExecute(Object[] result) {
progressDialog.cancel();
try
{
boolean status = (Boolean) result[0];
response = (String) result[1];
if(status)
{
videoDetailBeans = (ArrayList<MediaDetailBean>) result[2] ;
for (int i = 0; i < videoDetailBeans.size(); i++) {
videoDetailBeans_total.add(videoDetailBeans.get(i));
}
isCheck_video = new boolean[videoDetailBeans_total.size()];
for(int i=0;i<videoDetailBeans_total.size();i++)
{
if(!GRID_DATA.contains(videoDetailBeans_total.get(i).getAlbum()))
{
GRID_DATA.add(videoDetailBeans_total.get(i).getAlbum());
}
}
video_folder_gridView.setAdapter(new AlbumGridAdapter(getActivity(), videoDetailBeans_total));
//Toast.makeText(getActivity(), response, Toast.LENGTH_SHORT).show();
}
else
{
response = (String) result[1];
AppUtils.showDialog(getActivity(), response);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Шаг 5: Установите адаптер списка вида, например:
new GetVideoAsynctask(offset1, limit1).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Шаг 6: Самое важное прореживание - я беру на себя больше просмотра списка здесь:
com.costum.android.widget.LoadMoreListView) video_folder_gridView = (com.costum.android.widget.LoadMoreListView) rootView.findViewById(R.id.video_folder_gridView);
Шаг 7: В моем xml я объявляю следующее:
<com.costum.android.widget.LoadMoreListView
android:id="@+id/video_folder_gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="90dp"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp" />
Не стесняйтесь, если у вас есть какие-либо вопросы относительно этой концепции.
Ответ 3
Это моя реализация фильтра, который фильтрует, когда вы вводите одну букву. Это реализация Activity...
public class MessagesActivity extends Activity{
private ListView msgListView;
private EditText mSearchContent;
private MessagesAdapter msgAdapter;
public static ArrayList<MessagesBean> allMsgsList = new ArrayList<MessagesBean>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messages);
init();
msgAdapter = new MessagesAdapter(getApplicationContext(), allMsgsList, MessagesActivity.this);
msgListView.setAdapter(msgAdapter);
}
private void init() {
// TODO Auto-generated method stub
msgListView = (ListView) findViewById(R.id.messages_list);
msgListView.setOnScrollListener(this);
mSearchContent.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
public void afterTextChanged(Editable s) {
msgAdapter.getFilter().filter(s.toString());
}
});
}
Это реализация адаптера
public class MessagesAdapter extends BaseAdapter implements Filterable {
private Context mcontext;
private ArrayList<MessagesBean> all_details, dup_all_details;
private LayoutInflater inflater;
private DisplayImageOptions options;
private CustomClickLisntener clickLisntener;
private MessagesBean mMessagesBean;
private ViewHolder selectedHolder;
private ListViewFilter listviewFilter;
// int pos = 0;
public MessagesAdapter(Context context, ArrayList<MessagesBean> all_list, CustomClickLisntener lisntener) {
mcontext = context;
all_details = all_list;
clickLisntener = lisntener;
inflater = (LayoutInflater) mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
options = new DisplayImageOptions.Builder().cacheInMemory(true).cacheOnDisk(true).build();
dup_all_details = all_list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return all_details.size();
}
@Override
public MessagesBean getItem(int position) {
// TODO Auto-generated method stub
return all_details.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
static class ViewHolder {
TextView user_name, msg_sub, msg_content, msg_time;
ImageView user_image;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewholder = null;
if (convertView == null) {
viewholder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_item_inbox_msg, null);
viewholder.user_name = (TextView) convertView.findViewById(R.id.user_name);
viewholder.msg_time = (TextView) convertView.findViewById(R.id.msg_time);
viewholder.msg_sub = (TextView) convertView.findViewById(R.id.msg_subject);
viewholder.user_image = (ImageView) convertView.findViewById(R.id.user_image);
viewholder.msg_content = (TextView) convertView.findViewById(R.id.msg_content);
// viewholder.down_arrow.setTag(position);
convertView.setTag(viewholder);
} else {
viewholder = (ViewHolder) convertView.getTag();
}
mMessagesBean = all_details.get(position);
viewholder.user_name.setText(mMessagesBean.getFirstname().trim() + " " + mMessagesBean.getLastname());
viewholder.msg_time.setText(DateDifferent.getDateDifferance(mMessagesBean.getSentDate()));
viewholder.msg_sub.setText(mMessagesBean.getSubject());
viewholder.msg_content.setText(mMessagesBean.getMessage());
ImageLoader.getInstance().displayImage(mMessagesBean.getUserimage(), viewholder.user_image, options);
return convertView;
}
@Override
public Filter getFilter() {
// TODO Auto-generated method stub
if (listviewFilter == null) {
listviewFilter = new ListViewFilter();
}
return listviewFilter;
}
public class ListViewFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// TODO Auto-generated method stub
constraint = constraint.toString();
ArrayList<MessagesBean> allitems = new ArrayList<MessagesBean>();
FilterResults filterresults = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
for (int i = 0; i < dup_all_details.size(); i++) {
if (dup_all_details.get(i).getFirstname().contains(constraint)
|| dup_all_details.get(i).getLastname().contains(constraint)) {
allitems.add(dup_all_details.get(i));
}
}
filterresults.count = allitems.size();
filterresults.values = allitems;
} else {
System.out.println(" iam here..." + all_details.size());
synchronized (this) {
filterresults.count = allitems.size();
filterresults.values = allitems;
}
}
return filterresults;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
// TODO Auto-generated method stub
all_details = (ArrayList<MessagesBean>) results.values;
MessagesActivity.allMsgsList = all_details;
MessagesAdapter.this.notifyDataSetChanged();
}
}
}
Ответ 4
Вы можете сделать это как:
public void filter(String charText) {
drinks.clear();
if (charText.length() == 0) {
drinks.addAll(contact_list);
} else {
for (ContactLists wp : contact_list) {
if (wp.getContact_name().contains(charText)) {
drinks.add(wp);
}
}
}
contact_list.clear();
contact_list.addAll(drinks);
adapter.notifyDataSetChanged(contact_list);
}
и в вашем адаптере:
public void notifyDataSetChanged(List<ContactLists> items){
this.categoryArrayList = items;
super.notifyDataSetChanged();
}