【问题标题】:Search bar to ListView return blank values and getFilter errorListView 的搜索栏返回空白值和 getFilter 错误
【发布时间】:2014-07-13 11:39:55
【问题描述】:

我需要在我的应用程序中添加一个搜索栏,但我尝试的所有教程都不起作用。因为我想让这个栏返回我从Excel导入的ListView的值(我应用的是Activity显示人名的方式)。我的 ListView 是从 Excel 导入的,而不是在应用内创建的代码。

也就是说,当我搜索“A”时,会出现所有带有“A”的 ListView 名称,而当我搜索“Arn”时,会出现包含“Arn”的名称(例如 Arnold Clinton)。

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

搜索栏有效,您可以输入吗?但是当我输入值时......它只是不返回任何东西,变成空白。有什么帮助吗?如何让它发挥作用?还是有另一种简单的方法来制作搜索栏? ActionBar 可以吗.. 重要的是它可以工作。

然后我尝试在 CSVAdapter 中应用 getFilter,但是当我尝试将 bar 与此 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 传递给 CSVAdapter() 构造函数。那是对的吗?看起来应该是 textViewResourceId。
  • @PeterQuiring 我不知道,我在GitHub得到这个代码
  • 根据来源未使用。一个虚拟值。对不起。
  • allModelItemsArray 什么时候设置?我认为它是 null 导致 performFiltering() 中的 NPE
  • @PeterQuiring 怎么样?那我能做些什么来解决呢?抱歉,我是一名高中生,对编程不熟悉。

标签: java android eclipse excel listview


【解决方案1】:

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

这会更好,并且是解决此问题的正确方法。

【讨论】:

  • 这段代码有效,停止返回空值​​。但是,它只返回那些定义的名称。如何将我的 Excel 电子表格放回 CSV? (loadArrayFromFile)
  • 好的,编辑显示如何修复 loadArrayFromFile 函数。
  • 抱歉给我带来了麻烦。底线,不要使用 allModelItemsArray,这个数据应该在 CSVAdapter 本身。
  • 不,这也不起作用。我想我第一次是对的。这段代码一团糟……
  • 数据应该何时添加到 CSVAdapter?来自 loadArrayFromFile 或 publishResults() 函数?他们两个都做不到,否则你的数据会重复????
猜你喜欢
  • 2013-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-21
  • 1970-01-01
  • 2011-11-29
相关资源
最近更新 更多