0
votes

I have implemented the Navigation Drawer into my new app. But I cannot get the App name from ActionBar to toggle the Navigation Drawer. However, when I drag the navigation drawer, the ActionBar respond to this action by changing to an arrow.

Here is my code:

services_activity_main.xml

    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/container_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/title_bar_layout"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </LinearLayout>

        <LinearLayout
            android:id="@+id/contents_layout"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="32dp"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp">

        </LinearLayout>

        <LinearLayout
            android:id="@+id/navigation_bar_layout"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </LinearLayout>

    </LinearLayout>

    <FrameLayout
        android:id="@+id/services_navigation_drawer_layout"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start">

    </FrameLayout>

</android.support.v4.widget.DrawerLayout>

services_fragment_navigation_drawer.xml

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/services_navigation_drawer_gridview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:numColumns="auto_fit"
    android:horizontalSpacing="10dp"
    android:verticalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    android:choiceMode="multipleChoice"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:background="#EEE" />

MainActivity.java

public class MainActivity
       extends Activity
       implements BaseControllerFragment.ControllerCallbacks,
                  ServicesNavigationDrawerFragment.NavigationDrawerCallbacks {
    public final static String TAG = "MainActivity";

    LinearLayout titleBarLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.services_activity_main);

        titleBarLayout = (LinearLayout) findViewById(R.id.title_bar_layout);

        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().add(R.id.services_navigation_drawer_layout,
                new ServicesNavigationDrawerFragment(),
                TAG + "." + ServicesNavigationDrawerFragment.TAG).commit();
    }

    @Override
    public void updateTitleBar(View view) {
        titleBarLayout.removeAllViews();
        titleBarLayout.addView(view);
        titleBarLayout.invalidate();
    }

    @Override
    public void onNavigationDrawerItemSelected(int position) {
        switch (position) {
            case 0:
                replaceContainerContents(new BuildLicenseControllerFragment());
                return;
            case 1:
                replaceContainerContents(new BuildLicenseControllerFragment());
                return;
        }
    }

    private void replaceContainerContents(BaseControllerFragment controllerFragment) {
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.contents_layout,
                controllerFragment,
                TAG + "." + controllerFragment.TAG).commit();
    }
}

ServicesNavigationDrawerFragment.java

public class ServicesNavigationDrawerFragment extends Fragment {
    public final static String TAG = "ServicesNavigationDrawerFragment";

    String[] titles = {
            "String 1", // 0
            "String 2" // 1
    };

    int[] images = {
            R.drawable.service_build_license,
            R.drawable.service_build_license
    };

    private final static String STATE_SELECTED_POSITION = "SELECTED_POSITION";
    private final static String PREF_USER_LEARNED_DRAWER = "USER_LEARNED_DRAWER";

    private int selectedPosition = 0;
    private boolean fromSavedInstance;
    private boolean userLearnedDrawer;

    GridView drawerGridView;
    DrawerLayout drawerLayout;
    FrameLayout navigationDrawerLayout;
    ActionBarDrawerToggle drawerToggle;

    private NavigationDrawerCallbacks callbacks;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        userLearnedDrawer = sharedPreferences.getBoolean(PREF_USER_LEARNED_DRAWER, false);

