1

I'm trying to do something that from the beginning I already know it's quite difficult to achieve, and it's to place a footer for a navigation drawer menu at the bottom of the screen.

The fact is that I need the footer to be exactly at the bottom of the screen when the list view items of the drawer are all visible on the screen and the footer should be just below the last item when elements go off the screen and scrollbars appear (normal behaviour).

For that I'm using the addFooterView method in the next way

ViewGroup footer = (ViewGroup)inflater.inflate(R.layout.testme_drawer_footer, mDrawerList, false);

mDrawerList.addFooterView(footer, null, false);

Where testme_drawer_footer is the next layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/footer_menu_facebook"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="start"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/drawer_footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="#8d3169"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:textColor="#fff"
        android:textSize="12sp"/>

</LinearLayout>

Without doing anything the addFooterView just behaves the normal way and if elements are all visible in screen and there is much blank space left at bottom the footer just places below the last element (bad for what I'm trying to achieve).

I've tried many suggestions in different StackOverflow posts with no avail and after struggling my head for a while I was able to get something very close to what I need, and it's the next:

I have given all the list view elements a fixed height and the same for header so in the end I calculate footer height with screenHeight - statusBarHeight - actionBarHeight - drawerHeaderHeight - listViewElementHeight * numberOfElements in the next way:

ViewGroup footer = (ViewGroup)inflater.inflate(R.layout.testme_drawer_footer, mDrawerList, false);

        int screenHeight = GeneralUtils.getScreenHeight(oActivity);
        int statusBarHeight = GeneralUtils.getStatusBarHeight(oActivity);
        int actionBarHeight = GeneralUtils.getActionBarHeight(oActivity);
        int drawerHeaderHeight = GeneralUtils.dp2px(60, oActivity);
        int menuItemHeight = drawerHeaderHeight;
        int totalItemsHeight = menuItemHeight*(endItem-startItem+1);

        int footerHeight = screenHeight - statusBarHeight - actionBarHeight - drawerHeaderHeight - totalItemsHeight;
        footer.setMinimumHeight(footerHeight);

        mDrawerList.setFooterDividersEnabled(true);
        mDrawerList.addFooterView(footer, null, false);

But it's most likely some of the height measurement methods are not being quite exact and there is a difference of some pixels that it's not equal in all tested devices.

I know this is not the best way to do it, in fact I don't like it, I don't like to set a fixed height for drawer header and elements insted of wrap_content and I don't like calculating overall height this way but cannot find any other working way to achieve this.

Any help?

Thanks in advance!

This is the way I set the ListView in all activities:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:id="@+id/llMainMain"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="#ffffff"
                  android:orientation="horizontal">

    //MAIN CONTENT

    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="@dimen/navigation_drawer_width_phone"
        android:layout_height="match_parent"
        android:layout_gravity="left|start"
        android:headerDividersEnabled="true"
        android:background="#ffeeeeee"/>

</android.support.v4.widget.DrawerLayout>
Diego Perez
  • 2,188
  • 2
  • 30
  • 58
  • this might be helpful https://stackoverflow.com/questions/30543605/how-to-add-footer-to-navigationview-android-support-design-library – seon Jun 30 '17 at 09:55
  • Thanks for your reply and time @seon, I've finally solved my problem like I've described below. – Diego Perez Jun 30 '17 at 20:39

1 Answers1

0

After struggling my head for the whole day I've finally found a great and accurate solution and I'll answer my own question in order to help anyone who might be facing the same problem.

The key was to set fixed heights to ListView items (in my case I've set a fixed height of 60dp) and calculate ListView height before it gets drawn with a TreeObserver, then you just multiply fixed item height by number of items and substract this value to ListView height. In my case I had to add header height (also fixed) and item dividers size to the total ListView height, so in the end my piece of code looks like follows:

final int numberOfItems = endItem - startItem + 1;
        final ViewTreeObserver treeObserver = mDrawerList.getViewTreeObserver();
        treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {

    mDrawerList.getViewTreeObserver().removeOnGlobalLayoutListener(this);

                int mDrawerListHeight = mDrawerList.getHeight();
                int dividerHeight = mDrawerList.getDividerHeight() * numberOfItems;
                int footerHeight = calculateFooterHeight(oActivity, mDrawerListHeight, numberOfItems, dividerHeight);

                ViewGroup footer = (ViewGroup)inflater.inflate(R.layout.testme_drawer_footer, mDrawerList, false);
                footer.setMinimumHeight(footerHeight);

                mDrawerList.setFooterDividersEnabled(true);
                mDrawerList.addFooterView(footer, null, false);

                UserSession us = new UserSession(oActivity);
                String footerText = us.getUserSession().getAlias();

                TextView tvDrawerFooter = (TextView) oActivity.findViewById(R.id.drawer_footer);
                tvDrawerFooter.setText(footerText);

                // Set the list's click listener
                DrawerItemClickListener drawer = new DrawerItemClickListener();
                drawer.oActivity = oActivity;
                mDrawerList.setOnItemClickListener(drawer);
            }
        });

private static int calculateFooterHeight(Activity oActivity, int listViewHeight, int numberOfItems, int dividerHeight){

        int drawerHeaderHeight = GeneralUtils.dp2px(60, oActivity);
        int menuItemHeight = drawerHeaderHeight;
        int totalItemsHeight = menuItemHeight * numberOfItems;

        return listViewHeight - drawerHeaderHeight - totalItemsHeight - dividerHeight;
    }

I truly hope I can help anyone else with the same problem.

Diego Perez
  • 2,188
  • 2
  • 30
  • 58