/*
* Copyright 2014 Soichiro Kashima
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.marshalchen.common.demoofui.observablescrollview;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewTreeObserver;
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.marshalchen.common.demoofui.R;
import com.nineoldandroids.view.ViewHelper;
import com.nineoldandroids.view.ViewPropertyAnimator;
public class FlexibleSpaceWithImageScrollViewActivity extends ActionBarActivity implements ObservableScrollViewCallbacks {
private static final float MAX_TEXT_SCALE_DELTA = 0.3f;
private static final boolean TOOLBAR_IS_STICKY = false;
private View mToolbar;
private View mImageView;
private View mOverlayView;
private ObservableScrollView mScrollView;
private TextView mTitleView;
private View mFab;
private int mActionBarSize;
private int mFlexibleSpaceShowFabOffset;
private int mFlexibleSpaceImageHeight;
private int mFabMargin;
private int mToolbarColor;
private boolean mFabIsShown;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.observable_scroll_view_activity_flexiblespacewithimagescrollview);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
mFlexibleSpaceImageHeight = getResources().getDimensionPixelSize(R.dimen.flexible_space_image_height);
mFlexibleSpaceShowFabOffset = getResources().getDimensionPixelSize(R.dimen.flexible_space_show_fab_offset);
mActionBarSize = getActionBarSize();
mToolbarColor = getResources().getColor(R.color.primary);
mToolbar = findViewById(R.id.toolbar);
if (!TOOLBAR_IS_STICKY) {
mToolbar.setBackgroundColor(Color.TRANSPARENT);
}
mImageView = findViewById(R.id.image);
mOverlayView = findViewById(R.id.overlay);
mScrollView = (ObservableScrollView) findViewById(R.id.scroll);
mScrollView.setScrollViewCallbacks(this);
mTitleView = (TextView) findViewById(R.id.title);
mTitleView.setText(getTitle());
setTitle(null);
mFab = findViewById(R.id.fab);
mFabMargin = getResources().getDimensionPixelSize(R.dimen.margin_standard);
ViewHelper.setScaleX(mFab, 0);
ViewHelper.setScaleY(mFab, 0);
ViewTreeObserver vto = mScrollView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mScrollView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mScrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
mScrollView.scrollTo(0, mFlexibleSpaceImageHeight - mActionBarSize);
}
});
}
@Override
public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) {
// Translate overlay and image
float flexibleRange = mFlexibleSpaceImageHeight - mActionBarSize;
int minOverlayTransitionY = mActionBarSize - mOverlayView.getHeight();
ViewHelper.setTranslationY(mOverlayView, Math.max(minOverlayTransitionY, Math.min(0, -scrollY)));
ViewHelper.setTranslationY(mImageView, Math.max(minOverlayTransitionY, Math.min(0, -scrollY / 2)));
// Change alpha of overlay
ViewHelper.setAlpha(mOverlayView, Math.max(0, Math.min(1, (float) scrollY / flexibleRange)));
// Scale title text
float scale = 1 + Math.max(0, Math.min(MAX_TEXT_SCALE_DELTA, (flexibleRange - scrollY) / flexibleRange));
ViewHelper.setPivotX(mTitleView, 0);
ViewHelper.setPivotY(mTitleView, 0);
ViewHelper.setScaleX(mTitleView, scale);
ViewHelper.setScaleY(mTitleView, scale);
// Translate title text
int maxTitleTranslationY = (int) (mFlexibleSpaceImageHeight - mTitleView.getHeight() * scale);
int titleTranslationY = maxTitleTranslationY - scrollY;
if (TOOLBAR_IS_STICKY) {
titleTranslationY = Math.max(0, titleTranslationY);
}
ViewHelper.setTranslationY(mTitleView, titleTranslationY);
// Translate FAB
int maxFabTranslationY = mFlexibleSpaceImageHeight - mFab.getHeight() / 2;
int fabTranslationY = Math.max(mActionBarSize - mFab.getHeight() / 2,
Math.min(maxFabTranslationY, -scrollY + mFlexibleSpaceImageHeight - mFab.getHeight() / 2));
ViewHelper.setTranslationX(mFab, mOverlayView.getWidth() - mFabMargin - mFab.getWidth());
ViewHelper.setTranslationY(mFab, fabTranslationY);
// Show/hide FAB
if (ViewHelper.getTranslationY(mFab) < mFlexibleSpaceShowFabOffset) {
hideFab();
} else {
showFab();
}
if (TOOLBAR_IS_STICKY) {
// Change alpha of toolbar background
if (-scrollY + mFlexibleSpaceImageHeight <= mActionBarSize) {
setBackgroundAlpha(mToolbar, 1, mToolbarColor);
} else {
setBackgroundAlpha(mToolbar, 0, mToolbarColor);
}
} else {
// Translate Toolbar
if (scrollY < mFlexibleSpaceImageHeight) {
ViewHelper.setTranslationY(mToolbar, 0);
} else {
ViewHelper.setTranslationY(mToolbar, -scrollY);
}
}
}
@Override
public void onDownMotionEvent() {
}
@Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
}
private 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;
}
private void showFab() {
if (!mFabIsShown) {
ViewPropertyAnimator.animate(mFab).cancel();
ViewPropertyAnimator.animate(mFab).scaleX(1).scaleY(1).setDuration(200).start();
mFabIsShown = true;
}
}
private void hideFab() {
if (mFabIsShown) {
ViewPropertyAnimator.animate(mFab).cancel();
ViewPropertyAnimator.animate(mFab).scaleX(0).scaleY(0).setDuration(200).start();
mFabIsShown = false;
}
}
private void setBackgroundAlpha(View view, float alpha, int baseColor) {
int a = Math.min(255, Math.max(0, (int) (alpha * 255))) << 24;
int rgb = 0x00ffffff & baseColor;
view.setBackgroundColor(a + rgb);
}
}