Search code examples
javaandroidandroid-recyclerviewfooterdrawerlayout

Android RecyclerView Fixed Footer


Past few days I've been working on fixed footer for my recyclerview but so far I didn't get the result that I expected. I've already taken a look existing questions but got same result as before.It seems I 'm still missing a point but I can't figure out... Therefore I'm waiting for your suggestions. Thanks! Here is the current view of layout, I want that FOOTER part to be sticky at bottom of recyclerview.

DrawerAdapter.java

public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.DrawerViewHolder> {
// Class for view types.
private class VIEW_TYPES {
    public static final int Header = 0;
    public static final int Normal = 1;
    public static final int Footer = 2;
}

private ArrayList<DrawerItem> drawerMenuList;
private String userProfileName;
private String userProfileMail;
private Drawable userProfilePic;
private OnItemSelecteListener mListener;

public DrawerAdapter(ArrayList<DrawerItem> drawerMenuList, String name, String mail, Drawable profileImage) {
    this.drawerMenuList = drawerMenuList;
    this.userProfileMail = mail;
    this.userProfileName = name;
    this.userProfilePic = profileImage;
}

@Override
public DrawerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view;
    if (viewType == VIEW_TYPES.Header) {
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false);
    } else if (viewType == VIEW_TYPES.Footer) {
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer, parent, false);
    } else {
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
    }
    return new DrawerViewHolder(view, viewType);
}

@Override
public void onBindViewHolder(DrawerViewHolder holder, int position) {
    // If item's position 0 it's a header.
    if (position == 0) {
        holder.headerName.setText(userProfileName);
        holder.headerMail.setText(userProfileMail);
        holder.headerProfile.setImageDrawable(userProfilePic);
    } else if (position == 5) { // If position is 5 then it's footer.
        holder.headerName.setText("FOOTER");
    } else { // it's a menu item.
        holder.title.setText(drawerMenuList.get(position - 1).getTitle());
        holder.icon.setImageResource(drawerMenuList.get(position - 1).getIcon());
    }

}

@Override
public int getItemCount() {
    return drawerMenuList.size() + 1;
}

@Override
public int getItemViewType(int position) {
    if (position == 0) {
        return VIEW_TYPES.Header;
    } else if (position == 5) {
        return VIEW_TYPES.Footer;
    } else {
        return VIEW_TYPES.Normal;
    }
}


class DrawerViewHolder extends RecyclerView.ViewHolder {
    TextView title;
    TextView headerName;
    ImageView icon;
    TextView headerMail;
    ImageView headerProfile;

    public DrawerViewHolder(View itemView, int viewType) {
        super(itemView);

        if (viewType == VIEW_TYPES.Header) {
            headerName = (TextView) itemView.findViewById(R.id.header_name);
            headerMail = (TextView) itemView.findViewById(R.id.header_email);
            headerProfile = (ImageView) itemView.findViewById(R.id.circleView);
        } else if (viewType == VIEW_TYPES.Footer) {
            headerName = (TextView) itemView.findViewById(R.id.textView3);
        } else {
            title = (TextView) itemView.findViewById(R.id.title);
            icon = (ImageView) itemView.findViewById(R.id.icon);
        }
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mListener.onItemSelected(view, getAdapterPosition());
            }
        });

    }
}
// To set click listener.
public interface OnItemSelecteListener {
    void onItemSelected(View v, int position);
}

public void setOnItemClickLister(OnItemSelecteListener mListener) {
    this.mListener = mListener;
}

}

MainActivity.java

                            for (int i = 0; i < navMenuTitles.length; i++) {
                                Log.e("I", String.valueOf(i));
                                mDrawerItemList.add(new DrawerItem(navMenuTitles[i], navMenuIcons.getResourceId(i, -1)));
                            }
                            mDrawerItemList.add(new DrawerItem());

                            mRecyclerView = (RecyclerView) findViewById(R.id.drawerRecyclerView);
                            mDrawerAdapter = new DrawerAdapter(mDrawerItemList, logged_user.name, logged_user.email, draw_userImage);
                            mLinearLayoutManager = new CustomGridLayoutManager(HomeScreenActivity.this){
                                @Override
                                public boolean canScrollVertically() {
                                    return false;
                                }
                            };

                            mRecyclerView.setLayoutManager(mLinearLayoutManager);
                            mRecyclerView.setAdapter(mDrawerAdapter);
                            mDrawerLayout = (DrawerLayout) findViewById(R.id.DrawerLayout);
                            mDrawerToggle = new ActionBarDrawerToggle(HomeScreenActivity.this, mDrawerLayout, mToolbar, R.string.openDrawer, R.string.closeDrawer) {
                                @Override
                                public void onDrawerOpened(View drawerView) {
                                    super.onDrawerOpened(drawerView);
                                    // code here will execute once the drawer is opened( As I dont want anything happened whe drawer is
                                    // open I am not going to put anything here)
                                }

                                @Override
                                public void onDrawerClosed(View drawerView) {
                                    super.onDrawerClosed(drawerView);
                                    // Code here will execute once drawer is closed
                                }
                            }; // Drawer Toggle Object Made
                            mDrawerLayout.addDrawerListener(mDrawerToggle); // Drawer Listener set to the Drawer toggle
                            mDrawerToggle.syncState();               // Finally we set the drawer toggle sync State
                            mDrawerAdapter.setOnItemClickLister(new DrawerAdapter.OnItemSelecteListener() {
                                @Override
                                public void onItemSelected(View v, int position) {
                                    Log.e("CLICK", "You clicked at position: " + position);
                                }
                            });

drawer_layout.xml

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/DrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:elevation="7dp">

<FrameLayout
    android:id="@+id/containerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" />

<android.support.v7.widget.RecyclerView
    android:id="@+id/drawerRecyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentBottom="true"
    android:layout_gravity="left"
    android:background="#ffffff"
    app:reverseLayout="false"
    app:stackFromEnd="false">

</android.support.v7.widget.RecyclerView>

footer.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_alignParentBottom="true"
android:background="#ffffff"
android:layout_alignBottom="@id/drawerRecyclerView"
android:foregroundGravity="bottom">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="false"
        android:layout_alignParentEnd="true"
        android:background="#f16666"
        android:foregroundGravity="bottom"
        android:gravity="center_horizontal|bottom"
        android:paddingTop="@dimen/_15sdp"
        android:paddingBottom="@dimen/_15sdp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text="TEST"
                android:id="@+id/textView3"
                android:layout_gravity="center_horizontal"
                android:layout_alignParentBottom="true"
                android:gravity="center_horizontal|bottom" />
    </LinearLayout>
    </RelativeLayout>

Solution

  • In your drawer_layout.xml put RecyclerView inside a RelativeLayout and set alignParentTop to true. Then remove your footer view from your RecyclerView and put that inside the RelativeLayout below RecyclerView like this:

    <android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/DrawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:elevation="7dp">
    
        <FrameLayout
            android:id="@+id/containerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" />
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <android.support.v7.widget.RecyclerView
               android:id="@+id/drawerRecyclerView"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:layout_alignParentTop="true"
               android:layout_gravity="left"
               android:background="#ffffff"
               app:reverseLayout="false"
               app:stackFromEnd="false" />
    
            <include layout="@layout/footer" />
    
        </RelativeLayout>
    
    </android.support.v4.widget.DrawerLayout>
    

    You could also take a look at NavigationView so you don't have to customize your drawer list. Here is a tutorial on how to use this. It is pretty easy to use and requires less code. You could then take a look at this answer on how to put a footer in NavigationView.