Skip to content

Instantly share code, notes, and snippets.

@msama
Last active August 29, 2015 14:15
Show Gist options
  • Save msama/2cbb9778f0e41ff84de0 to your computer and use it in GitHub Desktop.
Save msama/2cbb9778f0e41ff84de0 to your computer and use it in GitHub Desktop.
Android DrawerMenu. A different approach using Enums.

Android DrawerMenu. A different approach using Enums.

This is an example of a drawer menu using enums to define view types and actions.

package com.ahuralab.shakeacocktail.drawer;
/**
* Menu actions used as events identifiers to propagate events.
*
* Created by msama on 14/02/2015.
*/
public enum DrawerAction {
NONE,
COCKTAILS_FILTER_ALL,
COCKTAILS_FILTER_USER_RATED,
// All the other actions
}
package com.ahuralab.shakeacocktail.drawer;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.ahuralab.shakeacocktail.R;
/**
* Instantiate the various items views.
*
* Created by msama on 02/02/2015.
*/
public class DrawerAdapter extends ArrayAdapter<DrawerItem> {
public DrawerAdapter(final Context context) {
super(context, 0);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Delegate view initialization to a sub function.
// Android automatically pass a convertView of the right type
// using getItemViewType(int position)
switch(DrawerItem.Type.values()[getItemViewType(position)]) {
case TOP:
return getTopView(position, convertView, parent);
case HEADER:
return getHeaderView(position, convertView, parent);
case ITEM:
return getItemView(position, convertView, parent);
}
return null;
}
// Delegate method to build the view for Top elements
private View getTopView(int position, View convertView, ViewGroup parent) {
DrawerItem.Top item = (DrawerItem.Top)getItem(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.drawer_top, parent, false);
}
TextView text = (TextView) convertView
.findViewById(R.id.name);
text.setText(item.getName());
text = (TextView) convertView
.findViewById(R.id.email);
text.setText(item.getEmail());
return convertView;
}
// Delegate method to build the view for Header views
private View getHeaderView(int position, View convertView, ViewGroup parent) {
DrawerItem.Header item = (DrawerItem.Header)getItem(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.drawer_list_header, parent, false);
}
TextView text = (TextView) convertView
.findViewById(R.id.title);
text.setText(item.getName());
return convertView;
}
// Delegate method to build the view for Item views
private View getItemView(int position, View convertView, ViewGroup parent) {
DrawerItem.Item item = (DrawerItem.Item)getItem(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.drawer_list_item, parent, false);
}
TextView text = (TextView) convertView
.findViewById(R.id.title);
text.setText(item.getName());
if (item.getIcon() != 0) {
ImageView icon = (ImageView) convertView
.findViewById(R.id.icon);
icon.setImageDrawable(convertView.getResources()
.getDrawable(item.getIcon()));
}
return convertView;
}
/**
* Specifies that not all the items are enabled and forces
* the view to check them one by one.
*
* @return <code>false</code>.
*/
@Override
public boolean areAllItemsEnabled() {
return false;
}
/**
* Specify that only items defined as {link DrawerItem.Type.ITEM}
* are enabled.
*
* @param position the element position being enquired.
* @return <code>true</code> if the element is enabled,
* <code>false</code> otherwise.
*/
@Override
public boolean isEnabled(int position) {
return getItem(position).getItemType() == DrawerItem.Type.ITEM;
}
/**
* Defines how many view types this adapter requires.
*
* @return the number of view types.
*/
@Override
public int getViewTypeCount() {
return DrawerItem.Type.values().length;
}
/**
* Returns a unique identifier for each different view type. This will be used by the
* {link #getView(int, View, ViewGroup)} method
*
* @param position the element position being enquired.
* @return a unique identifier.
*/
@Override
public int getItemViewType(int position) {
return getItem(position).getItemType().ordinal();
}
}
package com.ahuralab.shakeacocktail.drawer;
/**
* Defines the various types of drawer menu elements and provides
* static factory methods.
*
* Created by msama on 02/02/2015.
*/
public abstract class DrawerItem {
public static Top CreateTop(String name, String email) {
return new Top(name, email);
}
public static Header CreateHeader(String name) {
return new Header(name);
}
public static Item CreateItem(String name, DrawerAction action, int icon) {
return new Item(name, action, icon);
}
/**
* Menu type used to help the adapter to distinguish which view to use.
*/
public static enum Type {
TOP,
HEADER,
ITEM
}
private final Type itemType;
private DrawerItem(Type itemType) {
this.itemType = itemType;
}
public Type getItemType() {
return itemType;
}
/**
* Menu top banner showing the user identity.
*/
public static final class Top extends DrawerItem {
private String name;
private String email;
private Top(String name, String email) {
super(Type.TOP);
this.name = name;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
/**
* Menu section header to be used as a title.
*/
public static final class Header extends DrawerItem {
private final String name;
private Header(String name) {
super(Type.HEADER);
this.name = name;
}
public String getName() {
return name;
}
}
/**
* Clickable drawer item which triggers a
* {link com.ahuralab.shakeacocktail.drawer.DrawerAction}.
*/
public static final class Item extends DrawerItem {
private final String name;
private final DrawerAction action;
private final int icon;
private Item(String name, DrawerAction action, int icon) {
super(Type.ITEM);
this.name = name;
this.action = action;
this.icon = icon;
}
public String getName() {
return name;
}
public DrawerAction getAction() {
return action;
}
public int getIcon() {
return icon;
}
}
}
// Pseudo code
public class MyActivity extends Activity {
private ListView mDrawerList;
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
final DrawerAdapter adapter = new DrawerAdapter(this);
adapter.addAll(createDraver());
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
handleDrawerAction(((DrawerItem.Item) adapter.getItem(position)).getAction());
}
});
//...
}
private List<DrawerItem> createDraver() {
List<DrawerItem> drawerItems = new ArrayList<>();
drawerItems.add(DrawerItem.CreateTop(
"Username", "foo@email.org"));
// Menu events
drawerItems.add(DrawerItem.CreateHeader(
getResources().getString(R.string.drawer_header_cocktails)));
drawerItems.add(DrawerItem.CreateItem(
getResources().getString(R.string.drawer_item_filter_cocktails_all),
DrawerAction.COCKTAILS_FILTER_ALL, R.drawable.ic_glass));
drawerItems.add(DrawerItem.CreateItem(
getResources().getString(R.string.drawer_item_filter_user_rated),
DrawerAction.COCKTAILS_FILTER_USER_RATED, R.drawable.ic_star));
// Add other items
return drawerItems;
}
private void handleDrawerAction(DrawerAction action) {
switch(action) {
case COCKTAILS_FILTER_ALL: {
// Handle this case
break;
}
case COCKTAILS_FILTER_USER_RATED: {
// Handle this case
break;
}
// Handle other cases
}
// Close the drawer layout
mDrawerLayout.closeDrawer(Gravity.LEFT);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment