ca.zadrox.dota2esportticker.ui.BaseActivity.java Source code

Java tutorial

Introduction

Here is the source code for ca.zadrox.dota2esportticker.ui.BaseActivity.java

Source

/*
 * Copyright 2014 Nicholas Liu
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Portions Copyright 2014 Google Inc.
 */

package ca.zadrox.dota2esportticker.ui;

import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

import ca.zadrox.dota2esportticker.R;
import ca.zadrox.dota2esportticker.service.UpdateMatchService;
import ca.zadrox.dota2esportticker.ui.widget.MultiSwipeRefreshLayout;
import ca.zadrox.dota2esportticker.ui.widget.ScrimInsetsScrollView;
import ca.zadrox.dota2esportticker.util.HelpUtils;
import ca.zadrox.dota2esportticker.util.LUtils;
import ca.zadrox.dota2esportticker.util.PrefUtils;
import ca.zadrox.dota2esportticker.util.TimeUtils;
import ca.zadrox.dota2esportticker.util.UIUtils;

/**
 * Created by Acco on 10/20/2014.
 */
public abstract class BaseActivity extends ActionBarActivity implements
        SharedPreferences.OnSharedPreferenceChangeListener, MultiSwipeRefreshLayout.CanChildScrollUpCallback {
    protected static final int NAVDRAWER_ITEM_MATCHES = 0;
    protected static final int NAVDRAWER_ITEM_TEAMS = 1;
    protected static final int NAVDRAWER_ITEM_TOURNAMENTS = 2;
    protected static final int NAVDRAWER_ITEM_NEWS = 3;
    protected static final int NAVDRAWER_ITEM_SETTINGS = 4;
    protected static final int NAVDRAWER_ITEM_SEPARATOR = -1;
    protected static final int NAVDRAWER_ITEM_INVALID = -2;
    private static final String TAG = BaseActivity.class.getSimpleName();
    // hide additional UI elements on scroll
    private static final int HEADER_HIDE_ANIM_DURATION = 300;
    // probably not necessary, cause we don't have account... yet.
    private static final int ACCOUNT_BOX_EXPAND_ANIM_DURATION = 200;
    private static final int[] NAVDRAWER_TITLE_RES_ID = new int[] { R.string.navdrawer_item_matches,
            R.string.navdrawer_item_teams, R.string.navdrawer_item_tournaments, R.string.navdrawer_item_news,
            R.string.navdrawer_item_settings };
    private static final int[] NAVDRAWER_ICON_RES_ID = new int[] { R.drawable.ic_drawer_event,
            R.drawable.ic_drawer_group, R.drawable.ic_drawer_tournament, R.drawable.ic_drawer_subject,
            R.drawable.ic_drawer_settings };
    private static final int NAVDRAWER_LAUNCH_DELAY = 150;
    private static final int MAIN_CONTENT_FADEOUT_DURATION = 150;
    private static final int MAIN_CONTENT_FADEIN_DURATION = 250;
    private static final TypeEvaluator ARGB_EVALUATOR = new ArgbEvaluator();
    private DrawerLayout mDrawerLayout;
    private Handler mHandler;
    private ViewGroup mDrawerItemsListContainer;
    private boolean tabChanged;
    private LUtils mLUtils;
    private ObjectAnimator mStatusBarColorAnimator;
    // contains the views that we want to hide when the list is scrolled.
    private ArrayList<View> mHideableHeaderViews = new ArrayList<View>();
    // list of navdrawer items added.
    private ArrayList<Integer> mNavDrawerItems = new ArrayList<Integer>();
    // views associated with each navdrawer item
    private View[] mNavDrawerItemViews = null;
    // Used in at least News and Matches.
    private SwipeRefreshLayout mSwipeRefreshLayout;
    // ActionBar/Toolbar ref
    private Toolbar mActionBarToolbar;
    // Controls for hiding/showing actionbar on scroll.
    private boolean mActionBarAutoHideEnabled = false;
    private int mActionBarAutoHideSensitivity = 0;
    private int mActionBarAutoHideMinY = 0;
    private int mActionBarAutoHideSignal = 0;
    private boolean mActionBarShown = true;
    private Runnable mDeferredOnDrawerClosedRunnable;
    private int mThemedStatusBarColor;
    private int mNormalStatusBarColor;
    private int mProgressBarTopWhenActionBarShown;

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

        mHandler = new Handler();

        mLUtils = LUtils.getInstance(this);

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        sp.registerOnSharedPreferenceChangeListener(this);

        ActionBar ab = getSupportActionBar();
        if (ab != null) {
            ab.setDisplayHomeAsUpEnabled(true);
        }

        mThemedStatusBarColor = getResources().getColor(R.color.theme_primary_dark);
        mNormalStatusBarColor = mThemedStatusBarColor;

    }

    protected void trySetupSwipeRefresh() {
        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
        if (mSwipeRefreshLayout == null) {
            return;
        }

        mSwipeRefreshLayout.setColorSchemeColors(R.color.refresh_progress_1, R.color.refresh_progress_2,
                R.color.refresh_progress_3, R.color.refresh_progress_4);

        if (mActionBarShown) {
            // mSwipeRefreshLayout.setTop(mProgressBarTopWhenActionBarShown);
            mSwipeRefreshLayout.setProgressViewOffset(true, mProgressBarTopWhenActionBarShown,
                    mProgressBarTopWhenActionBarShown + 100);
        } else {
            mSwipeRefreshLayout.setProgressViewOffset(true, 0, UIUtils.calculateActionBarSize(this));
        }
    }

    protected void setProgressBarTopWhenActionBarShown(int progressBarTopWhenActionBarShown) {
        mProgressBarTopWhenActionBarShown = progressBarTopWhenActionBarShown;
        updateSwipeRefreshProgressBarTop();
    }

    private void updateSwipeRefreshProgressBarTop() {
        if (mSwipeRefreshLayout == null) {
            return;
        }

        if (mActionBarShown) {
            // mSwipeRefreshLayout.setTop(mProgressBarTopWhenActionBarShown);
            mSwipeRefreshLayout.setProgressViewOffset(true, mProgressBarTopWhenActionBarShown,
                    mProgressBarTopWhenActionBarShown + 100);
        } else {
            // mSwipeRefreshLayout.setTop(0);
            mSwipeRefreshLayout.setProgressViewOffset(true, 0, UIUtils.calculateActionBarSize(this));
        }
    }

    protected int getSelfNavDrawerItem() {
        return NAVDRAWER_ITEM_INVALID;
    }

    private void setupNavDrawer() {
        int selfItem = getSelfNavDrawerItem();

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (mDrawerLayout == null) {
            return;
        }
        mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.theme_primary_dark));
        ScrimInsetsScrollView navDrawer = (ScrimInsetsScrollView) mDrawerLayout.findViewById(R.id.navdrawer);

        if (selfItem == NAVDRAWER_ITEM_INVALID) {
            if (navDrawer != null) {
                ((ViewGroup) navDrawer.getParent()).removeView(navDrawer);
            }
            mDrawerLayout = null;
            return;
        }

        if (mActionBarToolbar != null) {
            mActionBarToolbar.setNavigationIcon(R.drawable.ic_drawer);
            mActionBarToolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mDrawerLayout.openDrawer(Gravity.START);
                }
            });
        }

        mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerClosed(View drawerView) {
                // run deferred action, if we have one
                if (mDeferredOnDrawerClosedRunnable != null) {
                    mDeferredOnDrawerClosedRunnable.run();
                    mDeferredOnDrawerClosedRunnable = null;
                }
                onNavDrawerStateChanged(false, false);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                onNavDrawerStateChanged(true, false);
            }

            @Override
            public void onDrawerStateChanged(int newState) {
                onNavDrawerStateChanged(isNavDrawerOpen(), newState != DrawerLayout.STATE_IDLE);
            }

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

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

        // populate the nav drawer with the correct items
        populateNavDrawer();

        // When the user runs the app for the first time, we want to land them with the
        // navigation drawer open. But just the first time.
        if (!PrefUtils.isWelcomeDone(this)) {
            // first run of the app starts with the nav drawer open
            PrefUtils.markWelcomeDone(this);
            mDrawerLayout.openDrawer(Gravity.START);

            this.startService(
                    new Intent(UpdateMatchService.ACTION_UPDATE_MATCHES, null, this, UpdateMatchService.class));

        }

        if (TimeUtils.getUTCTime() - PrefUtils.lastMatchUpdate(this) > 60000 * 60 * 12) {

            this.startService(new Intent(UpdateMatchService.ACTION_SCHEDULE_AUTO_UPDATE, null, this,
                    UpdateMatchService.class));

        }
    }

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

    protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
        if (mActionBarAutoHideEnabled && isOpen) {
            autoShowOrHideActionBar(true);
        }
    }

    protected void onNavDrawerSlide(float offset) {
    }

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

    private void populateNavDrawer() {
        mNavDrawerItems.clear();

        mNavDrawerItems.add(NAVDRAWER_ITEM_MATCHES);
        mNavDrawerItems.add(NAVDRAWER_ITEM_TEAMS);
        //mNavDrawerItems.add(NAVDRAWER_ITEM_TOURNAMENTS);
        //mNavDrawerItems.add(NAVDRAWER_ITEM_NEWS);
        mNavDrawerItems.add(NAVDRAWER_ITEM_SEPARATOR);
        mNavDrawerItems.add(NAVDRAWER_ITEM_SETTINGS);

        createNavDrawerItems();
    }

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

        mNavDrawerItemViews = new View[mNavDrawerItems.size()];
        mDrawerItemsListContainer.removeAllViews();

        int i = 0;

        for (int itemId : mNavDrawerItems) {
            mNavDrawerItemViews[i] = makeNavDrawerItem(itemId, mDrawerItemsListContainer);
            mDrawerItemsListContainer.addView(mNavDrawerItemViews[i]);
            ++i;
        }
    }

    private void setSelectedNavDrawerItem(int itemId) {
        if (mNavDrawerItemViews != null) {
            for (int i = 0; i < mNavDrawerItemViews.length; i++) {
                if (i < mNavDrawerItems.size()) {
                    int thisItemId = mNavDrawerItems.get(i);
                    formatNavDrawerItem(mNavDrawerItemViews[i], thisItemId, itemId == thisItemId);
                }
            }
        }
    }

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

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

        trySetupSwipeRefresh();
        updateSwipeRefreshProgressBarTop();

        //        View mainContent = findViewById(R.id.main_content);
        //        if (mainContent != null) {
        //            mainContent.setAlpha(0);
        //            mainContent.animate().alpha(1).setDuration(MAIN_CONTENT_FADEIN_DURATION);
        //        } else {
        //            Log.w(TAG, "No view to fade in");
        //        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
        case R.id.menu_about:
            HelpUtils.showAbout(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void goToNavDrawerItem(int item) {
        Intent intent;
        switch (item) {
        case NAVDRAWER_ITEM_MATCHES:
            intent = new Intent(this, MatchActivity.class);
            startActivity(intent);
            finish();
            break;
        case NAVDRAWER_ITEM_TEAMS:
            intent = new Intent(this, TeamActivity.class);
            startActivity(intent);
            finish();
            break;
        case NAVDRAWER_ITEM_TOURNAMENTS:
            Toast.makeText(this, "Not yet implemented", Toast.LENGTH_SHORT);
            break;
        //                intent = new Intent(this, LiveGameStatsActivity.class);
        //                startActivity(intent);
        //                finish();
        //                break;
        case NAVDRAWER_ITEM_NEWS:
            Toast.makeText(this, "Not yet implemented", Toast.LENGTH_SHORT);
            break;
        //                intent = new Intent(this, NewsActivity.class);
        //                startActivity(intent);
        //                finish();
        //                break;
        case NAVDRAWER_ITEM_SETTINGS:
            //                Toast.makeText(this, "Not yet implemented", Toast.LENGTH_SHORT);

            intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);
            break;
        }
    }

    private void onNavDrawerItemClicked(final int itemId) {
        if (itemId == getSelfNavDrawerItem()) {
            mDrawerLayout.closeDrawer(Gravity.START);
            return;
        }

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                goToNavDrawerItem(itemId);
            }
        }, NAVDRAWER_LAUNCH_DELAY);

        setSelectedNavDrawerItem(itemId);

        View mainContent = findViewById(R.id.main_content);
        if (mainContent != null) {
            //mainContent.animate().alpha(0).setDuration(MAIN_CONTENT_FADEOUT_DURATION);
        }

        mDrawerLayout.closeDrawer(Gravity.START);
    }

    protected void setTabChanged() {
        tabChanged = true;
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onStart() {
        super.onStart();
    }

    /**
     * Initializes the Action Bar auto-hide (aka Quick Recall) effect.
     */
    private void initActionBarAutoHide() {
        mActionBarAutoHideEnabled = true;
        mActionBarAutoHideMinY = getResources().getDimensionPixelOffset(R.dimen.action_bar_auto_hide_min_y);
        mActionBarAutoHideSensitivity = getResources()
                .getDimensionPixelOffset(R.dimen.action_bar_auto_hide_sensitivity);
    }

    /**
     * Indicates that the main content has scrolled (for the purposes of showing/hiding
     * the action bar for the "action bar auto hide" effect). currentY and deltaY may be exact
     * (if the underlying view supports it) or may be approximate indications:
     * deltaY may be INT_MAX to mean "scrolled forward indeterminately" and INT_MIN to mean
     * "scrolled backward indeterminately".  currentY may be 0 to mean "somewhere close to the
     * start of the list" and INT_MAX to mean "we don't know, but not at the start of the list"
     */
    private void onMainContentScrolled(int currentY, int deltaY) {
        if (deltaY > mActionBarAutoHideSensitivity) {
            deltaY = mActionBarAutoHideSensitivity;
        } else if (deltaY < -mActionBarAutoHideSensitivity) {
            deltaY = -mActionBarAutoHideSensitivity;
        }

        if (Math.signum(deltaY) * Math.signum(mActionBarAutoHideSignal) < 0) {
            // deltaY is a motion opposite to the accumulated signal, so reset signal
            mActionBarAutoHideSignal = deltaY;
        } else {
            // add to accumulated signal
            mActionBarAutoHideSignal += deltaY;
        }

        boolean shouldShow = currentY < mActionBarAutoHideMinY
                || (mActionBarAutoHideSignal <= -mActionBarAutoHideSensitivity);
        autoShowOrHideActionBar(shouldShow);
    }

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

    protected void autoShowOrHideActionBar(boolean show) {
        if (show == mActionBarShown) {
            return;
        }

        mActionBarShown = show;
        onActionBarAutoShowOrHide(show);
    }

    protected void enableActionBarAutoHide(final ListView listView) {
        initActionBarAutoHide();
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            final static int ITEMS_THRESHOLD = 3;
            int lastFvi = 0;

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                onMainContentScrolled(firstVisibleItem <= ITEMS_THRESHOLD ? 0 : Integer.MAX_VALUE,
                        lastFvi - firstVisibleItem > 0 ? Integer.MIN_VALUE
                                : lastFvi == firstVisibleItem ? 0 : Integer.MAX_VALUE);
                lastFvi = firstVisibleItem;
            }
        });
    }

    private View makeNavDrawerItem(final int itemId, ViewGroup container) {
        boolean selected = getSelfNavDrawerItem() == itemId;
        int layoutToInflate = 0;
        if (itemId == NAVDRAWER_ITEM_SEPARATOR) {
            layoutToInflate = R.layout.navdrawer_separator;
        } else {
            layoutToInflate = R.layout.navdrawer_item;
        }
        View view = getLayoutInflater().inflate(layoutToInflate, container, false);

        if (isSeparator(itemId)) {
            // we are 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 < NAVDRAWER_ICON_RES_ID.length ? NAVDRAWER_ICON_RES_ID[itemId] : 0;
        int titleId = itemId >= 0 && itemId < NAVDRAWER_TITLE_RES_ID.length ? NAVDRAWER_TITLE_RES_ID[itemId] : 0;

        // set icon and text
        iconView.setVisibility(iconId > 0 ? View.VISIBLE : View.GONE);
        if (iconId > 0) {
            iconView.setImageResource(iconId);
        }
        titleView.setText(getString(titleId));

        formatNavDrawerItem(view, itemId, selected);

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

        return view;
    }

    private boolean isSpecialItem(int itemId) {
        return itemId == NAVDRAWER_ITEM_SETTINGS;
    }

    private boolean isSeparator(int itemId) {
        return itemId == NAVDRAWER_ITEM_SEPARATOR;
    }

    private void formatNavDrawerItem(View view, int itemId, boolean selected) {
        if (isSeparator(itemId)) {
            // not applicable
            return;
        }

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

        // configure its appearance according to whether or not it's selected
        titleView.setTextColor(selected ? getResources().getColor(R.color.navdrawer_text_color_selected)
                : getResources().getColor(R.color.navdrawer_text_color));
        iconView.setColorFilter(selected ? getResources().getColor(R.color.navdrawer_icon_tint_selected)
                : getResources().getColor(R.color.navdrawer_icon_tint));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        sp.unregisterOnSharedPreferenceChangeListener(this);
    }

    protected void onRefreshingStateChanged(boolean refreshing) {
        if (mSwipeRefreshLayout != null) {
            mSwipeRefreshLayout.setRefreshing(refreshing);
        }
    }

    protected void enableDisableSwipeRefresh(boolean enable) {
        if (mSwipeRefreshLayout != null) {
            mSwipeRefreshLayout.setEnabled(enable);
        }
    }

    protected void registerHideableHeaderView(View hideableHeaderView) {
        if (!mHideableHeaderViews.contains(hideableHeaderView)) {
            mHideableHeaderViews.add(hideableHeaderView);
        }
    }

    protected void deregisterHideableHeaderView(View hideableHeaderView) {
        if (mHideableHeaderViews.contains(hideableHeaderView)) {
            mHideableHeaderViews.remove(hideableHeaderView);
        }
    }

    public LUtils getLUtils() {
        return mLUtils;
    }

    public int getThemedStatusBarColor() {
        return mThemedStatusBarColor;
    }

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

    protected void onActionBarAutoShowOrHide(boolean shown) {
        if (mStatusBarColorAnimator != null) {
            mStatusBarColorAnimator.cancel();
        }
        mStatusBarColorAnimator = ObjectAnimator
                .ofInt((mDrawerLayout != null) ? mDrawerLayout : mLUtils,
                        (mDrawerLayout != null) ? "statusBarBackgroundColor" : "statusBarColor",
                        shown ? Color.BLACK : mNormalStatusBarColor, shown ? mNormalStatusBarColor : Color.BLACK)
                .setDuration(250);
        if (mDrawerLayout != null) {
            mStatusBarColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    ViewCompat.postInvalidateOnAnimation(mDrawerLayout);
                }
            });
        }
        mStatusBarColorAnimator.setEvaluator(ARGB_EVALUATOR);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.L) {
            mStatusBarColorAnimator.start();
        }

        updateSwipeRefreshProgressBarTop();

        for (View view : mHideableHeaderViews) {
            if (shown) {
                view.animate().translationY(0).alpha(1).setDuration(HEADER_HIDE_ANIM_DURATION)
                        .setInterpolator(new DecelerateInterpolator());
            } else {
                view.animate().translationY(-UIUtils.calculateActionBarSize(this)).alpha(1)
                        .setDuration(HEADER_HIDE_ANIM_DURATION).setInterpolator(new DecelerateInterpolator());
            }
        }
    }

    @Override
    public boolean canSwipeRefreshChildScrollUp() {
        return false;
    }
}