package com.auth0.sharelock; import android.content.Intent; import android.content.res.TypedArray; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.Toolbar; import android.text.Html; import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.ImageButton; import android.widget.RelativeLayout; import android.widget.TextView; import com.github.ksoichiro.android.observablescrollview.ObservableScrollView; import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; import com.github.ksoichiro.android.observablescrollview.ScrollState; import com.github.ksoichiro.android.observablescrollview.ScrollUtils; import com.nineoldandroids.animation.ValueAnimator; import com.nineoldandroids.view.ViewHelper; import com.nineoldandroids.view.ViewPropertyAnimator; public class AboutActivity extends BaseMenuActivity implements ObservableScrollViewCallbacks { private int mFlexibleSpaceImageHeight; private int mActionBarSize; private int mIntersectionHeight; private View mHeader; private View mHeaderBar; private View mHeaderBackground; private boolean mReady; private int mPrevScrollY; private boolean mGapIsChanging; private boolean mGapHidden; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_about); ImageButton newButton = (ImageButton) findViewById(R.id.about_new_button); newButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startNewSecretActivity(); } }); final Toolbar toolbar = (Toolbar) findViewById(R.id.about_toolbar); setSupportActionBar(toolbar); mFlexibleSpaceImageHeight = getResources().getDimensionPixelSize(R.dimen.about_flexible_space_height); mActionBarSize = getActionBarSize(); // Even when the top gap has began to change, header bar still can move // within mIntersectionHeight. mIntersectionHeight = getResources().getDimensionPixelSize(R.dimen.about_intersection_height); mHeader = findViewById(R.id.about_header); mHeaderBar = findViewById(R.id.about_header_bar); mHeaderBackground = findViewById(R.id.about_header_background); final ObservableScrollView scrollable = createScrollable(); final TextView subtitleText = (TextView) findViewById(R.id.about_subtitle); subtitleText.setText(getString(R.string.about_subtitle)); setTitle(null); ScrollUtils.addOnGlobalLayoutListener((View) scrollable, new Runnable() { @Override public void run() { mReady = true; updateViews(scrollable.getCurrentScrollY(), false); } }); TextView aboutText = (TextView) findViewById(R.id.container); aboutText.setText(Html.fromHtml(getString(R.string.sharelock_about))); } private void startNewSecretActivity() { final Intent intent = new Intent(this, ComposeActivity.class); startActivity(intent); } @Override protected int getMenuLayout() { return R.menu.menu_about; } @Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { updateViews(scrollY, true); } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { } protected void updateViews(int scrollY, boolean animated) { // If it's ListView, onScrollChanged is called before ListView is laid out (onGlobalLayout). // This causes weird animation when onRestoreInstanceState occurred, // so we check if it's laid out already. if (!mReady) { return; } // Translate header ViewHelper.setTranslationY(mHeader, getHeaderTranslationY(scrollY)); // Show/hide gap final int headerHeight = mHeaderBar.getHeight(); boolean scrollUp = mPrevScrollY < scrollY; if (scrollUp) { if (mFlexibleSpaceImageHeight - headerHeight - mActionBarSize <= scrollY) { changeHeaderBackgroundHeightAnimated(false, animated); } } else { if (scrollY <= mFlexibleSpaceImageHeight - headerHeight - mActionBarSize) { changeHeaderBackgroundHeightAnimated(true, animated); } } mPrevScrollY = scrollY; } protected float getHeaderTranslationY(int scrollY) { final int headerHeight = mHeaderBar.getHeight(); int headerTranslationY = mActionBarSize - mIntersectionHeight; if (0 <= -scrollY + mFlexibleSpaceImageHeight - headerHeight - mActionBarSize + mIntersectionHeight) { headerTranslationY = -scrollY + mFlexibleSpaceImageHeight - headerHeight; } return headerTranslationY; } private void changeHeaderBackgroundHeightAnimated(boolean shouldShowGap, boolean animated) { if (mGapIsChanging) { return; } final int heightOnGapShown = mHeaderBar.getHeight(); final int heightOnGapHidden = mHeaderBar.getHeight() + mActionBarSize; final float from = mHeaderBackground.getLayoutParams().height; final float to; if (shouldShowGap) { if (!mGapHidden) { // Already shown return; } to = heightOnGapShown; } else { if (mGapHidden) { // Already hidden return; } to = heightOnGapHidden; } if (animated) { ViewPropertyAnimator.animate(mHeaderBackground).cancel(); ValueAnimator a = ValueAnimator.ofFloat(from, to); a.setDuration(100); a.setInterpolator(new AccelerateDecelerateInterpolator()); a.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float height = (float) animation.getAnimatedValue(); changeHeaderBackgroundHeight(height, to, heightOnGapHidden); } }); a.start(); } else { changeHeaderBackgroundHeight(to, to, heightOnGapHidden); } } private void changeHeaderBackgroundHeight(float height, float to, float heightOnGapHidden) { RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mHeaderBackground.getLayoutParams(); lp.height = (int) height; lp.topMargin = (int) (mHeaderBar.getHeight() - height); mHeaderBackground.requestLayout(); mGapIsChanging = (height != to); if (!mGapIsChanging) { mGapHidden = (height == heightOnGapHidden); } } protected int getActionBarSize() { TypedValue typedValue = new TypedValue(); int[] textSizeAttr = new int[]{R.attr.actionBarSize}; int indexOfAttrTextSize = 0; TypedArray a = obtainStyledAttributes(typedValue.data, textSizeAttr); int actionBarSize = a.getDimensionPixelSize(indexOfAttrTextSize, -1); a.recycle(); return actionBarSize; } protected ObservableScrollView createScrollable() { ObservableScrollView scrollView = (ObservableScrollView) findViewById(R.id.scroll); scrollView.setScrollViewCallbacks(this); return scrollView; } }