Skip to content

Instantly share code, notes, and snippets.

@VladSumtsov
Created August 30, 2016 07:24
Show Gist options
  • Save VladSumtsov/b7fd77d13e8d5ba5795bdd3fea9634e2 to your computer and use it in GitHub Desktop.
Save VladSumtsov/b7fd77d13e8d5ba5795bdd3fea9634e2 to your computer and use it in GitHub Desktop.
for mortar
package com.ghm.ui.view;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import com.ghm.R;
import com.ghm.mortar.ActivityOwnerPresenter;
import com.ghm.mortar.ActivityOwnerPresenter.MenuAction;
import com.ghm.ui.flow.AppMortarFramePathContainerView;
import com.ghm.ui.flow.AppPathContainer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import butterknife.BindView;
import butterknife.ButterKnife;
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
import mortar.MortarScope;
import static android.view.View.ALPHA;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
/**
* Created by Dmitriy Puzak on 6/15/16.
*/
public class ActivityOwnerHelper implements ActivityOwnerPresenter.Behaviour {
public static final String EXTRA_CONFIG_DATA = "extra_config_data";
private static final String CUSTOM_VIEW = "custom_view";
private final AppCompatActivity activity;
private final ActivityOwnerPresenter activityOwner;
@BindView(R.id.container) AppMortarFramePathContainerView container;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.horizontal_progress) MaterialProgressBar horizontalProgress;
@BindView(R.id.circle_progress) CircleProgressBar circleProgress;
@BindView(R.id.root_container) FrameLayout rootContainer;
private int drawableRes;
private Map<View, MenuAction> menuActions = new HashMap<>();
public ActivityOwnerHelper(AppCompatActivity activity, ActivityOwnerPresenter activityOwner) {
this.activity = activity;
this.activityOwner = activityOwner;
}
public void onCreate(Bundle savedInstanceState) {
ButterKnife.bind(this, activity);
activity.setSupportActionBar(toolbar);
activityOwner.takeView(this);
restoreConfig(savedInstanceState);
}
private void restoreConfig(Bundle savedInstanceState) {
if (savedInstanceState == null || !savedInstanceState.containsKey(EXTRA_CONFIG_DATA))
return;
ActivityOwnerPresenter.Config config = savedInstanceState.getParcelable(EXTRA_CONFIG_DATA);
if (config.isShowActionBar()) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) container.getLayoutParams();
lp.setMargins(0, getActionBarHeight(), 0, 0);
container.setLayoutParams(lp);
}
activityOwner.updateConfigFromParent(config);
}
public void onSaveInstanceState(Bundle outState) {
outState.putParcelable(EXTRA_CONFIG_DATA, activityOwner.getConfig());
}
public void onResume() {
activityOwner.updateConfigFromParent(activityOwner.getConfig());
}
public void onDestroy() {
activityOwner.dropView(this);
activityOwner.updateConfigFromParent(null);
}
@Override
public void setShowHomeEnabled(boolean enabled) {
ActionBar actionBar = activity.getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(enabled);
}
@Override
public void showUpButton(boolean enabled) {
ActionBar actionBar = activity.getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(enabled);
actionBar.setHomeButtonEnabled(enabled);
}
@Override public void setTitle(String title) {
ActionBar actionBar = activity.getSupportActionBar();
actionBar.setTitle(title);
}
@Override public void setTranslucentStatus(boolean translucent) {
setTranslucent(FLAG_TRANSLUCENT_STATUS, translucent);
}
@Override public void setTranslucentNavigation(boolean translucent) {
setTranslucent(FLAG_TRANSLUCENT_NAVIGATION, translucent);
}
private void setTranslucent(int flag, boolean translucent) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
Window window = activity.getWindow();
if (translucent) {
window.setFlags(flag, flag);
} else {
WindowManager.LayoutParams attrs = window.getAttributes();
attrs.flags &= (~flag);
window.setAttributes(attrs);
window.clearFlags(FLAG_LAYOUT_NO_LIMITS);
}
}
@Override public void shouldShowActionBar(boolean isVisible) {
if ((toolbar.getAlpha() == 1 && isVisible) ||
(toolbar.getAlpha() == 0 && !isVisible)) return;
int actionBarHeight = getActionBarHeight();
int from = isVisible ? 0 : actionBarHeight;
int to = isVisible ? actionBarHeight : 0;
ValueAnimator offsetAnimator = ValueAnimator
.ofInt(from, to)
.setDuration(AppPathContainer.TRANSACTION_DURATION);
offsetAnimator.addUpdateListener(animation -> {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) container.getLayoutParams();
lp.setMargins(0, (Integer) animation.getAnimatedValue(), 0, 0);
container.setLayoutParams(lp);
});
ObjectAnimator toolbarAnimator = ObjectAnimator
.ofFloat(toolbar, ALPHA, isVisible ? 0 : 1, isVisible ? 1 : 0)
.setDuration(isVisible ? AppPathContainer.TRANSACTION_DURATION : 0);
toolbarAnimator.addListener(new AnimatorListenerAdapter() {
@Override public void onAnimationEnd(Animator animation) {
if (!isVisible) toolbar.setVisibility(GONE);
}
@Override public void onAnimationStart(Animator animation) {
if (isVisible) toolbar.setVisibility(VISIBLE);
}
});
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(offsetAnimator, toolbarAnimator);
animatorSet.start();
}
private int getActionBarHeight() {
TypedArray styledAttributes = activity.getTheme().obtainStyledAttributes(new int[]{android.R.attr.actionBarSize});
int actionBarHeight = (int) styledAttributes.getDimension(0, 0);
styledAttributes.recycle();
return actionBarHeight;
}
@Override public Activity getActivity() {
return activity;
}
@Override public void addMenuAction(View view, MenuAction menuAction) {
menuActions.put(view, menuAction);
activity.invalidateOptionsMenu();
}
@Override public void removeMenuAction(View view) {
menuActions.remove(view);
activity.invalidateOptionsMenu();
}
/**
* Use double remove and post to avoid issue of toolbar
*/
@Override public void setToolbarCustomView(View view) {
View prevView = toolbar.findViewWithTag(CUSTOM_VIEW);
if (view != null) {
toolbar.setTitle("");
}
if (prevView != null && view != null && view.getClass() == prevView.getClass()) {
return;
}
//This double remove used to avoid issue of toolbar redrawing
toolbar.removeView(prevView);
toolbar.post(() -> toolbar.removeView(prevView));
if (view != null) {
view.setTag(CUSTOM_VIEW);
toolbar.post(() -> {
if (view.getParent() != null) return;
toolbar.addView(view);
});
}
}
@Override public void showHorizontalProgress(boolean isVisible) {
activityOwner.getConfig().setShowHorizontalProgress(isVisible);
horizontalProgress.setVisibility(isVisible ? VISIBLE : GONE);
}
@Override public void showCircleProgress(boolean isVisible) {
activityOwner.getConfig().setShowCircleProgress(isVisible);
circleProgress.setVisibility(isVisible ? VISIBLE : GONE);
}
@Override public void setMainBackground(@DrawableRes int drawableRes) {
if (drawableRes == this.drawableRes) return;
rootContainer.setBackgroundResource(drawableRes);
this.drawableRes = drawableRes;
}
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
activity.onBackPressed();
return true;
}
List<MenuAction> values = new ArrayList<>(menuActions.values());
for (MenuAction menuAction : values) {
menuAction.onOptionsItemSelected(item);
}
return false;
}
public boolean onCreateOptionsMenu(Menu menu, MortarScope activityScope) {
Set<View> keys = new HashSet<>(menuActions.keySet());
for (View view : keys) {
MenuAction menuAction = menuActions.get(view);
menuAction.onCreateOptionsMenu(activity.getMenuInflater(), menu);
}
// menu.add("Log")
// .setOnMenuItemClickListener(item -> {
// Log.d("DemoActivity", MortarScopeDevHelper.scopeHierarchyToString(activityScope));
// return true;
// });
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment