android – Add a header/footer in a listview in xml-ThrowExceptions

Exception or error:

I know how to add a header or a footer in JAVA, but I was wondering if I could add it straight in the XML.
I wouldn’t want to simulate this, but really add it as footer or header!

How to solve:

No, I don’t think that it is possible. Based on ListView source code there are only overScrollHeader/overScrollFooter are available from XML attributes. But these attributes accept only drawables.

If you don’t want to use tricks with layouts above/below ListView. You can extend ListView and implement your own footer and header support in customized View. It is not so hard because of footer and header are already implemented. You only have to add XML attributes parsing in your customized View’s constructor.

###

I was just trying to achieve the same thing (to keep my code cleaner and use XML for markup & source code for logic), but the only solution I found is to define the header view with XML somewhere in your layout and then detach it and put into ListView as header.

For example, having this XML:

<ListView android:id="@+id/myListView">
</ListView>

<LinearLayout android:id="@+id/myHeader">
    ....
</LinearLayout>

You can do this in your code:

ListView myListView = (ListView) findViewById(R.id.myListView);
LinearLayout myHeader = (LinearLayout) findViewById(R.id.myHeader);

// Let's remove the myHeader view from it's current child...
((ViewGroup) myHeader.getParent()).removeView(myHeader);

// ... and put it inside ListView.
myListView.addFooterView(myHeader);

Basically, what we do here is just detach the inflated LinearLayout from its parent and set it as ListView header child.

This is not an ideal solution, but it is still easier than creating/inflating header manually. Also this utilizes the power of XML inflation & view reusing if you’re using this inside some “holder” pattern.

Hope this helps somebody.

###

This is how it worked for me, in my Adapter class which extends the BaseAdapter. I am targeting API 23:

    @Override
    public View getView(int position, View view, ViewGroup parent) {
    if (position == 0) {
        if (view == null) {
            LayoutInflater layoutInflater = LayoutInflater.from(mContext);
            view = layoutInflater.inflate(R.layout.test_results_header, parent, false);
        }
    } else {
        if (view == null) {
            LayoutInflater layoutInflater = LayoutInflater.from(mContext);
            view = layoutInflater.inflate(R.layout.test_result_item, parent, false);
        }
    }

Pretty simple, I inflate a header XML for position 0 and the content XML for the rest. If you know the position where you want a header or any other XML, in your logic you would need to check the position, and inflate the respective XML for that position.

Leave a Reply

Your email address will not be published. Required fields are marked *