o9s
is a microblog
home archives search feed blogroll


Lists With Section Headers on Android

Sometimes you need section headers. It’s something you get out of the box on iOS. Why not on Android?

I coded a solution to this problem a while ago. I inflated my cells in my list adapter based on the type of the object. If the object was a string, I’d inflate a section header cell. All this code is available below.

Here’s something I never noticed before. Since my section header cells are just regular cells, they have dividers too. They shouldn’t. But they do. I’m looking for a better solution now. I’ll probably try one of the hundreds of Android libraries pertaining to list views.

public class FoodAdapter extends ArrayAdapter<Object> {

    private ArrayList<Fruit> fruits;
    private ArrayList<Vegetable> vegetables;

    public FoodAdapter(Context context) {
        super(context, R.layout.list_header);
    }

    public void setFruits(Fruit[] fruits) {
        this.fruits = new ArrayList<>(Arrays.asList(fruits));
        updateData();
    }

    public void setVegetables(Vegetable[] vegetables) {
        this.vegetables = new ArrayList<>(Arrays.asList(vegetables));
        updateData();
    }

    private void updateData() {
        clear();

        if (fruits != null &amp;&amp; fruits.size() > 0) {
            add("Fruits");
            addAll(fruits);
        }

        if (vegetables != null &amp;&amp; vegetables.size() > 0) {
            add("Vegetables");
            addAll(vegetables);
        }
    }

    @Override
    public int getViewTypeCount() {
        return 3; // Fruit cells, vegetable cells and section headers.
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        Object item = getItem(position);

        if (item instanceof Fruit) {
            Fruit fruit = (Fruit) item;
            FruitCell cell;

            if (view == null || !(view instanceof FruitCell)) {
                LayoutInflater inflater = LayoutInflater.from(getContext());
                cell = (FruitCell) inflater.inflate(R.layout.cell_fruit, parent, false);
            } else {
                cell = (FruitCell) view;
            }

            cell.setContent(fruit);

            return cell;
        } else if (item instanceof Vegetable) {
            Vegetable vegetable = (Vegetable) item;
            VegetableCell cell;

            if (view == null || !(view instanceof VegetableCell)) {
                LayoutInflater inflater = LayoutInflater.from(getContext());
                cell = (VegetableCell) inflater.inflate(R.layout.cell_vegetable, parent, false);
            } else {
                cell = (VegetableCell) view;
            }

            cell.setContent(vegetable);

            return cell;
        } else if (item instanceof String) {
            ListHeader header;

            if (view == null || !(view instanceof ListHeader)) {
                LayoutInflater inflater = LayoutInflater.from(getContext());
                header = (ListHeader) inflater.inflate(R.layout.list_header, parent, false);
            } else {
                header = (ListHeader) view;
            }

            header.setContent((String) item);

            return header;
        }

        return null;
    }

}

This is annoying. I liked how simple this solution is. I still think it’s a good way to go, but only if your lists have no dividers (or if your dividers take the whole width of the screen and are the same color as the background of your section header cells).

Back to the drawing board.

UPDATE: I fixed it by using this library.

Posted on 2018-03-16   #android     #java  






← Next post    ·    Previous post →