package com.seafile.seadroid2.ui.activity; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.PersistableBundle; import android.support.v4.app.NavUtils; import android.support.v4.app.TaskStackBuilder; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.DisplayMetrics; import android.view.View; import android.widget.AbsListView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; import com.seafile.seadroid2.R; import java.util.HashMap; import java.util.Map; /** * A base activity that handles common functionality in the app. This includes Action Bar tweaks. */ public class BaseActivity extends AppCompatActivity { // variables that control the Action Bar auto hide behavior (aka "quick recall") private boolean mActionBarAutoHideEnabled = false; // Primary toolbar and drawer toggle private Toolbar mActionBarToolbar; private int mActionBarAutoHideMinY = 0; private int mActionBarAutoHideSensivity = 0; private int mActionBarAutoHideSignal = 0; private boolean mActionBarShown = true; protected int screenWidth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActionBar ab = getSupportActionBar(); if (ab != null) { ab.setDisplayHomeAsUpEnabled(true); } } protected Toolbar getActionBarToolbar() { if (mActionBarToolbar == null) { mActionBarToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar); if (mActionBarToolbar != null) { // Depending on which version of Android you are on the Toolbar or the ActionBar may be // active so the a11y description is set here. mActionBarToolbar.setNavigationContentDescription(getResources().getString(R.string .navdrawer_description_a11y)); setSupportActionBar(mActionBarToolbar); } } return mActionBarToolbar; } @Override public void setContentView(int layoutResID) { super.setContentView(layoutResID); getActionBarToolbar(); } /** * Initializes the Action Bar auto-hide (aka Quick Recall) effect. */ private void initActionBarAutoHide() { mActionBarAutoHideEnabled = true; mActionBarAutoHideMinY = getResources().getDimensionPixelSize( R.dimen.action_bar_auto_hide_min_y); mActionBarAutoHideSensivity = getResources().getDimensionPixelSize( R.dimen.action_bar_auto_hide_sensivity); } protected void enableActionBarAutoHide(final ListView listView) { initActionBarAutoHide(); listView.setOnScrollListener(new AbsListView.OnScrollListener() { /** The heights of all items. */ private Map<Integer, Integer> heights = new HashMap<>(); private int lastCurrentScrollY = 0; @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // Get the first visible item's view. View firstVisibleItemView = view.getChildAt(0); if (firstVisibleItemView == null) { return; } // Save the height of the visible item. heights.put(firstVisibleItem, firstVisibleItemView.getHeight()); // Calculate the height of all previous (hidden) items. int previousItemsHeight = 0; for (int i = 0; i < firstVisibleItem; i++) { previousItemsHeight += heights.get(i) != null ? heights.get(i) : 0; } int currentScrollY = previousItemsHeight - firstVisibleItemView.getTop() + view.getPaddingTop(); onMainContentScrolled(currentScrollY, currentScrollY - lastCurrentScrollY); lastCurrentScrollY = currentScrollY; } }); } /** * 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 > mActionBarAutoHideSensivity) { deltaY = mActionBarAutoHideSensivity; } else if (deltaY < -mActionBarAutoHideSensivity) { deltaY = -mActionBarAutoHideSensivity; } 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 <= -mActionBarAutoHideSensivity); autoShowOrHideActionBar(shouldShow); } protected void autoShowOrHideActionBar(boolean show) { if (show == mActionBarShown) { return; } mActionBarShown = show; //onActionBarAutoShowOrHide(show); } /** * This utility method handles Up navigation intents by searching for a parent activity and * navigating there if defined. When using this for an activity make sure to define both the * native parentActivity as well as the AppCompat one when supporting API levels less than 16. * when the activity has a single parent activity. If the activity doesn't have a single parent * activity then don't define one and this method will use back button functionality. If "Up" * functionality is still desired for activities without parents then use * {@code syntheticParentActivity} to define one dynamically. * * Note: Up navigation intents are represented by a back arrow in the top left of the Toolbar * in Material Design guidelines. * * @param currentActivity Activity in use when navigate Up action occurred. * @param syntheticParentActivity Parent activity to use when one is not already configured. */ public static void navigateUpOrBack(Activity currentActivity, Class<? extends Activity> syntheticParentActivity) { // Retrieve parent activity from AndroidManifest. Intent intent = NavUtils.getParentActivityIntent(currentActivity); // Synthesize the parent activity when a natural one doesn't exist. if (intent == null && syntheticParentActivity != null) { try { intent = NavUtils.getParentActivityIntent(currentActivity, syntheticParentActivity); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } } if (intent == null) { // No parent defined in manifest. This indicates the activity may be used by // in multiple flows throughout the app and doesn't have a strict parent. In // this case the navigation up button should act in the same manner as the // back button. This will result in users being forwarded back to other // applications if currentActivity was invoked from another application. currentActivity.onBackPressed(); } else { if (NavUtils.shouldUpRecreateTask(currentActivity, intent)) { // Need to synthesize a backstack since currentActivity was probably invoked by a // different app. The preserves the "Up" functionality within the app according to // the activity hierarchy defined in AndroidManifest.xml via parentActivity // attributes. TaskStackBuilder builder = TaskStackBuilder.create(currentActivity); builder.addNextIntentWithParentStack(intent); builder.startActivities(); } else { // Navigate normally to the manifest defined "Up" activity. NavUtils.navigateUpTo(currentActivity, intent); } } } /** * Show the given message in a {@link Toast} for a short period of time * <p> * This method may be called from any thread * * @param activity * @param message */ public void showShortToast(final Activity activity, final String message) { if (activity == null) return; Toast.makeText(activity, message, Toast.LENGTH_SHORT).show(); } /** * Show the message with the given resource id in a {@link Toast} for a short period of time * <p> * This method may be called from any thread * * @param activity * @param resId */ public void showShortToast(final Activity activity, final int resId) { if (activity == null) return; showShortToast(activity, activity.getString(resId)); } /** * Show the given message in a {@link Toast} for a long period of time * <p> * This method may be called from any thread * * @param activity * @param message */ public void showLongToast(final Activity activity, final String message) { if (activity == null) return; Toast.makeText(activity, message, Toast.LENGTH_LONG).show(); } /** * Show the message with the given resource id in a {@link Toast} for a long period of time * <p> * This method may be called from any thread * * @param activity * @param resId */ public void showLongToast(final Activity activity, final int resId) { if (activity == null) return; showLongToast(activity, activity.getString(resId)); } }