com.afollestad.polar.ui.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.afollestad.polar.ui.MainActivity.java

Source

package com.afollestad.polar.ui;

import android.annotation.TargetApi;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.SharedElementCallback;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.DrawableRes;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.widget.LinearLayout;

import com.afollestad.bridge.Bridge;
import com.afollestad.materialdialogs.util.DialogUtils;
import com.afollestad.polar.BuildConfig;
import com.afollestad.polar.R;
import com.afollestad.polar.adapters.MainPagerAdapter;
import com.afollestad.polar.config.Config;
import com.afollestad.polar.dialogs.ChangelogDialog;
import com.afollestad.polar.dialogs.InvalidLicenseDialog;
import com.afollestad.polar.fragments.AboutFragment;
import com.afollestad.polar.fragments.ApplyFragment;
import com.afollestad.polar.fragments.HomeFragment;
import com.afollestad.polar.fragments.IconsFragment;
import com.afollestad.polar.fragments.KustomFragment;
import com.afollestad.polar.fragments.RequestsFragment;
import com.afollestad.polar.fragments.WallpapersFragment;
import com.afollestad.polar.fragments.ZooperFragment;
import com.afollestad.polar.fragments.base.BasePageFragment;
import com.afollestad.polar.kustom.KustomUtil;
import com.afollestad.polar.ui.base.BaseDonateActivity;
import com.afollestad.polar.util.DrawableXmlParser;
import com.afollestad.polar.util.LicensingUtils;
import com.afollestad.polar.util.PagesBuilder;
import com.afollestad.polar.util.TintUtils;
import com.afollestad.polar.util.Utils;
import com.afollestad.polar.util.VC;
import com.afollestad.polar.util.WallpaperUtils;
import com.afollestad.polar.views.DisableableViewPager;
import com.google.android.vending.licensing.Policy;

import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.ButterKnife;

import static com.afollestad.polar.fragments.WallpapersFragment.RQ_CROPANDSETWALLPAPER;
import static com.afollestad.polar.fragments.WallpapersFragment.RQ_VIEWWALLPAPER;
import static com.afollestad.polar.viewer.ViewerActivity.STATE_CURRENT_POSITION;

/**
 * @author Aidan Follestad (afollestad)
 */
