【问题标题】:My custom list filter is not working我的自定义列表过滤器不起作用
【发布时间】:2015-10-08 18:15:15
【问题描述】:

我已经尝试了一些来自 stackOverflow 的代码和许多解决方案,但没有一个对我有用 :(。我不知道为什么会发生这种情况。我已经发布了另一个 question 但我的运气不好,在有人回答之前它被标记为重复只是取决于我的描述。我正在寻找一个很好的解决方案。

这是我的代码

PhoneListAdapter.java

  import java.util.ArrayList;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import com.rupomkhondaker.sonalibank.R;
import com.rupomkhondaker.sonalibank.model.ContactItem;


public class PhoneListAdapter extends BaseAdapter implements Filterable{
    private ArrayList<ContactItem> listData;
    private ArrayList<ContactItem> origData;
    private LayoutInflater layoutInflater;
    private ValueFilter valueFilter;



    public PhoneListAdapter(Activity context, ArrayList<ContactItem> listData) {
        this.listData = listData;
        layoutInflater = LayoutInflater.from(context);
        origData = new ArrayList<>(listData);
    }

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

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

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

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.list_white_text, null);
            holder = new ViewHolder();
            holder.nameView = (TextView) convertView.findViewById(R.id.name_title);
            holder.phoneView = (TextView) convertView.findViewById(R.id.list_sub_phone);
            holder.mobileView = (TextView) convertView.findViewById(R.id.list_sub_mobile);
            holder.emailView = (TextView) convertView.findViewById(R.id.list_sub_email);
            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        ContactItem contactItem = listData.get(position);
        holder.nameView.setText(contactItem.getName());
        holder.phoneView.setText("Ph: " + contactItem.getPhone());
        holder.mobileView.setText("Mob: " + contactItem.getMobile());
        holder.emailView.setText("Email: " + contactItem.getEmail());



        return convertView;
    }

    static class ViewHolder {
        TextView nameView;
        TextView phoneView;
        TextView mobileView;
        TextView emailView;
        }

    // Filter Class
    public Filter getFilter() {
        if(valueFilter==null) {
            valueFilter=new ValueFilter();
        }
        return valueFilter;
    }
    private class ValueFilter extends Filter {

        //Invoked in a worker thread to filter the data according to the constraint.

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            FilterResults results = new FilterResults();
            if (constraint != null && constraint.length() > 0) {
                ArrayList<ContactItem> filterList = new ArrayList<ContactItem>();
                for (int i = 0; i < origData.size(); i++) {
                    final ContactItem contactItem = origData.get(i);
                    if (contactItem.getName().toString().toLowerCase().contains(constraint)) {
                        filterList.add(contactItem);
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
            } else {
                results.count = origData.size();
                results.values = origData;
            }
            return results;
        }

        //Invoked in the UI thread to publish the filtering results in the user interface.
    @Override
    @SuppressWarnings("unchecked")
        protected void publishResults(CharSequence constraint,FilterResults results) {
        origData = (ArrayList<ContactItem>) results.values;
            notifyDataSetChanged();
        }
    }
}

ContactItem.java

import java.io.Serializable;

public class ContactItem implements Serializable {

    private String name;
    private String phone;
    private String mobile;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "[ Name=" + name + ", Phone=" + phone + " , Mobile=" + mobile + ", Email=" + email + "]";
    }
}

GMOFragment.java

import android.app.Fragment;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.rupomkhondaker.sonalibank.adapter.PhoneListAdapter;
import com.rupomkhondaker.sonalibank.model.ContactItem;
import java.util.ArrayList;


public class GMOFragment extends Fragment {
    public GMOFragment(){}

    private static String DB_NAME ="SBLdata.db";// Database name
    private PhoneListAdapter mCustomAdapter;



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_contact, container, false);

        final ListView listView = (ListView) rootView.findViewById(R.id.gmolistView);
        EditText inputSearch =(EditText) rootView.findViewById(R.id.inputSearch);

        final ArrayList<ContactItem> listData = getListData();

        //listView.setAdapter(new PhoneListAdapter(getActivity(), listData));
        listView.setAdapter(mCustomAdapter = new PhoneListAdapter(getActivity(), listData));

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> a, View v, int position, long id) {
                ContactItem contactData = (ContactItem) listView.getItemAtPosition(position);
                Intent intent = new Intent(getActivity(), ContactDetail.class);
                intent.putExtra("DATA_KEY", contactData);
                startActivity(intent);
            }
        });


        inputSearch.addTextChangedListener(new TextWatcher() {
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                // When user changed the Text
                mCustomAdapter.getFilter().filter(cs.toString());
              }

            public void beforeTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
            }

            public void afterTextChanged(Editable cs) {    
            }
        });
        //search


    //Changing Actionbar Title
        getActivity().setTitle("GM Office Contact List");
        return rootView;
    }

    private ArrayList<ContactItem> getListData() {
        ArrayList<ContactItem> listMockData = new ArrayList<ContactItem>();
        DataBaseHelper empClick = new DataBaseHelper(getActivity(), DB_NAME);
        Cursor cursor = empClick.getDetailsofGMO();

        ContactItem newsData = null;

        while (cursor.moveToNext()) {
            newsData = new ContactItem();
            newsData.setName(cursor.getString(0));
            newsData.setPhone(cursor.getString(1));
            newsData.setMobile(cursor.getString(2));
            newsData.setEmail(cursor.getString(3));
            listMockData.add(newsData);
        }
        return listMockData;
    }

}

