搜索栏到ListView返回空白值和getFilter错误

时间:2014-07-13 11:39:56

标签: java android eclipse excel listview

我需要在我的应用中添加一个搜索栏,但我尝试过的所有教程都无效。因为我希望这个栏能够返回从Excel导入的ListView的值(我以一种活动显示人名的方式应用)。我的ListView是从Excel导入的,而不是在应用内代码中创建的。

也就是说,当我搜索" A" ListView的所有名称都带有" A"当我搜索" Arn"时出现名称包含" Arn" (例如阿诺德克林顿)。

这是TabelaActivity.java的代码:

package com.akzonobel.malote.tabela;

import com.akzonobel.malote.R;
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.ListView;

public class TabelaActivity extends Activity {
    CSVAdapter mAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tabela);

        ListView mList = (ListView)findViewById(R.id.mList);
        mAdapter = new CSVAdapter(this, -1);

        mList.setAdapter(mAdapter);
    }

    }

这是CSVAdapter.java的代码:

package com.akzonobel.malote.tabela;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;


public class CSVAdapter extends ArrayAdapter<State>{
    Context ctx;

    public CSVAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);

        this.ctx = context;

        loadArrayFromFile();    
    }



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

        TextView mView = (TextView)convertView;
        if(null == mView){ 
            mView = new TextView(parent.getContext());
            mView.setTextSize(19);
            mView.setTextColor(Color.WHITE);
        }

        mView.setText(getItem(pos).getName());

        return mView;
    }

    private void loadArrayFromFile(){
        try {
            InputStream is = ctx.getAssets().open("states.csv"); 
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line;

            while ((line = reader.readLine()) != null) {

                State cur = new State();
                cur.setName(line);

                this.add(cur);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}

这是State.java的代码:

package com.akzonobel.malote.tabela;

    public class State {

    private String name;


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


}

我尝试应用此搜索栏:

EditText inputSearch;
inputSearch = (EditText) findViewById(R.id.inputSearch);
inputSearch.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                // When user changed the Text
                TabelaActivity.this.mAdapter.getFilter().filter(cs);  
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                    int arg3) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable arg0) {
                // TODO Auto-generated method stub                          
            }
        });
    }

搜索栏有效,您可以输入吗?但是当我输入值时......它只是没有返回任何内容,变成空白。有帮助吗?如何使它工作?或者还有另一种简单的方法来制作搜索栏吗?动作棒可以......重要的是它有效。

然后我尝试在CSVAdapter中应用getFilter,但是当我尝试使用带有此getFilter的条时,它会单独崩溃并关闭。

这是我应用的代码getFilter

private List<State> allModelItemsArray;
private List<State> filteredModelItemsArray;
private Filter filter;
@Override
    public Filter getFilter() {
        if (filter == null){
          filter  = new ModelFilter();
        }
        return filter;
      }
private class ModelFilter extends Filter
    {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            constraint = constraint.toString().toLowerCase();
            FilterResults result = new FilterResults();
            if(constraint != null && constraint.toString().length() > 0)
            {
                ArrayList<State> filteredItems = new ArrayList<State>();

                for(int i = 0, l = allModelItemsArray.size(); i < l; i++)
                {
                    State m = allModelItemsArray.get(i);
                    if(m.getName().toLowerCase().contains(constraint))
                        filteredItems.add(m);
                }
                result.count = filteredItems.size();
                result.values = filteredItems;
            }
            else
            {
                synchronized(this)
                {
                    result.values = allModelItemsArray;
                    result.count = allModelItemsArray.size();
                }
            }
            return result;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            filteredModelItemsArray = (ArrayList<State>)results.values;
            notifyDataSetChanged();
            clear();
            for(int i = 0, l = filteredModelItemsArray.size(); i < l; i++)
                add(filteredModelItemsArray.get(i));
            notifyDataSetInvalidated();
        }
    }

当这是激活的getFilter时,除了关闭之外,它还会在LogCat中出现以下错误:

07-13 08:32:52.925: W/Filter(30254): An exception occured during performFiltering()!
07-13 08:32:52.925: W/Filter(30254): java.lang.NullPointerException
07-13 08:32:52.925: W/Filter(30254):    at com.akzonobel.malote.tabela.CSVAdapter$ModelFilter.performFiltering(CSVAdapter.java:129)
07-13 08:32:52.925: W/Filter(30254):    at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
07-13 08:32:52.925: W/Filter(30254):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-13 08:32:52.925: W/Filter(30254):    at android.os.Looper.loop(Looper.java:137)
07-13 08:32:52.925: W/Filter(30254):    at android.os.HandlerThread.run(HandlerThread.java:60)
07-13 08:33:14.856: D/AndroidRuntime(30254): Shutting down VM
07-13 08:33:14.856: W/dalvikvm(30254): threadid=1: thread exiting with uncaught exception (group=0x41101930)
07-13 08:33:14.876: E/AndroidRuntime(30254): FATAL EXCEPTION: main
07-13 08:33:14.876: E/AndroidRuntime(30254): java.lang.NullPointerException
07-13 08:33:14.876: E/AndroidRuntime(30254):    at com.akzonobel.malote.tabela.CSVAdapter$ModelFilter.publishResults(CSVAdapter.java:156)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at android.os.Looper.loop(Looper.java:137)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at android.app.ActivityThread.main(ActivityThread.java:5283)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at java.lang.reflect.Method.invokeNative(Native Method)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at java.lang.reflect.Method.invoke(Method.java:511)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
07-13 08:33:14.876: E/AndroidRuntime(30254):    at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

向State类添加构造函数:

public State(String name) {
  this.name = name;
}

不要使用全局allModelItemsArray和filteredItemsArray,摆脱它们。

然后改变你的performFiltering函数:

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {

            constraint = constraint.toString().toLowerCase();
            FilterResults result = new FilterResults();
            if(constraint != null && constraint.toString().length() > 0)
            {
                ArrayList<State> filteredItems = new ArrayList<State>();

                for(int i = 0, l = getCount(); i < l; i++)
                {
                    State m = getItem(i);
                    if(m.getName().toLowerCase().contains(constraint))
                        filteredItems.add(m);
                }
                result.count = filteredItems.size();
                result.values = filteredItems;
            }
            else
            {
                ArrayList<State> allItems = new ArrayList<State>();
                for(int i = 0, l = getCount(); i < l; i++)
                {
                    State m = getItem(i);
                    allItems.add(m);
                }
                synchronized(this)
                {
                    result.values = allItems;
                    result.count = allItems.size();
                }
            }
            return result;
        }

这样可以更好地解决这个问题。