My custom list filter is not working

♀尐吖头ヾ 提交于 2020-01-06 04:21:46

问题


I have tried several code and many solution from stackOverflow but none was work for me :( . I don't know why this happen. I have posted another question but my bad luck that before anyone answer it marked as duplicate just depend on my description. I am looking for a great solution.

Here is my code

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)


回答1:


Accordingly to the code you posted here

You PhoneListAdapter does not implement Filterable . Change

public class PhoneListAdapter extends BaseAdapter {

to

public class PhoneListAdapter extends BaseAdapter implements Filterable{

in your Fragment you never assign mCustomAdapter. Its value is always null.

Change

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

to

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

EDIT

    @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;
    }

you probably want to save a copy of listData to revert the search

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);
}

In performFiltering use origData, instead of listData. That's should be enough to let you restore your dataset




回答2:


Looking at your code from here How to add filter on my custom list adapter in android app

You declare your adapter:

private PhoneListAdapter mCustomAdapter;

And then call it before you have initialised it.

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

So you are getting a nullpointer exception in your onTextChanged.



来源:https://stackoverflow.com/questions/33023111/my-custom-list-filter-is-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!