将搜索功能添加到ArrayAdapter列表Android

时间:2014-11-07 09:20:27

标签: java android search android-listview

我开发了 Android 应用(最小API 8 ,最高API 20 ),其中列出了 assets文件夹中的所有文件,并使用 ArrayAdapter 将其显示为列表。当用户选择任何项目时,文件将根据项目位置打开并显示在下一个活动中。 我正在尝试向列表添加搜索功能,因此当用户键入搜索查询时,列表会被过滤。我确实尝试将 TextChangedListener 添加到Activity中,但是您知道它有限制,仅适用于单个字(添加空格会使列表空白)。在过去的几天里,我已经检查了stacoverflow中有关此问题的所有问题和答案,但无法解决我的问题。

有没有办法覆盖 getFilter 方法,将搜索功能添加到接受任意数量字词并过滤列表的列表中?

而不是使用TextChangeListener添加 SearchView 来归档此目标?

这是java代码:

import java.io.IOException;
import java.util.ArrayList;
import android.app.ListActivity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class All extends ListActivity implements View.OnClickListener{

    String[] items;
    ListView l;
    EditText etSearch;
    Button btnProgramsList, btnMainMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list);
        btnProgramsList = (Button) findViewById(R.id.btnProgramsList);
        btnMainMenu = (Button) findViewById(R.id.btnMainMenu);
        btnProgramsList.setOnClickListener(this);
        btnMainMenu.setOnClickListener(this);
        getFileList();
        l = getListView();
        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(All.this, android.R.layout.simple_list_item_1, items);
        l.setAdapter(adapter);
        etSearch = (EditText) findViewById(R.id.etSearch);
        etSearch.addTextChangedListener(new TextWatcher() {

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

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }

    private void getFileList() {
        ArrayList<String> filesArrayList = new ArrayList<String>();
        final AssetManager assetManager = getAssets();
        String[] filelist;
        try {
            filelist = assetManager.list("All");
            for(String name: filelist){
                name = name.substring(0, name.length() - 2);
                filesArrayList.add(name);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        items = new String[filesArrayList.size()];
        filesArrayList.toArray(items);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        int p = position;
        Intent i = new Intent(All.this, AllPrograms.class);
        i.putExtra("KEY", p);
        startActivity(i);
    }

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.btnMainMenu){
            Intent i = new Intent(".MainMenu");
            startActivity(i);
        }
        else{
            Intent i = new Intent(".Menu");
            startActivity(i);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

使用搜索视图而不是编辑文本进行搜索,以下是它为我工作的搜索视图示例

Check It Out:-

如果您发现任何相关问题,请告诉我。

答案 1 :(得分:0)

感谢 Sam https://stackoverflow.com/a/13391689/4226207),问题已解决。

我刚刚在我的应用中创建了一个新类 ArrayAdapter.java 并覆盖了 getFilter()方法,只是下面的部分 performFiltering()。然后我删除了

import android.widget.ArrayAdapter;

现在搜索是完美的。这是我在ArrayAdapter类中更改的部分:

@Override
protected FilterResults performFiltering(CharSequence prefix) {
    FilterResults results = new FilterResults();

    if (mOriginalValues == null) {
        synchronized (mLock) {
            mOriginalValues = new ArrayList<T>(mObjects);
        }
    }

    if (prefix == null || prefix.length() == 0) {
        ArrayList<T> list;
        synchronized (mLock) {
            list = new ArrayList<T>(mOriginalValues);
        }
        results.values = list;
        results.count = list.size();
    } else {
        String prefixString = prefix.toString().toLowerCase();

        ArrayList<T> values;
        synchronized (mLock) {
            values = new ArrayList<T>(mOriginalValues);
        }

        final int count = values.size();
        final ArrayList<T> newValues = new ArrayList<T>();

        for (int i = 0; i < count; i++) {
            final T value = values.get(i);
            final String valueText = value.toString().toLowerCase();

            // First match against the whole, non-splitted value
            if (valueText.startsWith(prefixString)) {
                newValues.add(value);
            } else {
                final String[] prefixes = prefixString.split(" ");
                final int prefixCount = prefixes.length;

                    int loc;
                    if(valueText.startsWith(prefixes[0]) || (loc = valueText.indexOf(' ' + prefixes[0])) > -1)
                        loc = valueText.indexOf(prefixes[0]);

                    for (int j = 1; j < prefixCount && loc > -1; j++) 
                        loc = valueText.indexOf(' ' + prefixes[j], loc + 2);

                    if(loc > -1)
                        newValues.add(value);
            }
        }

        results.values = newValues;
        results.count = newValues.size();
     }

    return results;
}