        if(savedInstanceState != null) {
            selectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
            fromSavedInstance = true;
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        drawerGridView = (GridView) inflater.inflate(R.layout.services_fragment_navigation_drawer, container, false);

        drawerGridView.setAdapter(new ServicesAdapter(titles, images));

        drawerGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectItem(position);
            }
        });

        return drawerGridView;
    }

    @Override
    public void onAttach(final Activity activity) {
        super.onAttach(activity);
        try {
            callbacks = (NavigationDrawerCallbacks) activity;
            drawerLayout = (DrawerLayout) activity.findViewById(R.id.activity_services_drawer_layout);
            navigationDrawerLayout = (FrameLayout) activity.findViewById(R.id.services_navigation_drawer_layout);

            drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

            ActionBar actionBar = getActionBar();
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeButtonEnabled(true);

            drawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, R.string.app_name, R.string.app_name) {
                @Override
                public void onDrawerClosed(View drawerView) {
                    super.onDrawerClosed(drawerView);
                    Log.i(TAG, "Drawer Closed!");

                    if (!isAdded()) {
                        return;
                    }

//                    activity.invalidateOptionsMenu();
                }

                @Override
                public void onDrawerOpened(View drawerView) {
                    super.onDrawerOpened(drawerView);
                    Log.i(TAG, "Drawer Opened!");

                    if (!isAdded()) {
                        return;
                    }

                    if( ! userLearnedDrawer) {
                        userLearnedDrawer = true;
                        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
                        sharedPreferences.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
                    }

//                    activity.invalidateOptionsMenu();
                }
            };

            if( ! userLearnedDrawer && ! fromSavedInstance) {
                drawerLayout.openDrawer(navigationDrawerLayout);
            }

            drawerLayout.post(new Runnable() {
                @Override
                public void run() {
                    drawerToggle.syncState();
                }
            });

            drawerLayout.setDrawerListener(drawerToggle);
        } catch(ClassCastException e) {
            throw new ClassCastException(activity.getClass() + " must implements NavigationDrawerCallbacks interface.");
        }
    }

    private ActionBar getActionBar() {
        return getActivity().getActionBar();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(STATE_SELECTED_POSITION, selectedPosition);
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if(drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }

    private void selectItem(int position) {
        selectedPosition = position;

        if(drawerGridView != null) {
            drawerGridView.setItemChecked(position, true);
        }

        if(drawerLayout != null) {
            drawerLayout.closeDrawer(navigationDrawerLayout);
        }

        if(callbacks != null) {
            callbacks.onNavigationDrawerItemSelected(position);
        }
    }

    private class ServicesAdapter extends BaseAdapter {
        public final static String TAG = "ServicesAdapter";
        private Context context;

        private LayoutInflater inflater;

        private String[] titles;
        private int[] images;

        private ServicesAdapter(String[] titles, int[] images) {
            if(titles.length != images.length) {
                throw new RuntimeException("You Must Provide Same Number of Titles and Images.");
            }

            context = getActivity();
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            this.titles = titles;
            this.images = images;
        }

        @Override
        public int getCount() {
            return images.length;
        }

        @Override
        public Object getItem(int position) {
            return titles[position];
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textView = null;

            if(convertView != null) {
                textView = (TextView) convertView;
            } else {
                textView = (TextView) inflater.inflate(R.layout.services_layout_drawer_item, parent, false);
            }

            Log.i(TAG, textView.getCompoundDrawables()[1].getBounds().toString());

            Drawable drawable = context.getResources().getDrawable(images[position]);
            drawable.setBounds(new Rect(0, 0, 128, 128));

            textView.setText(titles[position]);
            textView.setCompoundDrawables(null, drawable, null, null);

            return textView;
        }
    }

    public interface NavigationDrawerCallbacks {
        public void onNavigationDrawerItemSelected(int position);
    }
}
2

2 Answers

0
votes

Make sure you have everything on your drawerToggle like follows

mDrawerToggle = new ActionBarDrawerToggle(
            getActivity(),                    /* host Activity */
            mDrawerLayout,                    /* DrawerLayout object */
            R.drawable.ic_drawer,             /* nav drawer image to replace 'Up' caret */
            R.string.navigation_drawer_open,  /* "open drawer" description for accessibility */
            R.string.navigation_drawer_close  /* "close drawer" description for accessibility */
    ) {
        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
            if (!isAdded()) {
                return;
            }

            getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            if (!isAdded()) {
                return;
            }

            if (!mUserLearnedDrawer) {
                // The user manually opened the drawer; store this flag to prevent auto-showing
                // the navigation drawer automatically in the future.
                mUserLearnedDrawer = true;
                SharedPreferences sp = PreferenceManager
                        .getDefaultSharedPreferences(getActivity());
                sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
            }

            getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }
    };
0
votes

You shouldn't handle your navigation drawer from fragment.

      ActionBar actionBar = getActionBar();
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeButtonEnabled(true);

            drawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, R.string.app_name, R.string.app_name) {
                @Override
                public void onDrawerClosed(View drawerView) {
                    super.onDrawerClosed(drawerView);
                    Log.i(TAG, "Drawer Closed!");

                    if (!isAdded()) {
                        return;
                    }

//                    activity.invalidateOptionsMenu();
                }

                @Override
                public void onDrawerOpened(View drawerView) {
                    super.onDrawerOpened(drawerView);
                    Log.i(TAG, "Drawer Opened!");

                    if (!isAdded()) {
                        return;
                    }

                    if( ! userLearnedDrawer) {
                        userLearnedDrawer = true;
                        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity);
                        sharedPreferences.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
                    }

//                    activity.invalidateOptionsMenu();
                }
            };

            if( ! userLearnedDrawer && ! fromSavedInstance) {
                drawerLayout.openDrawer(navigationDrawerLayout);
            }

            drawerLayout.post(new Runnable() {
                @Override
                public void run() {
                    drawerToggle.syncState();
                }
            });

            drawerLayout.setDrawerListener(drawerToggle);
        } catch(ClassCastException e) {
            throw new ClassCastException(activity.getClass() + " must implements NavigationDrawerCallbacks interface.");
        }
    }

    private ActionBar getActionBar() {
        return getActivity().getActionBar();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(STATE_SELECTED_POSITION, selectedPosition);
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if(drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }a

Shift above code from fragment to your MAinActivity.java