原木猫

  at android.os.HandlerThread.run(HandlerThread.java:60)
10-11 19:31:21.388    1400-1415/? W/Filter﹕ An exception occured during performFiltering()!
    java.lang.NullPointerException
            at com.rupomkhondaker.sonalibank.adapter.PhoneListAdapter$ValueFilter.performFiltering(PhoneListAdapter.java:97)
            at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:60)
10-11 19:31:21.548    1400-1415/? W/Filter﹕ An exception occured during performFiltering()!
    java.lang.NullPointerException
            at com.rupomkhondaker.sonalibank.adapter.PhoneListAdapter$ValueFilter.performFiltering(PhoneListAdapter.java:97)
            at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:60)
10-11 19:31:21.929    1400-1415/? W/Filter﹕ An exception occured during performFiltering()!
    java.lang.NullPointerException
            at com.rupomkhondaker.sonalibank.adapter.PhoneListAdapter$ValueFilter.performFiltering(PhoneListAdapter.java:97)
            at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:60)
10-11 19:31:22.108    1400-1415/? W/Filter﹕ An exception occured during performFiltering()!
    java.lang.NullPointerException
            at com.rupomkhondaker.sonalibank.adapter.PhoneListAdapter$ValueFilter.performFiltering(PhoneListAdapter.java:97)
            at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:60)
10-11 19:31:37.029    1400-1400/? W/EGL_emulation﹕ eglSurfaceAttrib not implemented
10-11 19:31:37.578    1400-1416/? W/Filter﹕ An exception occured during performFiltering()!
    java.lang.NullPointerException
            at com.rupomkhondaker.sonalibank.adapter.PhoneListAdapter$ValueFilter.performFiltering(PhoneListAdapter.java:97)
            at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)

【问题讨论】:

  • onTextChanged 字段可能有问题
  • 如果不需要编辑文本,你可以使用 searchview,那么我可以帮助我使用 searchView 实现它。!
  • @MFaisalHyder 你能看看我的另一个(问题)[stackoverflow.com/questions/32943680/…
  • 我正在使用自定义 listView 并从我的数据库中获取数据我的另一个问题有完整的详细信息
  • 好吧,给我看看 searchView

标签: android listview filter custom-adapter


【解决方案1】:

根据您发布的代码here

PhoneListAdapter 没有实现 Filterable 。改变

public class PhoneListAdapter extends BaseAdapter {

public class PhoneListAdapter extends BaseAdapter implements Filterable{

在您的 Fragment 中,您永远不会分配 mCustomAdapter。它的值始终为空。

改变

listView.setAdapter(new PhoneListAdapter(getActivity(), listData));

 listView.setAdapter(mCustomAdapter = new PhoneListAdapter(getActivity(), listData));

编辑

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        FilterResults results = new FilterResults();
        if (constraint != null && constraint.length() > 0) {
            ArrayList<ContactItem> filterList = new ArrayList<ContactItem>();
            for (int i = 0; i < listData.size(); i++) {
                final ContactItem contactItem = listData.get(i);
                if (constraint.contains(contactItem.getName())) {
                    filterList.add(contactItem);
                }
            }
            results.count = filterList.size();
            results.values = filterList;
        } else {
            results.count = listData.size();
            results.values = listData;
        }
        return results;
    }

您可能想要保存listData 的副本以恢复搜索

编辑2:

@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,FilterResults results) {
    listData = (ArrayList<ContactItem>) results.values;
    notifyDataSetChanged();

 }

EDIT3

public class PhoneListAdapter extends BaseAdapter implements Filterable{
private ArrayList<ContactItem> listData;
private ArrayList<ContactItem> origData;
private LayoutInflater layoutInflater;
private ValueFilter valueFilter;
private Filter mFilter;


public PhoneListAdapter(Activity context, ArrayList<ContactItem> listData) {
    this.listData = listData;
    layoutInflater = LayoutInflater.from(context);
    origData = new ArrayList<>(listData);
}

performFiltering 中使用origData,而不是listData。这应该足以让您恢复数据集

【讨论】:

  • 添加方法后java.lang.NullPointerException at com.rupomkhondaker.sonalibank.adapter.PhoneListAdapter$ValueFilter.performFiltering(PhoneListAdapter.java:97)
  • mStringFilterList 为空。您的适配器基于 ArrayList。为什么您的过滤器正在处理不同的数据集?
  • 我是 android 的新手 :( 所以你能告诉我它是如何工作的 :( 请拜托
  • 我会试试的。可以发帖ContactItem 吗?
  • 我已经用我所有的代码更新了我上面的问题,请检查:)
【解决方案2】:

从这里查看您的代码How to add filter on my custom list adapter in android app

你声明你的适配器:

private PhoneListAdapter mCustomAdapter;

然后在初始化之前调用它。

@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
    mCustomAdapter.getFilter().filter(arg0);
}

所以你的 onTextChanged 中出现了一个空指针异常。

【讨论】:

  • 是的!但是我上面的当前代码似乎不错,但没有过滤它在第 97 行的我的自定义适配器上说错误 ..在我的 getFilter where for loop start
猜你喜欢
  • 2018-03-17
  • 2017-08-16
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2012-08-19
  • 1970-01-01
  • 2017-07-25
  • 2012-08-22
相关资源
最近更新 更多