Jahir Fiquitiva
Jahir Fiquitiva

Reputation: 1509

How to sort and filter a string-array?

I want to sort a list of items in a string-array and then filter them using a SearchView in the toolbar.

This is the string-array (each item is the name of a png drawable in res folder):

<string-array name="brands">
    <item>facebook</item>
    <item>twitter</item>
    <item>instagram</item>
    <item>android</item>
    <item>blackberry</item>
    <item>samsung</item>
    <item>huawei</item>
    <item>starbucks</item>
    <item>motorola</item>
    <item>nexus</item>
    <item>lg</item>
    <item>beats</item>
    <item>sony</item>
    <item>lenovo</item>
    <item>dell</item>
    <item>hp</item>
</string-array>

In a RecyclerView Adapter, I have set the array and an ArrayList:

private String[] brands;
private ArrayList<Integer> drawables;

And I have a function that adds the id of the drawables from the string-array to the ArrayList so I can later load the drawable by simply writing drawables.get(position); :

private void loadLogo() {
    drawables = new ArrayList<>();

    brands = context.getResources().getStringArray(R.array.brands);

    for (String extra : brands) {
        int res = context.getResources().getIdentifier(extra, "drawable", context.getPackageName());
        if (res != 0) {
            final int brandInt = context.getResources().getIdentifier(extra, "drawable", context.getPackageName());
            if (brandInt != 0)
                drawables.add(brandInt);
        }
    }
}

What I want to know is:

  1. How to sort brands before adding items to drawables.
  2. How to create a filter function to filter brands and make the content change in the RecylerView properly.

I hope someone can help me. Thanks in advance.

Upvotes: 2

Views: 2644

Answers (1)

Jahir Fiquitiva
Jahir Fiquitiva

Reputation: 1509

Here's how I did it.

I created another ArrayList<Integer> and 2 List<Array>, at the end they were the "variables:

private ArrayList<Integer> drawables, mFiltered;
private String[] brands;
private List<String> stringList, mFilteredNames;
int resId;

Then when "starting" the adapter, I sorted the string array this way:

stringList = new ArrayList<String>(Arrays.asList(brands));
Collections.sort(stringList);
loadLogo(stringList);

The new loadLogo void is:

private void loadLogo(List<String> list) {
        drawables = new ArrayList<>();

        for (String extra : list) {
            int res = r.getIdentifier(extra, "drawable", p);
            if (res != 0) {
                final int brandInt = r.getIdentifier(extra, "drawable", p);
                if (brandInt != 0)
                    drawables.add(brandInt);
            }
        }
    }

And this is my filter function:

public synchronized void filter(CharSequence s) {
        if (s == null || s.toString().trim().isEmpty()) {
            if (mFiltered != null) {
                mFiltered = null;
                notifyDataSetChanged();
            }
        } else {
            if (mFiltered != null)
                mFiltered.clear();
            mFiltered = new ArrayList<>();
            mFilteredNames = new ArrayList<String>();
            for (int i = 0; i < stringList.size(); i++) {
                final String name = stringList.get(i);
                if (name.toLowerCase(Locale.getDefault())
                        .startsWith(s.toString().toLowerCase(Locale.getDefault()))) {
                    mFiltered.add(drawables.get(i));
                    mFilteredNames.add(name);
                }
            }
            notifyDataSetChanged();
        }

And in the onBindViewHolder method of the RecyclerView adapter, I wrote this:

if (mFiltered != null) {
            resId = mFiltered.get(position);
            holder.logo.setImageResource(resId);
        } else {
            resId = drawables.get(position);
            holder.logo.setImageResource(resId);
        }

I don't know if it's the right way to do it, but is working for my purpose. If someone has a better answer I will be thankful.

Also, I don't know how useful this could be for other people as it is mostly for a custom purpose, but I hope this helps someone else too.

Upvotes: 2

Related Questions