package com.thebluealliance.androidclient.activities; import com.thebluealliance.androidclient.R; import com.thebluealliance.androidclient.TBAAndroid; import com.thebluealliance.androidclient.activities.settings.SettingsActivity; import com.thebluealliance.androidclient.di.components.DaggerMyTbaComponent; import com.thebluealliance.androidclient.di.components.HasMyTbaComponent; import com.thebluealliance.androidclient.di.components.MyTbaComponent; import com.thebluealliance.androidclient.fragments.NavigationDrawerFragment; import com.thebluealliance.androidclient.listitems.NavDrawerItem; import com.thebluealliance.androidclient.views.ScrimInsetsFrameLayout; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.TaskStackBuilder; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AppCompatActivity; import android.view.Gravity; import android.widget.FrameLayout; /** * Activity that provides a navigation drawer. * <p> * This allows for the easy reuse of a single navigation drawer throughout the app. */ public abstract class NavigationDrawerActivity extends AppCompatActivity implements NavigationDrawerFragment.NavigationDrawerListener, HasMyTbaComponent { private static final String IS_DRAWER_OPEN = "is_drawer_open"; protected static final int DRAWER_CLOSE_ANIMATION_DURATION = 600; private NavigationDrawerFragment mNavDrawerFragment; private DrawerLayout mDrawerLayout; private FrameLayout mContentView; private ScrimInsetsFrameLayout mDrawerContainer; private String mActionBarTitle; private boolean mUseActionBarToggle = false; private boolean mEncourageLearning = false; protected Handler handler; /** * Tells the activity whether or not to use the action bar toggle for the navigation drawer. * * @param use True if this activity should use the action bar toggle */ public void useActionBarToggle(boolean use) { mUseActionBarToggle = use; } /** * Tells the activity whether or not to use the action bar toggle for the navigation drawer. * * @param encourage True if this activity should use the action bar toggle */ public void encourageLearning(boolean encourage) { mEncourageLearning = encourage; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.activity_navigation_drawer); mDrawerLayout = (DrawerLayout) findViewById(R.id.nav_drawer_layout); mContentView = (FrameLayout) findViewById(R.id.content); mDrawerLayout.setStatusBarBackground(R.color.primary_dark); mDrawerContainer = (ScrimInsetsFrameLayout) findViewById(R.id.navigation_drawer_fragment_container); handler = new Handler(); } @Override protected void onResume() { super.onResume(); if (mNavDrawerFragment != null) { mNavDrawerFragment.setupNavDrawerHeader(); } } /** * We set up the nav drawer here to give child activities a chance to set the window's Action * Bar if they're using a Toolbar instead of the default Action Bar. */ @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Call this so that subclasses can configure the navigation drawer before it is created onCreateNavigationDrawer(); mNavDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer_fragment); mNavDrawerFragment.setUp(R.id.navigation_drawer_fragment_container, (DrawerLayout) findViewById(R.id.nav_drawer_layout), mEncourageLearning, mUseActionBarToggle); mDrawerContainer.setOnInsetsCallback(insets -> mNavDrawerFragment.onInsetsChanged(insets)); // Restore the state of the navigation drawer on rotation changes if (savedInstanceState != null && savedInstanceState.getBoolean(IS_DRAWER_OPEN, false)) { mDrawerLayout.openDrawer(Gravity.LEFT); } onNavigationDrawerCreated(); } /** * Called before the navigation drawer is created. Subclasses can override this to perform * setup before the navigation drawer is created, such as enabling or disabling it or disabling * the action bar toggle. Subclasses do not have to call through to super. */ public void onCreateNavigationDrawer() { // Default implementation is empty } /** * Called after the notification drawer is created. Allows subclasses to override this and * configure the navigation drawer. */ public void onNavigationDrawerCreated() { // Default implementation is empty } /** * Inflates the specified view into the "content container" of the activity. This allows the * resuse of a single layout containing a navigation drawer and said container across all * instances of this activity. Subclassing activities that call setContentView(...) will have * their requested layout inserted into the content container. * * @param layoutResID id of the view to be inflated into the content container */ @Override public void setContentView(int layoutResID) { mContentView.removeAllViews(); getLayoutInflater().inflate(layoutResID, mContentView); } /** * Provides a default implementation of item click handling that simply opens the specified * mode in a StartActivity that is inserted into the back stack. Children classes can override * this if they want to enable custom handling of click events. If children override this * method, they should <strong>not</strong> call through to this method. * * @param item The item that was clicked */ @Override public void onNavDrawerItemClicked(NavDrawerItem item) { final int id = item.getId(); final Intent intent; switch (id) { case R.id.nav_item_settings: intent = new Intent(NavigationDrawerActivity.this, SettingsActivity.class); break; default: intent = null; break; } // Launch after a short delay to give the drawer time to close. if (intent != null) { handler.postDelayed(() -> startActivity(intent), DRAWER_CLOSE_ANIMATION_DURATION); } /* * We manually add the start activity to the back stack so that we maintain proper * back button functionality and so we get the proper "activity finish" animation. * * Launch after a short delay to give the drawer time to close. */ handler.postDelayed(() -> TaskStackBuilder.create(NavigationDrawerActivity.this).addNextIntent(HomeActivity.newInstance(NavigationDrawerActivity.this, id)).startActivities(), DRAWER_CLOSE_ANIMATION_DURATION); } /** * Allows the navigation drawer to be enabled or disabled. * * @param enabled true if the navigation drawer should be enabled */ public void setNavigationDrawerEnabled(boolean enabled) { if (enabled) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); } else { mDrawerLayout.closeDrawers(); mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); } } /** * Shows the specified item in the navigation drawer with a highlight. * * @param itemId ID of the item to be selected */ public void setNavigationDrawerItemSelected(int itemId) { mNavDrawerFragment.setItemSelected(itemId); } /** * Check if the navigation drawer is visible * * @return true if the drawer is open */ public boolean isDrawerOpen() { return mDrawerLayout.isDrawerOpen(Gravity.LEFT); } /** * Closes the navigation drawer */ public void closeDrawer() { getDrawerLayout().closeDrawer(Gravity.LEFT); } /** * Opens the navigation drawer */ public void openDrawer() { getDrawerLayout().openDrawer(Gravity.LEFT); } /** * Allows access to the DrawerLayout that this activity hosts * * @return the DrawerLayout of this activity */ public DrawerLayout getDrawerLayout() { return mDrawerLayout; } /** * Allows access to the DrawerFragment that this activity hosts * * @return the DrawerFragment of this activity */ public NavigationDrawerFragment getDrawerFragment() { return mNavDrawerFragment; } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(IS_DRAWER_OPEN, isDrawerOpen()); } /** * Sets the title of this activity's action bar. * <p> * If subclassing activities want the title to be automatically handled when the nav drawer is * opened or closed, they should set the action bar title via this method * * @param title The desired title string */ public void setActionBarTitle(String title) { mActionBarTitle = title; if (!isDrawerOpen() && getSupportActionBar() != null) { getSupportActionBar().setTitle(mActionBarTitle); } } public void setActionBarSubtitle(String subtitle) { if (!isDrawerOpen() && getSupportActionBar() != null) { getSupportActionBar().setSubtitle(subtitle); } } /** * Sets the title of this activity's action bar. * <p> * If subclassing activities want the title to be automatically handled when the nav drawer is * opened or closed, they should set the action bar title via this method * * @param resID The desired title string resource */ public void setActionBarTitle(int resID) { mActionBarTitle = getResources().getString(resID); if (!isDrawerOpen()) { getSupportActionBar().setTitle(mActionBarTitle); } } @Override public MyTbaComponent getMyTbaComponent() { TBAAndroid application = (TBAAndroid) getApplication(); return DaggerMyTbaComponent.builder() .tBAAndroidModule(application.getModule()) .accountModule(application.getAccountModule()) .authModule(application.getAuthModule()) .applicationComponent(application.getComponent()) .build(); } }