简体   繁体   中英

Best way for to sort listview

I have fragment with ListView connected to custom ArrayAdapter. Also on this fragment I have TextView for to sort items by name. Currently it works in next style, when I input any text in this TextView I'm changing sorting order for SQL request, like so: On first positions I'm showing items which contain "entered text" and after that all other items.

Now I'm doing it from my view, by stupid way, I'm every time reselect data from database, with ordering by some specific order field, which = 1 if Name field contain "entered text" and = 0 if not contain.

Can somebody tell me if it's possible to sort ArrayList in this style without reselect data from database?

Here is my solution:

    if (mActualFilter.equals("")) {
      Collections.sort(mProductItems, new Comparator<ProductItem>() {
        @Override
        public int compare(ProductItem o1, ProductItem o2) {
          return o1.getName().compareToIgnoreCase(o2.getName());
        }
      });
    } else {
      Collections.sort(mProductItems, new Comparator<ProductItem>() {
        @Override
        public int compare(ProductItem o1, ProductItem o2) {
          String mName1 = o1.getName();
          String mName2 = o2.getName();

        if ((mName1.toLowerCase().contains(mActualFilter.toLowerCase())) && (!mName2.toLowerCase().contains(mActualFilter.toLowerCase()))) {
          return -1;
        } else if  ((!mName1.toLowerCase().contains(mActualFilter.toLowerCase())) && (mName2.toLowerCase().contains(mActualFilter.toLowerCase()))) {
            return 1;
          } else {
            return 0;
          }
        }
      });
    }

Does the data change according to user's input?

If it changes, then you have no option but to re-select data.

If it doesn't change, you can sort the Array using java.util.Collections.sort(array, comparator) (and you can create custom comparators that sort based on the fields you need)

Example (supposing I have a class with 2 fields):

class MyClass {
    private String someField;
    private int otherField;
    // getters and setters, etc..
}

I can create a comparator that compares someField :

Comparator<MyClass> someFieldComparator = new Comparator<MyClass>() {
    @Override
    public int compare(MyClass m1, MyClass m2) {
        return m1.getSomeField().compareTo(m2.getSomeField());
    }
};

Method compare must return -1 if m1 is "less than" m2 (which means, if m1 must be before m2 when I sort), 1 if m1 is "greater than" m2 ( m1 must be after m2 when I sort), or 0 if they are considered "equal" (it doesn't matter the order of m1 and m2 when I sort). In this case, I used compareTo of String class, because it does this same logic with strings. If I call Collections.sort(list, someFieldComparator) , it will sort according to values of someField .

For otherField , I could create another comparator:

Comparator<MyClass> otherFieldComparator = new Comparator<MyClass>() {
    @Override
    public int compare(MyClass m1, MyClass m2) {
        int v1 = m1.getOtherField();
        int v2 = m2.getOtherField();
        if (v1 < v2) {
            return -1;
        }
        if (v1 > v2) {
            return 1;
        }
        return 0;
    }
};

Note that I used the same logic of returning -1 , 1 or 0 as described above.

So you can create as many comparators as needed and use them accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM