我的自定义列表过滤器不起作用

时间:2015-10-08 18:15:16

标签: android listview filter custom-adapter

我已经尝试了几个代码和很多来自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;
    }

}

Log Cat

  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)

enter image description here

2 个答案:

答案 0 :(得分:1)

根据您发布的代码here

PhoneListAdapter未实施Filterable。改变

public class PhoneListAdapter extends BaseAdapter {

public class PhoneListAdapter extends BaseAdapter implements Filterable{
你的片段中的

你永远不会分配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的副本以还原搜索

EDIT2:

@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。这应该足以让您恢复数据集

答案 1 :(得分:0)

从这里查看您的代码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中得到了一个nullpointer异常。