public class MainActivity extends BaseDonateActivity
        implements LicensingUtils.LicensingCallback, NavigationView.OnNavigationItemSelectedListener {

    @BindView(R.id.toolbar)
    Toolbar mToolbar;

    @Nullable
    @BindView(R.id.tabs)
    TabLayout mTabs;

    @Nullable
    @BindView(R.id.navigation_view)
    NavigationView mNavView;
    @Nullable
    @BindView(R.id.drawer)
    DrawerLayout mDrawer;

    @BindView(R.id.pager)
    DisableableViewPager mPager;

    @Nullable
    @BindView(R.id.app_bar)
    LinearLayout mAppBarLinear;

    int mDrawerModeTopInset;

    private PagesBuilder mPages;

    private boolean isReentering;
    private int reenterPos;

    @Override
    public Toolbar getToolbar() {
        return mToolbar;
    }

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

        final boolean useNavDrawer = Config.get().navDrawerModeEnabled();
        if (useNavDrawer)
            setContentView(R.layout.activity_main_drawer);
        else
            setContentView(R.layout.activity_main);

        ButterKnife.bind(this);
        setSupportActionBar(mToolbar);

        setupPages();
        setupPager();
        if (useNavDrawer)
            setupNavDrawer();
        else
            setupTabs();

        // Restore last selected page, tab/nav-drawer-item
        if (Config.get().persistSelectedPage()) {
            int lastPage = PreferenceManager.getDefaultSharedPreferences(MainActivity.this)
                    .getInt("last_selected_page", 0);
            if (lastPage > mPager.getAdapter().getCount() - 1)
                lastPage = 0;
            mPager.setCurrentItem(lastPage);
            if (mNavView != null)
                invalidateNavViewSelection(lastPage);
        }
        dispatchFragmentUpdateTitle(!useNavDrawer);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setExitSharedElementCallback(new SharedElementCallback() {
                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
                @Override
                public void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {
                    if (isReentering) {
                        WallpapersFragment frag = (WallpapersFragment) getFragmentManager()
                                .findFragmentByTag("page:" + mPager.getCurrentItem());
                        final RecyclerView recyclerView = frag.getRecyclerView();
                        View item = recyclerView.findViewWithTag("view_" + reenterPos);
                        View image = item.findViewById(R.id.image);

                        names.clear();
                        names.add(image.getTransitionName());
                        sharedElements.clear();
                        sharedElements.put(image.getTransitionName(), image);

                        isReentering = false;
                    }
                }
            });
        }

        processIntent(getIntent());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        processIntent(intent);
    }

    private void processIntent(Intent intent) {
        if (Intent.ACTION_SET_WALLPAPER.equals(intent.getAction())) {
            for (int i = 0; i < mPages.size(); i++) {
                PagesBuilder.Page page = mPages.get(i);
                if (page.drawerId == R.id.drawer_wallpapers) {
                    mPager.setCurrentItem(i);
                    break;
                }
            }
        }
    }

    private void setupPages() {
        mPages = new PagesBuilder(7);
        if (Config.get().homepageEnabled())
            mPages.add(new PagesBuilder.Page(R.id.drawer_home, R.drawable.tab_home, R.string.home,
                    new HomeFragment()));
        mPages.add(new PagesBuilder.Page(R.id.drawer_icons, R.drawable.tab_icons, R.string.icons,
                new IconsFragment()));
        if (Config.get().wallpapersEnabled())
            mPages.add(new PagesBuilder.Page(R.id.drawer_wallpapers, R.drawable.tab_wallpapers, R.string.wallpapers,
                    new WallpapersFragment()));
        if (Config.get().iconRequestEnabled())
            mPages.add(new PagesBuilder.Page(R.id.drawer_requestIcons, R.drawable.tab_requests,
                    R.string.request_icons, new RequestsFragment()));
        mPages.add(new PagesBuilder.Page(R.id.drawer_apply, R.drawable.tab_apply, R.string.apply,
                new ApplyFragment()));
        if (Config.get().kustomWidgetEnabled())
            mPages.add(new PagesBuilder.Page(R.id.drawer_kwgt, R.drawable.tab_kwgt, R.string.kwgt,
                    KustomFragment.newInstance(KustomUtil.FOLDER_WIDGETS)));
        if (Config.get().kustomWallpaperEnabled())
            mPages.add(new PagesBuilder.Page(R.id.drawer_klwp, R.drawable.tab_klwp, R.string.klwp,
                    KustomFragment.newInstance(KustomUtil.FOLDER_WALLPAPERS)));
        if (Config.get().zooperEnabled())
            mPages.add(new PagesBuilder.Page(R.id.drawer_zooper, R.drawable.tab_zooper, R.string.zooper,
                    new ZooperFragment()));
        mPages.add(new PagesBuilder.Page(R.id.drawer_about, R.drawable.tab_about, R.string.about,
                new AboutFragment()));
    }

    public boolean retryLicenseCheck() {
        return LicensingUtils.check(this, this);
    }

    @Override
    public void onLicensingResult(boolean allow, int reason) {
        if (allow)
            showChangelogIfNecessary(true);
        else
            InvalidLicenseDialog.show(this, reason == Policy.RETRY);
    }

    @Override
    public void onLicensingError(int errorCode) {
        Utils.showError(this,
                new Exception(
                        "License checking error occurred, make sure everything is setup correctly. Error code: "
                                + errorCode));
    }

    public void showChangelogIfNecessary(boolean licenseAllowed) {
        if (!Config.get().changelogEnabled()) {
            retryLicenseCheck();
        } else if (licenseAllowed || retryLicenseCheck()) {
            final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
            final int currentVersion = BuildConfig.VERSION_CODE;
            if (currentVersion != prefs.getInt("changelog_version", -1)) {
                prefs.edit().putInt("changelog_version", currentVersion).apply();
                ChangelogDialog.show(this);
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);

        if (!Config.get().changelogEnabled())
            menu.findItem(R.id.changelog).setVisible(false);

        MenuItem darkTheme = menu.findItem(R.id.darkTheme);
        if (!Config.get().allowThemeSwitching())
            darkTheme.setVisible(false);
        else
            darkTheme.setChecked(darkTheme());

        MenuItem navDrawerMode = menu.findItem(R.id.navDrawerMode);
        if (Config.get().navDrawerModeAllowSwitch()) {
            navDrawerMode.setVisible(true);
            navDrawerMode.setChecked(Config.get().navDrawerModeEnabled());
        }

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.changelog) {
            ChangelogDialog.show(this);
            return true;
        } else if (item.getItemId() == R.id.darkTheme) {
            darkTheme(!darkTheme());
            mToolbar.postDelayed(new Runnable() {
                @Override
                public void run() {
                    recreate();
                }
            }, 500);
            return true;
        } else if (item.getItemId() == R.id.navDrawerMode) {
            item.setChecked(!item.isChecked());
            Config.get().navDrawerModeEnabled(item.isChecked());
            recreate();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void setupNavDrawer() {
        assert mNavView != null;
        assert mDrawer != null;
        mNavView.getMenu().clear();
        for (PagesBuilder.Page page : mPages)
            page.addToMenu(mNavView.getMenu());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            getWindow().setStatusBarColor(Color.TRANSPARENT);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mDrawer.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {

                @TargetApi(Build.VERSION_CODES.LOLLIPOP)
                @Override
                public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
                    //TODO: Check if NavigationView needs bottom padding
                    WindowInsets drawerLayoutInsets = insets.replaceSystemWindowInsets(
                            insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
                            insets.getSystemWindowInsetRight(), 0);
                    mDrawerModeTopInset = drawerLayoutInsets.getSystemWindowInsetTop();
                    ((DrawerLayout) v).setChildInsets(drawerLayoutInsets,
                            drawerLayoutInsets.getSystemWindowInsetTop() > 0);
                    return insets;
                }
            });
        }

        assert getSupportActionBar() != null;
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        Drawable menuIcon = VC.get(R.drawable.ic_action_menu);
        menuIcon = TintUtils.createTintedDrawable(menuIcon, DialogUtils.resolveColor(this, R.attr.tab_icon_color));
        getSupportActionBar().setHomeAsUpIndicator(menuIcon);

        mDrawer.addDrawerListener(
                new ActionBarDrawerToggle(this, mDrawer, mToolbar, R.string.drawer_open, R.string.drawer_close));
        mDrawer.setStatusBarBackgroundColor(DialogUtils.resolveColor(this, R.attr.colorPrimaryDark));
        mNavView.setNavigationItemSelectedListener(this);

        final ColorDrawable navBg = (ColorDrawable) mNavView.getBackground();
        final int selectedIconText = DialogUtils.resolveColor(this, R.attr.colorAccent);
        int iconColor;
        int titleColor;
        int selectedBg;
        if (TintUtils.isColorLight(navBg.getColor())) {
            iconColor = ContextCompat.getColor(this, R.color.navigationview_normalicon_light);
            titleColor = ContextCompat.getColor(this, R.color.navigationview_normaltext_light);
            selectedBg = ContextCompat.getColor(this, R.color.navigationview_selectedbg_light);
        } else {
            iconColor = ContextCompat.getColor(this, R.color.navigationview_normalicon_dark);
            titleColor = ContextCompat.getColor(this, R.color.navigationview_normaltext_dark);
            selectedBg = ContextCompat.getColor(this, R.color.navigationview_selectedbg_dark);
        }

        final ColorStateList iconSl = new ColorStateList(new int[][] { new int[] { -android.R.attr.state_checked },
                new int[] { android.R.attr.state_checked } }, new int[] { iconColor, selectedIconText });
        final ColorStateList textSl = new ColorStateList(new int[][] { new int[] { -android.R.attr.state_checked },
                new int[] { android.R.attr.state_checked } }, new int[] { titleColor, selectedIconText });
        mNavView.setItemTextColor(textSl);
        mNavView.setItemIconTintList(iconSl);

        StateListDrawable bgDrawable = new StateListDrawable();
        bgDrawable.addState(new int[] { android.R.attr.state_checked }, new ColorDrawable(selectedBg));
        mNavView.setItemBackground(bgDrawable);

        mPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                dispatchFragmentUpdateTitle(false);
                invalidateNavViewSelection(position);
            }
        });

        mToolbar.setContentInsetsRelative(getResources().getDimensionPixelSize(R.dimen.second_keyline), 0);
    }

    void invalidateNavViewSelection(int position) {
        assert mNavView != null;
        final int selectedId = mPages.get(position).drawerId;
        mNavView.post(new Runnable() {
            @Override
            public void run() {
                mNavView.setCheckedItem(selectedId);
            }
        });
    }

    @Override
    public int getLastStatusBarInsetHeight() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return 0;
        }

        boolean useNavDrawer = Config.get().navDrawerModeEnabled();
        if (useNavDrawer) {
            return mDrawerModeTopInset;
        } else {
            return findViewById(R.id.root).getPaddingTop();
        }
    }

    private void setupPager() {
        mPager.setAdapter(new MainPagerAdapter(getFragmentManager(), mPages));
        mPager.setOffscreenPageLimit(mPages.size() - 1);
        // Paging is only enabled in tab mode
        mPager.setPagingEnabled(!Config.get().navDrawerModeEnabled());
    }

    private void setupTabs() {
        assert mTabs != null;
        mTabs.setTabMode(mPages.size() > 6 ? TabLayout.MODE_SCROLLABLE : TabLayout.MODE_FIXED);
        mTabs.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPager));
        mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabs) {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);
                dispatchFragmentUpdateTitle(false);
            }
        });

        for (PagesBuilder.Page page : mPages)
            addTab(page.iconRes);
        mTabs.setSelectedTabIndicatorColor(DialogUtils.resolveColor(this, R.attr.tab_indicator_color));
    }

    void dispatchFragmentUpdateTitle(final boolean checkTabsLocation) {
        //First set the presumed title, then let fragment do anything specific.
        setTitle(mPages.get(mPager.getCurrentItem()).titleRes);

        mPager.post(new Runnable() {
            @Override
            public void run() {
                final BasePageFragment frag = (BasePageFragment) getFragmentManager()
                        .findFragmentByTag("page:" + mPager.getCurrentItem());
                if (frag != null)
                    frag.updateTitle();

                if (checkTabsLocation) {
                    moveTabsIfNeeded();
                }
            }
        });
    }

    void moveTabsIfNeeded() {
        final CharSequence currentTitle = getTitle();

        String longestTitle = null;
        for (PagesBuilder.Page page : mPages) {
            String title = getString(page.titleRes);
            if (longestTitle == null || title.length() > longestTitle.length()) {
                longestTitle = title;
            }
        }
        setTitle(longestTitle);

        if (mTabs != null) {
            ViewTreeObserver vto = mToolbar.getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @SuppressWarnings("deprecation")
                @Override
                public void onGlobalLayout() {
                    if (mToolbar.isTitleTruncated() && mTabs.getParent() == mToolbar) {
                        mToolbar.removeView(mTabs);
                        //noinspection ConstantConditions
                        mAppBarLinear.addView(mTabs);
                    }

                    setTitle(currentTitle);

                    mToolbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }
            });
        }
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        ((DrawerLayout) findViewById(R.id.drawer)).closeDrawers();
        final int index = mPages.findPositionForItem(item);
        if (index > -1)
            mPager.setCurrentItem(index, false);
        return false;
    }

    private void addTab(@DrawableRes int icon) {
        assert mTabs != null;
        TabLayout.Tab tab = mTabs.newTab().setIcon(VC.get(icon));
        if (tab.getIcon() != null) {
            Drawable tintedIcon = DrawableCompat.wrap(tab.getIcon());
            DrawableCompat.setTint(tintedIcon, DialogUtils.resolveColor(this, R.attr.tab_icon_color));
            tab.setIcon(tintedIcon);
        }
        mTabs.addTab(tab);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (Config.get().persistSelectedPage()) {
            PreferenceManager.getDefaultSharedPreferences(MainActivity.this).edit()
                    .putInt("last_selected_page", mPager.getCurrentItem()).commit();
        }
        if (isFinishing()) {
            Config.deinit();
            Bridge.destroy();
            DrawableXmlParser.cleanup();
            LicensingUtils.cleanup();
            VC.destroy();
            Utils.wipe(getExternalCacheDir());
        }
    }

    @Override
    public void onBackPressed() {
        if (mPager != null) {
            FragmentManager fm = getFragmentManager();
            Fragment current = fm.findFragmentByTag("page:" + mPager.getCurrentItem());
            if (current != null && current instanceof RequestsFragment
                    && ((RequestsFragment) current).onBackPressed()) {
                return;
            }
        }
        super.onBackPressed();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RQ_CROPANDSETWALLPAPER) {
            WallpapersFragment.showToast(this, R.string.wallpaper_set);
            WallpaperUtils.resetOptionCache(true);
        } else if (requestCode == RQ_VIEWWALLPAPER) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mDrawer != null) {
                getWindow().setStatusBarColor(Color.TRANSPARENT);
                mDrawer.setStatusBarBackgroundColor(DialogUtils.resolveColor(this, R.attr.colorPrimaryDark));
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onActivityReenter(int resultCode, Intent data) {
        super.onActivityReenter(resultCode, data);

        isReentering = true;
        reenterPos = data.getIntExtra(STATE_CURRENT_POSITION, 0);

        WallpapersFragment frag = (WallpapersFragment) getFragmentManager()
                .findFragmentByTag("page:" + mPager.getCurrentItem());
        final RecyclerView recyclerView = frag.getRecyclerView();
        if (recyclerView != null) {
            postponeEnterTransition();
            recyclerView.scrollToPosition(reenterPos);
            recyclerView.post(new Runnable() {
                @Override
                public void run() {
                    recyclerView.getViewTreeObserver()
                            .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                                @Override
                                public boolean onPreDraw() {
                                    recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);

                                    startPostponedEnterTransition();
                                    return true;
                                }
                            });
                }
            });
        }
    }
}