0

I have developed an Android app (min API 8, max API 20) which lists all files inside the assets folder and shows them as a list using ArrayAdapter. When the user select any item the file will open and display in the next activity according to the item position. I am trying to add a search functionality to the list so when the user type a search query, the list gets filtered. I did try to add TextChangedListener to the Activity but as you know it has limitation which only works with single word (adding space will blank the list). In the last few days I have checked all questions and answers regarding to this problem in the stacoverflow but couldn't solved my problem.

Is there any way to override the getFilter method to add search functionality to the list which accepts any numbers of words and filter the list?

or

Instead of using TextChangeListener adding SearchView to archive this goal?

Here is the java code:

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);
        }
    }
}
Shahryar
  • 11
  • 2

2 Answers2

0

Use Search view instead of edit text to search, here is the example of search view it worked for me

Check It Out:-

if you found any issue regarding this please let me know.

Community
  • 1
  • 1
Dinesh R Rajput
  • 732
  • 8
  • 22
  • Thanks for the reply, I've seen that question but it just made me confuse. I am not using MenuBar and database in my app, all files simply stored inside the assets folder and show to the user using AssetManager. – Shahryar Nov 07 '14 at 09:54
0

Thanks to the Sam (https://stackoverflow.com/a/13391689/4226207), problem solved.

I just created a new class ArrayAdapter.java in my app and override the getFilter() method, just the section below performFiltering(). Then I remove the

import android.widget.ArrayAdapter;

Now the search is perfect. Here is the section that I changed in the ArrayAdapter class:

@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;
}
Community
  • 1
  • 1
Shahryar
  • 11
  • 2