com.davisosa.structura.activities.base.BaseActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.davisosa.structura.activities.base.BaseActivity.java

Source

package com.davisosa.structura.activities.base;

import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.LayoutRes;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;

import com.davisosa.structura.R;
import com.davisosa.structura.activities.BSTActivity;
import com.davisosa.structura.activities.LLActivity;
import com.davisosa.structura.util.OverviewStyler;
import com.davisosa.structura.util.PrefUtils;
import com.davisosa.structura.util.UIUtils;
import com.mikepenz.aboutlibraries.Libs;

import java.util.ArrayList;
import java.util.List;

/**
 * A base {@link android.app.Activity} that handles common functionality in the app.
 */
public abstract class BaseActivity extends ActionBarActivity
        implements SharedPreferences.OnSharedPreferenceChangeListener {
    /* Symbols for navigation drawer items (indices must correspond to RES_IDS_DRAWER_TITLE).
     * This is a list of all possible items, which are not necessarily present,
     * in the navigation drawer. */
    protected static final int DRAWER_ITEM_LL = 0;
    protected static final int DRAWER_ITEM_BST = 1;
    protected static final int DRAWER_ITEM_SETTINGS = 2;
    protected static final int DRAWER_ITEM_ABOUT = 3;
    protected static final int DRAWER_ITEM_INVALID = -1;
    protected static final int DRAWER_ITEM_SEPARATOR = -2;
    protected static final int DRAWER_ITEM_SEPARATOR_SPECIAL = -3;
    protected static final int DRAWER_ITEM_GONE = -4;

    // Titles for navigation drawer items (indices must correspond to DRAWER_ITEM_*)
    private static final int[] RES_IDS_DRAWER_TITLE = new int[] { R.string.title_linked_list, R.string.title_bst,
            R.string.title_settings, R.string.title_about };

    // Icons for navigation drawer items (indices must correspond to RES_IDS_DRAWER_TITLE)
    private static final int[] RES_IDS_DRAWER_ICON = new int[] { 0, // Section 1
            0, // Section 2
            R.drawable.ic_settings, R.drawable.ic_about };

    // Delay to launch navigation drawer item, to allow close animation to play
    private static final int DRAWER_LAUNCH_DELAY = 250;

    // Navigation drawer
    private DrawerLayout mDrawerLayout;

    private ViewGroup mDrawerItemsListContainer;

    /**
     * Helper component that ties the action bar to the navigation drawer.
     */
    private ActionBarDrawerToggleWrapper mDrawerToggle;

    private Handler mHandler;

    // List of navigation drawer items that were actually added to the drawer, in order
    private List<Integer> mDrawerItems = new ArrayList<>();

    // Views that correspond to each navigation drawer item; default null
    private View[] mDrawerItemViews = null;

    // Primary toolbar and drawer toggle
    private Toolbar mActionBarToolbar;

    private int mThemedStatusBarColor;
    private int mNormalStatusBarColor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        OverviewStyler.styleOverviewEntry(this);
        PrefUtils.registerOnSharedPreferenceChangeListener(this, this);

        mHandler = new Handler();
        mThemedStatusBarColor = getResources().getColor(R.color.theme_primary_dark);
        mNormalStatusBarColor = mThemedStatusBarColor;
    }

    protected boolean isDrawerOpen() {
        return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(Gravity.START);
    }

    protected void closeDrawer() {
        if (mDrawerLayout != null) {
            mDrawerLayout.closeDrawer(Gravity.START);
        }
    }

    /**
     * Populates the navigation drawer with the appropriate items.
     */
    private void populateDrawer() {
        mDrawerItems.clear();

        mDrawerItems.add(DRAWER_ITEM_LL);
        mDrawerItems.add(DRAWER_ITEM_BST);

        mDrawerItems.add(DRAWER_ITEM_SEPARATOR_SPECIAL);
        mDrawerItems.add(DRAWER_ITEM_SETTINGS);
        mDrawerItems.add(DRAWER_ITEM_ABOUT);

        createDrawerItems();
    }

    @Override
    public void onBackPressed() {
        if (isDrawerOpen()) {
            closeDrawer();
        } else {
            super.onBackPressed();
        }
    }

    private void createDrawerItems() {
        mDrawerItemsListContainer = (ViewGroup) findViewById(R.id.drawer_items_list);
        if (mDrawerItemsListContainer == null) {
            return;
        }

        mDrawerItemViews = new View[mDrawerItems.size()];
        mDrawerItemsListContainer.removeAllViews();

        int i = 0;
        for (int itemId : mDrawerItems) {
            mDrawerItemViews[i] = createDrawerItem(itemId, mDrawerItemsListContainer);
            mDrawerItemsListContainer.addView(mDrawerItemViews[i]);
            i++;
        }
    }

    /**
     * Sets the given navigation drawer item's appearance to the selected state.
     *
     * @param itemId selected navigation drawer item
     */
    private void setSelectedDrawerItem(int itemId) {
        if (mDrawerItemViews != null) {
            int numItems = mDrawerItems.size();
            for (int i = 0; i < mDrawerItemViews.length && i < numItems; i++) {
                int thisItemId = mDrawerItems.get(i);
                formatDrawerItem(mDrawerItemViews[i], thisItemId, itemId == thisItemId);
            }
        }
    }

    /**
     * Returns the navigation drawer item that corresponds to this {@link android.app.Activity}.
     * <br>
     * Subclasses of {@link com.davisosa.structura.activities.base.BaseActivity} override
     * this to indicate what navigation drawer item corresponds to them.
     *
     * @return {@code DRAWER_ITEM_INVALID} to mean that this {@link android.app.Activity} should
     * not have a navigation drawer.
     */
    protected int getSelfDrawerItem() {
        return DRAWER_ITEM_INVALID;
    }

    /**
     * Sets up the navigation drawer as appropriate.
     */
    private void setupNavigationDrawer() {
        // Selected navigation drawer item
        int selfItem = getSelfDrawerItem();

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (mDrawerLayout == null) {
            return;
        }
        mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.theme_primary_dark));
        ScrollView drawer = (ScrollView) mDrawerLayout.findViewById(R.id.drawer);
        if (selfItem == DRAWER_ITEM_INVALID) {
            // Don't show a navigation drawer.
            if (drawer != null) {
                ((ViewGroup) drawer.getParent()).removeView(drawer);
            }
            mDrawerLayout = null;
            return;
        }

        /* ActionBarDrawerToggle ties together the the proper interactions
         * between the navigation drawer and the action bar app icon. */
        mDrawerToggle = setupDrawerToggle(mActionBarToolbar, mDrawerLayout, new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerClosed(View drawerView) {
                invalidateOptionsMenu(); // Calls onPrepareOptionsMenu()
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                invalidateOptionsMenu(); // Calls onPrepareOptionsMenu()
            }

            @Override
            public void onDrawerStateChanged(int newState) {
            }

            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
            }
        });

        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START);

        // Populate the navigation drawer with the correct items.
        populateDrawer();

        mDrawerToggle.syncState();

        // First run of the app starts with the navigation drawer open.
        if (!PrefUtils.isWelcomeDone(this)) {
            PrefUtils.markWelcomeDone(this);
            mDrawerLayout.openDrawer(Gravity.START);
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (mDrawerToggle != null) {
            mDrawerToggle.onConfigurationChanged(newConfig);
        }
    }

    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        super.setContentView(layoutResID);
        getActionBarToolbar();
    }

    public void onDrawerItemClicked(final int itemId) {
        if (itemId == getSelfDrawerItem()) {
            mDrawerLayout.closeDrawer(Gravity.START);
            return;
        }

        if (isSpecialItem(itemId)) {
            goToDrawerItem(itemId);
        } else {
            // Launch the target activity after a short delay, to allow the close animation to play.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    goToDrawerItem(itemId);
                }
            }, DRAWER_LAUNCH_DELAY);

            // Change the active item on the list so the user can see the item changed.
            setSelectedDrawerItem(itemId);
        }

        mDrawerLayout.closeDrawer(Gravity.START);
    }

    protected ActionBarDrawerToggleWrapper setupDrawerToggle(Toolbar toolbar, DrawerLayout drawerLayout,
            final DrawerLayout.DrawerListener drawerListener) {
        ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
                drawerLayout, /* DrawerLayout object */
                toolbar, /* action bar Toolbar */
                R.string.drawer_open, /* "open drawer" description for accessibility */
                R.string.drawer_close /* "close drawer" description for accessibility */
        ) {
            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
                drawerListener.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                drawerListener.onDrawerOpened(drawerView);
            }

            @Override
            public void onDrawerStateChanged(int newState) {
                super.onDrawerStateChanged(newState);
                drawerListener.onDrawerStateChanged(newState);
            }

            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
                super.onDrawerSlide(drawerView, slideOffset);
                drawerListener.onDrawerSlide(drawerView, slideOffset);
            }
        };

        drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mDrawerLayout.openDrawer(Gravity.START);
            }
        });

        drawerLayout.setDrawerListener(drawerToggle);
        return new ActionBarDrawerToggleWrapper(drawerToggle);
    }

    private boolean isSpecialItem(int itemId) {
        return itemId == DRAWER_ITEM_SETTINGS || itemId == DRAWER_ITEM_ABOUT;
    }

    /**
     * Navigates to selected drawer item.
     *
     * @param item selected navigation drawer item
     */
    public void goToDrawerItem(int item) {
        switch (item) {
        case DRAWER_ITEM_LL:
            UIUtils.startActivityWithTransition(this, new Intent(this, LLActivity.class));
            finish();
            break;
        case DRAWER_ITEM_BST:
            UIUtils.startActivityWithTransition(this, new Intent(this, BSTActivity.class));
            finish();
            break;
        case DRAWER_ITEM_SETTINGS:
            // TODO: startActivity
            break;
        case DRAWER_ITEM_ABOUT:
            new Libs.Builder().withFields(R.string.class.getFields())
                    .withLibraries("materialdesignicons", "mdiexpanded", "slidingtabs", "materialdialogs",
                            "snackbar")
                    .withExcludedLibraries("materialicons").withLicenseShown(true).withVersionShown(false)
                    .withActivityTitle(getResources().getString(R.string.title_about))
                    .withActivityTheme(R.style.Theme_Structura_LibsActivity).start(this);
            break;
        }
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        setupNavigationDrawer();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        switch (id) {
        case R.id.action_settings:
            // TODO
            break;
        case R.id.action_example:
            // TODO
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    protected Toolbar getActionBarToolbar() {
        if (mActionBarToolbar == null) {
            mActionBarToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
            if (mActionBarToolbar != null) {
                setSupportActionBar(mActionBarToolbar);
            }
        }
        return mActionBarToolbar;
    }

    private View createDrawerItem(final int itemId, ViewGroup container) {
        boolean selected = getSelfDrawerItem() == itemId;

        int layout;
        if (itemId == DRAWER_ITEM_SEPARATOR) {
            layout = R.layout.drawer_separator;
        } else if (itemId == DRAWER_ITEM_SEPARATOR_SPECIAL) {
            layout = R.layout.drawer_separator;
        } else {
            layout = R.layout.drawer_item;
        }
        View view = getLayoutInflater().inflate(layout, container, false);

        if (isSeparator(itemId)) {
            // We're done.
            UIUtils.setAccessibilityIgnore(view);
            return view;
        }

        ImageView iconView = (ImageView) view.findViewById(R.id.icon);
        TextView titleView = (TextView) view.findViewById(R.id.title);
        int iconId = itemId >= 0 && itemId < RES_IDS_DRAWER_ICON.length ? RES_IDS_DRAWER_ICON[itemId] : 0;
        int titleId = itemId >= 0 && itemId < RES_IDS_DRAWER_TITLE.length ? RES_IDS_DRAWER_TITLE[itemId] : 0;

        // Set icon and text.
        if (iconId > 0) {
            iconView.setVisibility(View.VISIBLE);
            iconView.setImageResource(iconId);
        } else {
            iconView.setVisibility(View.INVISIBLE);
        }
        titleView.setText(getString(titleId));

        formatDrawerItem(view, itemId, selected);

        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onDrawerItemClicked(itemId);
            }
        });

        return view;
    }

    private boolean isSeparator(int itemId) {
        return itemId == DRAWER_ITEM_SEPARATOR || itemId == DRAWER_ITEM_SEPARATOR_SPECIAL;
    }

    private void formatDrawerItem(View view, int itemId, boolean selected) {
        if (isSeparator(itemId)) {
            return; // N/A
        }

        ImageView iconView = (ImageView) view.findViewById(R.id.icon);
        TextView titleView = (TextView) view.findViewById(R.id.title);

        if (selected) {
            view.setBackgroundResource(R.drawable.drawer_item_bg_selected);
        }

        // Configure its appearance according to whether or not it's selected.
        Resources res = getResources();
        titleView.setTextColor(selected ? res.getColor(R.color.drawer_text_color_selected)
                : res.getColor(R.color.drawer_text_color));
        iconView.setColorFilter(
                selected ? res.getColor(R.color.drawer_icon_tint_selected) : res.getColor(R.color.drawer_icon_tint),
                PorterDuff.Mode.SRC_IN);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        PrefUtils.unregisterOnSharedPreferenceChangeListener(this, this);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    }

    public int getThemedStatusBarColor() {
        return mThemedStatusBarColor;
    }

    public void setNormalStatusBarColor(int color) {
        mNormalStatusBarColor = color;
        if (mDrawerLayout != null) {
            mDrawerLayout.setStatusBarBackgroundColor(mNormalStatusBarColor);
        }
    }

    public class ActionBarDrawerToggleWrapper {
        private ActionBarDrawerToggle mDrawerToggle;

        public ActionBarDrawerToggleWrapper(ActionBarDrawerToggle drawerToggle) {
            mDrawerToggle = drawerToggle;
        }

        public void syncState() {
            if (mDrawerToggle != null) {
                mDrawerToggle.syncState();
            }
        }

        public void onConfigurationChanged(Configuration newConfig) {
            // Forward the new configuration to the drawer toggle component.
            if (mDrawerToggle != null) {
                mDrawerToggle.onConfigurationChanged(newConfig);
            }
        }

        public boolean onOptionsItemSelected(MenuItem item) {
            // Toggle navigation drawer on selecting action bar app icon/title.
            return mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item);
        }
    }
}