I have been making an app that uses a recycler view in a navigation drawer. Why the contents of the recycler view are not showing up. The view is definitely there as I can see the scroll shadows. I am not sure what I have done wrong, as the app does not crash when it is run.
Navigation Drawer Fragment:
public class NavigationDrawerFragment extends android.support.v4.app.Fragment {
public static final String PREF_FILE_NAME = "testPref";
public static final String KEY_USER_LEARNED_DRAWER = "user_learned_drawer";
private RecyclerView mRecyclerView;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private View containerView;
private Boolean mUserLearnedDrawer;
private Boolean mFromSavedInstanceState;
private DrawerAdapter adapter;
public NavigationDrawerFragment() {
mFromSavedInstanceState = false;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUserLearnedDrawer = Boolean.valueOf(readFromPreferences(getActivity(), KEY_USER_LEARNED_DRAWER, "false"));
if (savedInstanceState != null){
mFromSavedInstanceState = true;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
mRecyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
adapter = new DrawerAdapter(getActivity(), getData());
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return layout;
}
public static List<DrawerRow> getData(){
List<DrawerRow> data = new ArrayList<>();
int icons[] = {R.drawable.ic_launcher,R.drawable.ic_launcher,R.drawable.ic_launcher,R.drawable.ic_launcher};
String titles[] = {"Link 1","Link 2","Link 3","Link 4"};
for (int i = 0 ; i < titles.length && i < icons.length; i++){
DrawerRow current = new DrawerRow();
current.iconId = icons[i];
current.title = titles[i];
data.add(current);
}
return data;
}
public void setUp(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
containerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolbar, R.string.drawerOpen, R.string.drawerClosed){
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if(!mUserLearnedDrawer){
mUserLearnedDrawer = true;
saveToPreferences(getActivity(),KEY_USER_LEARNED_DRAWER, mUserLearnedDrawer+"");
}
getActivity().invalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
getActivity().invalidateOptionsMenu();
}
};
if(!mUserLearnedDrawer && !mFromSavedInstanceState){
mDrawerLayout.openDrawer(containerView);
}
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public void saveToPreferences(Context context, String prefName, String prefValue){
SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = sharedPreferences.edit();
mEditor.putString(prefName, prefValue);
mEditor.apply();
}
public static String readFromPreferences(Context context, String prefName, String defaultValue){
SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getString(prefName,defaultValue);
}
}
Adapter:
public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.MyViewHolder>{
private LayoutInflater inflator;
List<DrawerRow> data = Collections.EMPTY_LIST;
public DrawerAdapter(FragmentActivity activity, List<DrawerRow> data) {
inflator = LayoutInflater.from(activity);
this.data = data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = inflator.inflate(R.layout.nav_drawer_row , viewGroup,false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder viewHolder, int i) {
DrawerRow current = data.get(i);
viewHolder.title.setText(current.title);
viewHolder.icon.setImageResource(current.iconId);
}
#Override
public int getItemCount() {
return 0;
}
class MyViewHolder extends RecyclerView.ViewHolder{
ImageView icon;
TextView title;
public MyViewHolder(View itemView) {
super(itemView);
icon = (ImageView) itemView.findViewById(R.id.list_icon);
title = (TextView) itemView.findViewById(R.id.list_text);
}
}
}
Drawer Row:
public class DrawerRow {
int iconId;
String title;
}
Layout:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawerLayout">
<!--Main Content -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text" />
</LinearLayout>
<!--Nav Drawer -->
<fragment
android:layout_width="#dimen/nav_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="uk.co.clickcomputing.hhscweatherstation.NavigationDrawerFragment"
android:id="#+id/fragment_navigation_drawer"/>
</android.support.v4.widget.DrawerLayout>
Drawer Row:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:padding="#dimen/list_padding"
android:id="#+id/list_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="#drawable/ic_launcher"/>
<TextView
android:padding="#dimen/list_padding"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="New Text"
android:id="#+id/list_text" />
</LinearLayout>
Navigation Drawer Fragment Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#eee"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="140dp"
android:layout_marginBottom="8dp"
android:contentDescription="#string/nav_drawer_img_desciption"
android:scaleType="centerCrop"
android:src="#drawable/nav_drawer" />
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/drawerList">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
The issue is that you are returning the item count as 0 which tells that there is no rows to show. You should return the size of the List as shown below.
#Override
public int getItemCount() {
return data.size();
}
Replace following line
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
with
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setAdapter(adapter);
I agree that you need to return the correct item number but I think you might have a problem with setting the recycler view's height to wrap_content as well. I found this link very helpful. Hope it helps.
Make sure RecyclerView parent container width not set as WrapContent
#Override
public int getItemCount() {
return data.size();
}
and layout height in your row is android:layout_height="match_parent" but must be android:layout_height="wrap_content"
Adding app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" to the RelativeLayout solved my problem.
<androidx.recyclerview.widget.RecyclerView
...
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
...
/>
Check for your RecyclerView's width and height attributes, if they are set to wrap content, change it to match parent or constraint your view in some specific area.
Also check for Parent view's width attribute, if it's set to wrap content change it to match parent as well.
I have given static height and match_parent. It works for my Example I haved added it in nested recyclerview.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/new_store_page_phoneNumber_rv"
android:layout_width="match_parent"
android:layout_height="50dp"
android:scrollIndicators="bottom"
android:fadeScrollbars="false"
android:layout_gravity="center_vertical"
app:adapter="#{adapter}"
android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"
android:scrollbarAlwaysDrawHorizontalTrack="true"
android:scrollbars="none"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="horizontal" />
If you are fetching data from the network, make sure you are reloading/refreshing your adapter in the UI thread. This was the solution for me.
The common problem is that you might have forgotten to set your recyclerview with adapter
example in kotlin
adapter= CartAdapter(this)
val linearLayoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
binding.productCartRecycler.layoutManager = linearLayoutManager
binding.productCartRecycler.adapter = adapter
Related
I am not getting any view from the recycler, I did some debug and the constructor of the adapter is called with items on its list, also the method
getItemCount()
but none of the rest seem to be executed.
I´ve been wandering around stack looking for this problem and i found different approaches to a solution, problem is none worked out for me, maybe I am just missing something i can´t see.
I read somewhere that it could be because the recycler view is inside an scroll view, but the solution given did not worked for me
my custom adapter:
public class CircumstancesAdapter extends RecyclerView.Adapter<CircumstancesAdapter.CircumstancesViewHolder> {
List<CatalogRespModel> circumList;
Context mContext;
public CircumstancesAdapter(List<CatalogRespModel> list, Context context) {
this.circumList = list;
this.mContext = context;
}
#Override
public CircumstancesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.row_item_circumstances, parent, false);
return new CircumstancesViewHolder(view);
}
#Override
public void onBindViewHolder(CircumstancesViewHolder holder, int position) {
holder.tvCircum.setText(circumList.get(position).get_Descripcion());
}
#Override
public int getItemCount() {
if(circumList != null) return circumList.size();
else return 0;
}
public class CircumstancesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
RadioButton rbCircum;
TextView tvCircum;
private Context context;
public CircumstancesViewHolder(View itemView) {
super(itemView);
rbCircum = (RadioButton) itemView.findViewById(R.id.rb_circ);
rbCircum.setOnClickListener(this);
tvCircum = (TextView) itemView.findViewById(R.id.tv_circ);
this.context = itemView.getContext();
}
#Override
public void onClick(View v) {
}
}
}
my container layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- TODO: Update blank fragment layout -->
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:id="#+id/text2"
android:text="#string/text_circ"
android:textSize="20sp"
android:textColor="#color/colorPrimaryshadow"/>
<RelativeLayout
android:id="#+id/placa"
android:layout_width="180dp"
android:layout_height="120dp"
android:layout_gravity="center"
android:background="#drawable/placa">
<TextView
android:id="#+id/tv_plate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:layout_centerInParent="true"
android:text="#string/dummy"
android:textSize="40sp"
android:textColor="#android:color/black"/>
</RelativeLayout>
<ImageView
android:id="#+id/iv_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="true"
android:src="#drawable/conductora" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rview_circumstances"
android:layout_width="match_parent"
android:background="#fff"
android:orientation="vertical"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/boton_continuar_circustanciasa"
android:layout_marginTop="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/continuar"
android:layout_marginBottom="10dp"
android:elevation="30dp"
android:layout_gravity="center"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</FrameLayout>
my row layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:background="#fff"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:layout_height="wrap_content">
<RadioButton
android:id="#+id/rb_circ"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:buttonTint="#color/colorAccentDark"
android:gravity="center_vertical"
android:textSize="14sp" />
<TextView
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:id="#+id/tv_circ"
android:textSize="14sp"
android:text="texto de prueba"
android:textColor="#color/colorAccentDark"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
and in my onCreateView inside the fragment:
recyclerView = (RecyclerView) rootView.findViewById(R.id.rview_circumstances);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(true);
if(Catalogs.circumstancesArray.size() > 0){
adapter = new CircumstancesAdapter(Catalogs.circumstancesArray, getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
Note: I checked the List size and is greater than 0
Fragment code as requested:
public class CircumstancesFragment extends Fragment {
Button btnContinue;
TextView tvPlate;
private ImageView ivIndicator;
private static int iNumDevices;
IFragmentListener iFragmentListener;
private RecyclerView recyclerView;
RecyclerView.Adapter adapter;
private final static String TAGMap = CircumstancesFragment.class.getSimpleName();
public static final String TAG = "CircumstancesFragment.java";
public static CircumstancesFragment getInstance(Bundle bundle){
if(bundle != null){
iNumDevices = bundle.getInt("numDevices");
}
return new CircumstancesFragment();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if(context != null){
if(context instanceof IFragmentListener){
iFragmentListener = (IFragmentListener) context;
} else
throw new RuntimeException("el contexto no esta implementando la interfaz");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View rootView = inflater.inflate(R.layout.fragment_circustancias_, container, false);
btnContinue = (Button) rootView.findViewById(R.id.boton_continuar_circustanciasa);
tvPlate = (TextView) rootView.findViewById(R.id.tv_plate);
recyclerView = (RecyclerView) rootView.findViewById(R.id.rview_circumstances);
ivIndicator = (ImageView) rootView.findViewById(R.id.iv_indicator);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(true);
if(Catalogs.circumstancesArray.size() > 0){
adapter = new CircumstancesAdapter(Catalogs.circumstancesArray, getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
btnContinue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
try
{
iFragmentListener.notify(null, TAG);
} catch (Exception ex)
{
Log.d("error", ex.getMessage());
}
}
});
setLayout(iNumDevices);
return rootView;
}
private void setLayout(int i){
tvPlate.setText(FdccoreConstants.insuredArray.get(0).get_Placa_Vehiculo());
if(i== FdccoreConstants.ONE_DEVICE){
ivIndicator.setImageResource(R.drawable.conductora);
}else if(i== FdccoreConstants.TWO_DEVICE){
ivIndicator.setImageResource(R.drawable.only_conductor);
}
}
private void resetView(){
}
}
Please provide more code because Your layout and adapter is working fine.
I only changed Your model list to String.
Maybe in place when You checked list size and list.size() > 0 add
adapter.notifyDataSetChanged();
=====
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rview_circumstances);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(true);
list = new ArrayList<>();
list.add("asd");
list.add("sasf");
list.add("asasfasf");
list.add("asgagsad");
list.add("asgas");
list.add("asagasgd");
list.add("asreyeryd");
list.add("asgsheyd");
CircumstancesAdapter adapter = new CircumstancesAdapter(list, this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
solution: somehow in order to work with the scroll view i must add this line
compile 'com.android.support:recyclerview-v7:25.3.1'
compiling only appcompat-v7 wont work
I am making an app which consists of a navigation drawer and a recycler view inside it. However, the items inside the recycler view are not being displayed. I am not sure what I have been doing wrong. I will provide what I have. If you require anything please ask. Thanks
Adapter
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {
private LayoutInflater inflater;
List<Information> data = Collections.emptyList();
public Adapter(Context context, List<Information> data){
inflater=LayoutInflater.from(context);
this.data=data;
}
public MyViewHolder onCreateViewHolder(ViewGroup parent, int i) {
View view = inflater.inflate(R.layout.custom_row, parent, false);
MyViewHolder holder= new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder viewHolder, int i) {
Information current = data.get(i);
viewHolder.title.setText(current.title);
viewHolder.icon.setImageResource(current.iconId);
}
#Override
public int getItemCount() {
return 0;
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView title;
ImageView icon;
public MyViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.listText);
icon = (ImageView) itemView.findViewById(R.id.listIcon);
}
}
}
Information
public class Information {
int iconId;
String title;
}
NavigationDrawerFragment
public class NavigationDrawerFragment extends Fragment {
private RecyclerView recyclerView;
public static final String PREF_FILE_NAME = "testpref";
public static final String KEY_USER_LEARNED_DRAWER = "user_learned_drawer";
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private boolean mUserLearnedDrawer;
private View containerView;
private Adapter adapter;
private boolean mFromSavedInstanceState;
public NavigationDrawerFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUserLearnedDrawer= Boolean.valueOf(readFrompreferences(getActivity(),KEY_USER_LEARNED_DRAWER,"false"));
if(savedInstanceState!=null)
{
mFromSavedInstanceState=true;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView=(RecyclerView) layout.findViewById(R.id.drawerList);
adapter = new Adapter(getActivity(),getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return layout;
}
public static List<Information> getData(){
List<Information> data = new ArrayList<>();
int[] icons={R.drawable.thechefhat,R.drawable.thegrocerybasket,R.drawable.favouritesstar,R.drawable.supported};
String[] titles = {"Recipes","Ingredients","Favourites","Help"};
for(int i=0;i<titles.length&&i<icons.length;i++){
Information current = new Information();
current.iconId=icons[i];
current.title = titles[i];
data.add(current);
}
return data;
}
public void setUp(int fragmentID, DrawerLayout drawerLayout, final Toolbar toolbar) {
containerView =getActivity().findViewById(fragmentID);
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);
if(!mUserLearnedDrawer){
mUserLearnedDrawer=true;
saveToPreferences(getActivity(), KEY_USER_LEARNED_DRAWER,mUserLearnedDrawer+"");
}
getActivity().invalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
getActivity().invalidateOptionsMenu();
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
if(slideOffset<0.6)
toolbar.setAlpha(1-slideOffset);
}
};
if(!mUserLearnedDrawer&&!mFromSavedInstanceState){
mDrawerLayout.openDrawer(containerView);
}
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public static void saveToPreferences(Context context,String preferenceName, String preferenceValue){
SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_FILE_NAME,Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString(preferenceName,preferenceValue);
editor.apply();
}
public static String readFrompreferences(Context context, String preferenceName, String defaultValue){
SharedPreferences sharedPreferences=context.getSharedPreferences(PREF_FILE_NAME,Context.MODE_PRIVATE);
return sharedPreferences.getString(preferenceName,defaultValue);
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar)findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer,(DrawerLayout)findViewById(R.id.drawer_Layout), toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:padding="8dp"
android:id="#+id/listIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="#drawable/supported"
/>
<TextView
android:id="#+id/listText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dummy Text"
android:padding="8dp"
android:layout_gravity="center_vertical" />
</LinearLayout>
fragment_navigation_drawer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/lightPrimaryColor"
tools:context="com.example.ivan.tutorialapp.NavigationDrawerFragment">
<LinearLayout
android:id="#+id/containerDrawerImage"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="280dp"
android:layout_height="140dp"
android:layout_marginBottom="16dp"
android:src="#drawable/banner" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/drawerList"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:padding="8dp"
android:id="#+id/listIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="#drawable/supported"
/>
<TextView
android:id="#+id/listText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dummy Text"
android:padding="8dp"
android:layout_gravity="center_vertical" />
</LinearLayout>
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:fitsSystemWindows="true"
android:layout_height="match_parent">
<RelativeLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ivan.tutorialapp.MainActivity">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar">
</include>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/app_bar"
android:text="#string/hello_world"
/>
</RelativeLayout>
<fragment
android:id="#+id/fragment_navigation_drawer"
android:name="com.example.ivan.tutorialapp.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">
</fragment>
</android.support.v4.widget.DrawerLayout>
You should change this method to return actual item count
#Override
public int getItemCount() {
return 0;
}
I am learning how to use navigation drawer and navigation tab. I created an app that implement a navigation drawer on MainActivity and each item on navigation drawer will replace fragment on MainActivity to the corresponding fragment.
My first fragment provide two navigation tab using SlidingTabLayout and SlidingTabStrip. The other fragments are just a textview.
If I move from the first item to the second item and then back to first item again, my tab still show two tab, but in fact, I can slide more than two times and the content is not shown.
How do I fix this?
What it should be:
After I move to second drawer and then back to first drawer:
What happened after that:
You can see that I can slide more than twice and the content of fragments are not shown.
MainActivity.java
public class MainActivity extends ActionBarActivity {
String titles[] = {"TabsFragment", "TextFragment"};
Fragment fragment[] = {TabsFragment.newInstance(), TextFragment.newInstance()};
RecyclerView mRecyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
DrawerLayout drawer;
ActionBarDrawerToggle mDrawerToggle;
static View.OnClickListener drawerItemClickListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(true);
mAdapter = new DrawerAdapter(titles);
drawerItemClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
int selectedPos = mRecyclerView.getChildPosition(v);
drawer.closeDrawers();
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_content, fragment[selectedPos])
.commit();
}
};
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this,
drawer,
toolbar,
R.string.open_drawer,
R.string.close_drawer) {
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
supportInvalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
supportInvalidateOptionsMenu();
}
};
drawer.setDrawerListener(mDrawerToggle);
mDrawerToggle.syncState();
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_content, fragment[0])
.commit();
}
}
}
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_layout">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize" />
<FrameLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/toolbar"/>
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ffffff"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.DrawerLayout>
TabsFragment.java
public class TabsFragment extends Fragment {
public static Fragment newInstance() {
TabsFragment fragment = new TabsFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tabs, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewPager mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
mViewPager.setAdapter(new SamplePagerAdapter(getActivity().getSupportFragmentManager(), getActivity().getApplicationContext()));
SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setDistributeEvenly(true);
mSlidingTabLayout.setViewPager(mViewPager);
}
class SamplePagerAdapter extends FragmentPagerAdapter {
private String[] tabTitles = new String[] {"Tab One", "Tab Two"};
private Context context;
public SamplePagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public int getCount() {
return tabTitles.length;
}
#Override
public CharSequence getPageTitle(int position) {
return tabTitles[position];
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
android.support.v4.app.Fragment[] fragment = {TabOneFragment.newInstance(), TabTwoFragment.newInstance()};
return fragment[position];
}
}
}
fragment_tabs.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TabsFragment">
<android.com.drawertab.SlidingTabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/toolbar" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/sliding_tabs" />
</RelativeLayout>
TabsOneFragment.java
public class TabOneFragment extends Fragment{
public static TabOneFragment newInstance() {
TabOneFragment fragment = new TabOneFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab_one, container, false);
}
}
fragment_tabs_one.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:id="#+id/text"
android:text="TAB ONE" />
</LinearLayout>
TabsTwoFragment.java
public class TabTwoFragment extends Fragment {
public static TabTwoFragment newInstance() {
TabTwoFragment fragment = new TabTwoFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_tab_two, container, false);
}
}
fragment_tabs_two.java
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:id="#+id/text"
android:text="TAB TWO" />
</LinearLayout>
TextFragment.java
public class TextFragment extends Fragment {
public static Fragment newInstance() {
TextFragment fragment = new TextFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_text, container, false);
}
}
fragment_text.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:id="#+id/text"
android:text="FRAGMENT TEXT" />
</LinearLayout>
DrawerAdapter.java
public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.ViewHolder> {
private String mNavTitles[];
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public ViewHolder(View itemView,int ViewType) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.rowText);
itemView.setOnClickListener(MainActivity.drawerItemClickListener);
}
}
public DrawerAdapter(String[] titles) {
mNavTitles = titles;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.drawer_item_row, parent, false);
ViewHolder vhItem = new ViewHolder(v, viewType);
return vhItem;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textView.setText(mNavTitles[position]);
}
#Override
public int getItemCount() {
return mNavTitles.length;
}
}
drawer_item_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="12dp"
android:paddingTop="4dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/rowText" />
</LinearLayout>
If you are correct about sliding more times than twice, then you need to set the override method getCount correctly (I realize you know). That's the only issue you need to worry about.
private String[] tabTitles = new String[] {"Tab One", "Tab Two"};
...
#Override
public int getCount() {
return tabTitles.length;
}
Note: I declared tabTitles differently as an array of String "String[]", widely accepted. The other style "tabTitles[]" may not work well with its methods like length.
Looking at your code more closely, I suspect objects TabOneFragment and TabTwoFragment is not working well. Normally override getItem returns the same static Fragment. And of course, I do not see that declaration or code for it.
My suggested try is (from your code):
#Override
public android.support.v4.app.Fragment getItem(int position) {
return TabsFragment.newInstance(position);
}
Note: With the above code, I don't see any use for TabOneFragment and TabTwoFragment, referenced in getItem(int position) in SamplePagerAdapter class. The TextView UI in layout fragment_tab_one.xml is only used for the tab texts. For those texts, the override getPageTitle(int position) can be used and is already coded.
i have a navigation drawer layout created from a NavigationDrawerFragment which extends fragment.I have added android:clickable="true" inside a linear layout in fragment_navigation_drawer as shown below.However i am stuck on how or where to add OnClick event in my NavigationDrawerFragment,or should i do it in another class which extends activity?Thanks in advance.
NavigationDrawerFragment.java:
public class NavigationDrawerFragment extends Fragment {
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private boolean mUserLearnedDrawer;
private boolean mFromSavedInstanceState;
public static final String PREF_FILE_NAME = "testpref";
public static final String KEY_USER_LEARNED_DRAWER = "user_learned_drawer";
private View containerView;
private AdapterClass adapter;
private RecyclerView recyclerView;
public NavigationDrawerFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUserLearnedDrawer = Boolean.valueOf(readFromPreferences(getActivity(), KEY_USER_LEARNED_DRAWER, "false"));
if (savedInstanceState != null) {
mFromSavedInstanceState = true;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
adapter = new AdapterClass(getActivity(), getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return layout;
}
public static List<Information> getData() {
List<Information> data = new ArrayList<>();
int[] icons = {R.drawable.ic_menu_check, R.drawable.ic_menu_check, R.drawable.ic_menu_check, R.drawable.ic_menu_check};
String[] titles = {"Make up", "Lotions", "Deodorants", "Gels"};
for (int i = 0; i < titles.length && i < icons.length; i++) {
Information current = new Information();
current.iconId = icons[i];
current.title = titles[i];
data.add(current);
}
return data;
}
public void setUp(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
containerView = getActivity().findViewById(fragmentId);
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);
if (!mUserLearnedDrawer) {
mUserLearnedDrawer = true;
saveToPreferences(getActivity(), KEY_USER_LEARNED_DRAWER, mUserLearnedDrawer + "");
}
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(containerView);
}
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
public static void saveToPreferences(Context context, String preferenceName, String preferenceValue) {
SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(preferenceName, preferenceValue);
editor.apply();
}
public static String readFromPreferences(Context context, String preferenceName, String defaultValue) {
SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getString(preferenceName, defaultValue);
}
}
fragment_navigation_drawer.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context="com.snappy.stevekamau.snappy.NavigationDrawerFragment">
<LinearLayout
android:id="#+id/containerDrawerImage"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<ImageView
android:layout_width="280dp"
android:layout_height="140dp"
android:background="#000000"
android:src="#drawable/header"></ImageView>
<LinearLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:clickable="true"
android:background="#drawable/linear_layout_clicked" >
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:src="#drawable/basket"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginLeft="0dp"
android:text="My Basket"
android:textStyle="bold"
android:textColor="#color/colorSecondaryText"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="13dp"
android:layout_marginTop="10dp"
android:textStyle="bold"
android:textSize="16dp"
android:text="Categories" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:layout_below="#id/containerDrawerImage"
android:id="#+id/drawerList"
android:layout_marginTop="5dp"
android:background="#ffffff"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
The obvious approach is to explicitly set a View.OnClickListener on the relevant widget (i.e. in onCreateView()):
layout.findViewById(R.id.linear).setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
startActivity(...);
}
});
As far as your question goes:
where to add OnClick event in my NavigationDrawerFragment,or should i do it in another class which extends activity?
The listener really belongs in the class that inflates the layout file. If that's your NavigationDrawerFragment (which appear to be the case), then that's where the listener should live. From there on you can propagate the call elsewhere, but you can start an activity from a fragment just fine.
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>