自定义列表视图,带有过滤搜索edittext

时间:2015-05-27 05:29:56

标签: java android listview android-listview android-search

设置自己创建自定义列表视图的挑战,并能够使用编辑框过滤器过滤该列表视图。所有的布局看起来都很好但是当我在查询框中输入时,我得到了一个空对象引用的虚拟方法。

以下是我的代码,我做错了什么。我希望listview根据框中的文本动态更改。

logcat的

05-27 01:20:16.738  10798-10798/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.ak273.chefs, PID: 10798
java.lang.NullPointerException: Attempt to invoke virtual method 'int com.ak273.chefs.listBuilder.getCount()' on a null object reference
        at com.ak273.chefs.searchList.getCount(searchList.java:35)
        at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:806)
        at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:6117)
        at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
        at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
        at com.ak273.chefs.searchList$ItemFilter.publishResults(searchList.java:125)
        at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

mainActivity.java

            final ArrayList<Integer> recipeIDS = recipeID;

            final listBuilder adapterSearch = new listBuilder(getActivity(), recipeImgs, recipeNames, recipeDesc);

            final searchList search = new searchList(getActivity(),adapterSearch);

            listView = (ListView)rootView.findViewById(R.id.list_search);

            listView.setAdapter(search);

            listView.setClickable(true);
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                    int addRecipeID = recipeIDS.get(position);

                    Log.d(YOUR_SEARCH, "CLICKED ON RECIPE: " + addRecipeID);

                    Intent intent = new Intent(parent.getContext(), individual_recipe.class);

                    Bundle bundle = dbHelper.getFullRecipe(addRecipeID);
                    bundle.putInt("recipeID", addRecipeID);
                    intent.putExtras(bundle);

                    startActivity(intent);

                }

            });

            EditText recipeSearch = (EditText)rootView.findViewById(R.id.edit_search);
            recipeSearch.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                    final String ON_TEXT_CHANGED = "ON TEXT CHANGED";

                    Log.d(ON_TEXT_CHANGED, "[ " + s + " ]");

                    search.getFilter().filter(s.toString());

                }

                @Override
                public void afterTextChanged(Editable s) {

                }
            });

listBuilder.java

public class listBuilder extends ArrayAdapter<String> implements Filterable {

String[] recipeNames;
String[] recipeDesc;
ArrayList<Uri> recipeImgs;
Context context;

public listBuilder(Activity context, ArrayList<Uri> recipeImgs, String[] text, String[] recipeDesc){
    super(context, R.layout.list_recipe, text);

    this.recipeNames = text;
    this.recipeDesc = recipeDesc;
    this.recipeImgs = recipeImgs;
    this.context = context;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View single_row = inflater.inflate(R.layout.list_recipe, null, true);

    ImageView imageView = (ImageView)single_row.findViewById(R.id.list_recipePic);

    TextView textView = (TextView)single_row.findViewById(R.id.list_recipeName);
    textView.setText(recipeNames[position]);

    textView = (TextView)single_row.findViewById(R.id.list_recipeDesc);
    textView.setText(recipeDesc[position]);

    imageView.setImageURI(recipeImgs.get(position));

    return single_row;

}

}

searchList.java代码:

searchList.java

public class searchList extends BaseAdapter implements Filterable {

private listBuilder originalList = null;
private listBuilder filteredList = null;
private LayoutInflater layoutInflater;
private int cnt;
private ItemFilter itemFilter = new ItemFilter();

public searchList(Context context, listBuilder data) {
    this.originalList = data;
    this.filteredList = data;
    layoutInflater = LayoutInflater.from(context);
}

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

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

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder holder;

    if (convertView == null) {

        convertView = layoutInflater.inflate(R.layout.list_recipe,null);

        holder = new ViewHolder();
        holder.image = (ImageView)convertView.findViewById(R.id.list_recipePic);
        holder.title = (TextView)convertView.findViewById(R.id.list_recipeName);
        holder.desc = (TextView)convertView.findViewById(R.id.list_recipeDesc);

        convertView.setTag(holder);

    } else {

        holder = (ViewHolder)convertView.getTag();

    }

    holder.image.setImageURI(filteredList.recipeImgs.get(position));
    holder.title.setText(filteredList.recipeNames[position]);
    holder.desc.setText(filteredList.recipeDesc[position]);

    return convertView;
}

static class ViewHolder {
    ImageView image;
    TextView title;
    TextView desc;
}

public Filter getFilter() {
    return itemFilter;
}

private class ItemFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {

        String filterString = constraint.toString().toLowerCase();

        FilterResults results = new FilterResults();

        final String[] list = originalList.recipeNames;

        int count = list.length;

        final ArrayList<String> newList = new ArrayList<String>(count);

        String filterableString;

        for (int i = 0; i < count; i++) {

            filterableString = newList.get(i);

            if (filterableString.toLowerCase().contains(filterString)) {
                newList.add(filterableString);
            }

        }

        results.values = newList;
        results.count = newList.size();

        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        filteredList = (listBuilder)results.values;
        //cnt = results.count;

        notifyDataSetChanged();
    }

}
}

2 个答案:

答案 0 :(得分:0)

在您的searchList(应该是SearchList)中,您必须包含数据所在的结构。

类似于数组或列表。

您正在扩展ArrayAdapter

的类上调用getCount

getCount()应该引用包含数据的结构

答案 1 :(得分:0)

   @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.mainlistview);
            EditText et = (EditText) findViewById(R.id.edittextsearch_lv);
            ListView lv = (ListView) findViewById(R.id.listview);
            final ArrayAdapter adapter = new ArrayAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, listdata);
            lv.setAdapter(adapter);
            et.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    adapter.getFilter().filter(s.toString());

                }

                @Override
                public void afterTextChanged(Editable s) {

                }
            });

    }