I am trying to implement a toggle button into the Navigation Drawer Project, that Android Studio can automatically generate. In the end I want to have something like this ("Downloaded only"-Button):
Unfortunately I don't understand how to add a toggle button to the ListView of the NavDrawer. I could probably use one of the "Custom NavDrawer Libs" out there but I would like to understand the way Google proposes it with the auto generated example.
Any ideas on how to implement this into the default NavDrawer Project?
I would do something like this: instead of using a listview I would use an RecyclerView. Then I create three different layout definitions for the label with icon, the divider and the label with optional switch. Your RecyclerView Adapter should extend Form RecyclerView.Adapter. For each of those three layouts you should create an own implementation of ViewHolder. Now you have to create several classes for the list items and one superclass for all of them. In your Adapter you have to override the getViewType method. Tomorrow when I'm at work I could post some demo code for you.
Edit:
activity_main.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="de.devhew.navigationdrawerexample.MainActivity">
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.Toolbar.Overflow"
app:theme="@style/AppTheme.Toolbar" />
<FrameLayout
android:id="@+id/main_content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<fragment
android:id="@+id/fragment_navigation_drawer"
android:name="de.devhew.navigationdrawerexample.drawer.NavigationDrawerFragment"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer"
tools:layout="@layout/fragment_navigation_drawer" />
MainActivity.java
public class MainActivity extends ActionBarActivity {
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar_main);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
List<NavDrawerEntry> drawerEntries = new ArrayList<>();
drawerEntries.add(new NavDrawerItemWithIcon("Home", R.drawable.app_generic));
drawerEntries.add(new NavDrawerItemWithIcon("People", R.drawable.app_generic));
drawerEntries.add(new NavDrawerItemWithIcon("Stuff", R.drawable.app_generic));
drawerEntries.add(new NavDrawerDivider());
drawerEntries.add(new NavDrawerItem("Settings"));
drawerEntries.add(new NavDrawerToggle("Wifi only"));
NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.init((android.support.v4.widget.DrawerLayout) findViewById(R.id.drawer_layout),
toolbar, drawerEntries);
}}
NavigationDrawerFragment.java
public class NavigationDrawerFragment extends Fragment {
private View root;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private RecyclerView mRecyclerView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
return root;
}
public void init(DrawerLayout drawerLayout, final Toolbar toolbar, List<NavDrawerEntry> drawerEntries) {
mDrawerLayout = drawerLayout;
mDrawerToggle = new ActionBarDrawerToggle(getActivity(),
drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActivity().invalidateOptionsMenu();
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
getActivity().invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
@Override
public void run() {
mDrawerToggle.syncState();
}
});
mRecyclerView = (RecyclerView) root.findViewById(R.id.nav_list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setHasFixedSize(true);
NavigationDrawerAdapter adapter = new NavigationDrawerAdapter(getActivity(), drawerEntries);
mRecyclerView.setAdapter(adapter);
}}
NavigationDrawerAdapter.java
public class NavigationDrawerAdapter
extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<NavDrawerEntry> data;
private LayoutInflater inflater;
public NavigationDrawerAdapter(Context context, List<NavDrawerEntry> data) {
this.data = data;
this.inflater = LayoutInflater.from(context);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View itemLayoutView;
switch (viewType) {
case 0:
itemLayoutView = inflater.inflate(R.layout.layout_nav_drawer_item_with_icon, viewGroup, false);
ItemWithIconVH holder = new ItemWithIconVH(itemLayoutView);
return holder;
case 1:
itemLayoutView = inflater.inflate(R.layout.layout_nav_drawer_divider, viewGroup, false);
DividerVH dividerViewHolder = new DividerVH(itemLayoutView);
return dividerViewHolder;
case 2:
itemLayoutView = inflater.inflate(R.layout.layout_nav_drawer_item, viewGroup, false);
ItemVH itemViewHolder = new ItemVH(itemLayoutView);
return itemViewHolder;
case 3:
itemLayoutView = inflater.inflate(R.layout.layout_nav_drawer_toggle, viewGroup, false);
ToggleVH toggleViewHolder = new ToggleVH(itemLayoutView);
return toggleViewHolder;
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final NavDrawerEntry item = data.get(position);
if (item instanceof NavDrawerItemWithIcon) {
ItemWithIconVH viewHolder = (ItemWithIconVH) holder;
viewHolder.mTitle.setText(((NavDrawerItemWithIcon) item).getTitle());
viewHolder.mImageView.setImageResource(((NavDrawerItemWithIcon) item).getIconId());
}
if (item instanceof NavDrawerItem) {
ItemVH viewHolder = (ItemVH) holder;
viewHolder.mTitle.setText(((NavDrawerItem) item).getTitle());
}
if (item instanceof NavDrawerToggle) {
ToggleVH viewHolder = (ToggleVH) holder;
viewHolder.mTitle.setText(((NavDrawerToggle) item).getTitle());
viewHolder.mSwitch.setChecked(((NavDrawerToggle) item).isChecked());
}
}
@Override
public int getItemViewType(int position) {
if (data.get(position) instanceof NavDrawerItemWithIcon)
return 0;
if (data.get(position) instanceof NavDrawerDivider)
return 1;
if (data.get(position) instanceof NavDrawerItem)
return 2;
if (data.get(position) instanceof NavDrawerToggle)
return 3;
return -1;
}
@Override
public int getItemCount() {
return data.size();
}
class ItemWithIconVH extends RecyclerView.ViewHolder {
final TextView mTitle;
final ImageView mImageView;
public ItemWithIconVH(View itemView) {
super(itemView);
mTitle = (TextView) itemView.findViewById(R.id.nav_item_title);
mImageView = (ImageView) itemView.findViewById(R.id.nav_item_image);
}
}
class DividerVH extends RecyclerView.ViewHolder {
public DividerVH(View itemView) {
super(itemView);
}
}
class ItemVH extends RecyclerView.ViewHolder {
final TextView mTitle;
public ItemVH(View itemView) {
super(itemView);
mTitle = (TextView) itemView.findViewById(R.id.nav_item_title);
}
}
class ToggleVH extends RecyclerView.ViewHolder {
final TextView mTitle;
final Switch mSwitch;
public ToggleVH(View itemView) {
super(itemView);
mTitle = (TextView) itemView.findViewById(R.id.nav_item_title);
mSwitch = (Switch) itemView.findViewById(R.id.nav_switch);
}
}}
Superclass for all NavDrawer Items:
public class NavDrawerEntry {}
Item without icon:
public class NavDrawerItem extends NavDrawerEntry {
private String title;
public NavDrawerItem(String title) {
this.setTitle(title);
}
public String getTitle() {
return title;
}
private void setTitle(String title) {
this.title = title;
}}
Item with icon:
public class NavDrawerItemWithIcon extends NavDrawerEntry {
private String title;
private int iconId;
public NavDrawerItemWithIcon(String title, int iconId) {
this.setTitle(title);
this.setIconId(iconId);
}
public int getIconId() {
return iconId;
}
private void setIconId(int iconId) {
this.iconId = iconId;
}
public String getTitle() {
return title;
}
private void setTitle(String title) {
this.title = title;
}}
Divider:
public class NavDrawerDivider extends NavDrawerEntry {}
Item with Switch:
public class NavDrawerToggle extends NavDrawerEntry {
private String title;
private boolean checked;
public NavDrawerToggle(String title) {
this.setTitle(title);
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public String getTitle() {
return title;
}
private void setTitle(String title) {
this.title = title;
}}
layout_nav_drawer_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:clickable="true"
android:orientation="horizontal">
<TextView
android:id="@+id/nav_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:fontFamily="sans-serif"
android:textColor="#000"
android:textSize="16sp" /></LinearLayout>
layout_nav_drawer_item_with_icon.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:clickable="true"
android:orientation="horizontal">
<ImageView
android:id="@+id/nav_item_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:src="@drawable/app_generic" />
<TextView
android:id="@+id/nav_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:fontFamily="sans-serif"
android:text="Verbundene Geräte"
android:textColor="#000"
android:textSize="16sp" /></LinearLayout>
layout_nav_drawer_divider.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ddd"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp" /></LinearLayout>
layout_nav_drawer_toggle.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:clickable="true">
<TextView
android:id="@+id/nav_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:fontFamily="sans-serif"
android:text="Verbundene Geräte"
android:textColor="#000"
android:textSize="16sp" />
<Switch
android:id="@+id/nav_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="16dp" /></RelativeLayout>
fragment_navigation_drawer.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="280dp"
android:layout_height="match_parent"
android:background="#eee"
tools:context="de.vacom.hew.materialdemo.NavigationDrawerFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:background="@color/primaryColor"
android:elevation="3dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/nav_app_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="55dp"
android:src="@drawable/app_generic" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="64dp"
android:fontFamily="sans-serif-medium"
android:text="Demo App"
android:textColor="#eee"
android:textSize="18sp" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/nav_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout></FrameLayout>