package com.byoutline.kickmaterial.activities;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.StringRes;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Pair;
import android.view.View;
import android.view.Window;
import android.view.animation.DecelerateInterpolator;
import com.byoutline.kickmaterial.R;
import com.byoutline.kickmaterial.fragments.KickMaterialFragment;
import com.byoutline.kickmaterial.utils.LUtils;
import com.byoutline.secretsauce.activities.BaseAppCompatActivity;
import com.byoutline.secretsauce.fragments.MenuOption;
import com.byoutline.secretsauce.fragments.NavigationDrawerFragment;
import com.byoutline.secretsauce.utils.ViewUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @author Pawel Karczewski <pawel.karczewski at byoutline.com> on 2015-01-03
*/
public abstract class KickMaterialBaseActivity extends BaseAppCompatActivity implements KickMaterialFragment.HostActivity, NavigationDrawerFragment.NavigationDrawerCallbacks {
private static final int HEADER_HIDE_ANIM_DURATION = 300;
private int actionBarAutoHideSensitivity = 0;
private int actionBarAutoHideMinY = 0;
private int actionBarAutoHideSignal = 0;
private boolean actionBarShown = true;
protected static Bundle getSharedElementsBundle(Activity activity, View... sharedViews) {
final Bundle options;
if (LUtils.hasL()) {
options = getSharedElementsBundleL(activity, sharedViews);
} else {
options = new Bundle();
}
return options;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static Bundle getSharedElementsBundleL(Activity activity, View... sharedViews) {
Bundle options;
View decor = activity.getWindow().getDecorView();
View navBar = decor.findViewById(android.R.id.navigationBarBackground);
View toolbar = decor.findViewById(R.id.toolbar);
List<Pair<View, String>> sharedElements = new ArrayList<>();
for (View sharedElement : sharedViews) {
if (sharedElement == null) {
continue;
}
sharedElements.add(new Pair<>(sharedElement, sharedElement.getTransitionName()));
}
if (navBar != null) {
sharedElements.add(new Pair<>(navBar, Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME));
}
if (toolbar != null) {
sharedElements.add(new Pair<>(toolbar, "toolbar"));
}
@SuppressWarnings("unchecked") Pair<View, String>[] arr = sharedElements.toArray(new Pair[sharedElements.size()]);
options = ActivityOptions.makeSceneTransitionAnimation(activity, arr).toBundle();
return options;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
blockOrientationOnBuggedAndroidVersions();
}
protected boolean shouldBlockOrientationOnBuggedAndroidVersions() {
return true;
}
private void blockOrientationOnBuggedAndroidVersions() {
if(!shouldBlockOrientationOnBuggedAndroidVersions()){
return;
}
// On Android 5.0 rotating device in activity that was entered with
// transition will cause crash during activity exit transition.
// This bug was fixed in Android 5.1.
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
protected void injectViewsAndSetUpToolbar() {
injectViewsAndSetUpToolbar(R.id.toolbar, R.id.toolbar_title_tv);
ViewCompat.setElevation(this.toolbar, ViewUtils.convertDpToPixel(4.0F, this));
}
@Override
public void enableActionBarAutoHide(final RecyclerView listView) {
initActionBarAutoHide();
listView.setOnScrollListener(new RecyclerView.OnScrollListener() {
final static int ITEMS_THRESHOLD = 1;
int lastFvi = 0;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstVisibleItem = ((GridLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
onMainContentScrolled(firstVisibleItem <= ITEMS_THRESHOLD ? 0 : Integer.MAX_VALUE,
lastFvi - firstVisibleItem > 0 ? Integer.MIN_VALUE :
lastFvi == firstVisibleItem ? 0 : Integer.MAX_VALUE
);
lastFvi = firstVisibleItem;
}
});
}
/**
* Initializes the Action Bar auto-hide (aka Quick Recall) effect.
*/
private void initActionBarAutoHide() {
actionBarAutoHideMinY = getResources().getDimensionPixelSize(R.dimen.action_bar_auto_hide_min_y);
actionBarAutoHideSensitivity = getResources().getDimensionPixelSize(
R.dimen.action_bar_auto_hide_sensivity);
}
/**
* 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 > actionBarAutoHideSensitivity) {
deltaY = actionBarAutoHideSensitivity;
} else if (deltaY < -actionBarAutoHideSensitivity) {
deltaY = -actionBarAutoHideSensitivity;
}
if (Math.signum(deltaY) * Math.signum(actionBarAutoHideSignal) < 0) {
// deltaY is a motion opposite to the accumulated signal, so reset signal
actionBarAutoHideSignal = deltaY;
} else {
// add to accumulated signal
actionBarAutoHideSignal += deltaY;
}
boolean shouldShow = currentY < actionBarAutoHideMinY ||
(actionBarAutoHideSignal <= -actionBarAutoHideSensitivity);
autoShowOrHideActionBar(shouldShow);
}
protected void autoShowOrHideActionBar(boolean show) {
if (show == actionBarShown) {
return;
}
actionBarShown = show;
onActionBarAutoShowOrHide(show);
}
protected void onActionBarAutoShowOrHide(boolean shown) {
View view = toolbar;
if (shown) {
view.animate()
.translationY(0)
.alpha(1)
.setDuration(HEADER_HIDE_ANIM_DURATION)
.setInterpolator(new DecelerateInterpolator());
} else {
view.animate()
.translationY(-view.getBottom())
.alpha(0)
.setDuration(HEADER_HIDE_ANIM_DURATION)
.setInterpolator(new DecelerateInterpolator());
}
}
@Override
public void showActionbar(boolean show, boolean animate) {
if (animate) {
autoShowOrHideActionBar(show);
} else {
if (show) {
getSupportActionBar().show();
} else {
getSupportActionBar().hide();
}
}
}
public void setToolbarText(@StringRes int textId) {
setToolbarText(getString(textId));
}
@Override
public void onPause() {
super.onPause();
}
@Override
public Class<? extends android.support.v4.app.Fragment> onNavigationDrawerItemSelected(MenuOption menuOption) {
// Currently there is no drawer
return null;
}
}