package com.joker.rxweather.ui;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPropertyAnimatorListener;
import android.support.v4.view.animation.FastOutLinearInInterpolator;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.joker.rxweather.common.Constants;
/**
* Created by Joker on 2015/11/5.
*/
@CoordinatorLayout.DefaultBehavior(ForkView.Behavior.class) public class ForkView extends TextView {
private static final String TAG = ForkView.class.getSimpleName();
public ForkView(Context context) {
super(context);
}
public ForkView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ForkView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (ForkView.this.getY() == 0 && ForkView.this.getVisibility() != GONE) {
ViewCompat.setY(ForkView.this, ForkView.calculateTranslation(ForkView.this));
ForkView.this.setVisibility(GONE);
}
}
@Override public Parcelable onSaveInstanceState() {
SavedState savedState = new SavedState(super.onSaveInstanceState());
savedState.stateToSave = ForkView.this.getTranslationY();
return savedState;
}
@Override public void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
ForkView.this.setTranslationY(savedState.stateToSave);
}
static class SavedState extends BaseSavedState {
private float stateToSave;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
this.stateToSave = in.readFloat();
}
@Override public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeFloat(this.stateToSave);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
public static class Behavior extends android.support.design.widget.CoordinatorLayout.Behavior<ForkView> {
private boolean isOuting;
public Behavior() {
}
@Override public boolean layoutDependsOn(CoordinatorLayout parent, ForkView child, View dependency) {
return dependency instanceof AppBarLayout;
}
@Override public boolean onDependentViewChanged(CoordinatorLayout parent, ForkView child, View dependency) {
if (dependency instanceof AppBarLayout) {
Behavior.this.updateVisibility(parent, (AppBarLayout) dependency, child);
}
return false;
}
private boolean updateVisibility(CoordinatorLayout parent, AppBarLayout appBarLayout, ForkView child) {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
if (layoutParams.getAnchorId() != appBarLayout.getId()) {
return false;
}
int distanceToScroll = ForkView.calculateTranslation(child);
/*other animation......*/
//ViewCompat.setTranslationY(child, Math.abs(y) - distanceToScroll);
if (Math.abs(appBarLayout.getY()) >= getMinimumHeightForVisibleOverlappingContent(appBarLayout)) {
if (child.getVisibility() != VISIBLE) {
this.animateIn(child, distanceToScroll);
}
} else {
if (!Behavior.this.isOuting && child.getVisibility() == View.VISIBLE) {
this.animateOut(child, -distanceToScroll);
}
}
return true;
}
final int getMinimumHeightForVisibleOverlappingContent(AppBarLayout appBarLayout) {
int topInset = 0;
int minHeight = ViewCompat.getMinimumHeight(appBarLayout);
if (minHeight != 0) {
return minHeight * 2 + topInset;
} else {
int childCount = appBarLayout.getChildCount();
return childCount >= 1 ? ViewCompat.getMinimumHeight(appBarLayout.getChildAt(childCount - 1)) * 2 + topInset
: 0;
}
/* try {
Method method =
AppBarLayout.class.getDeclaredMethod("getMinimumHeightForVisibleOverlappingContent");
method.setAccessible(true);
method.invoke(appBarLayout);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}*/
}
private void animateIn(ForkView child, float distanceToScroll) {
child.setVisibility(VISIBLE);
ViewCompat
.animate(child)
.alpha(1.0f)
.translationY(distanceToScroll)
.setDuration(Constants.MILLISECONDS_400)
.setInterpolator(new FastOutSlowInInterpolator())
.withLayer()
.setListener(null);
}
private void animateOut(final ForkView child, float distanceToScroll) {
ViewCompat
.animate(child)
.alpha(0.4f)
.translationY(distanceToScroll)
.setDuration(Constants.MILLISECONDS_400)
.setInterpolator(new FastOutLinearInInterpolator())
.withLayer()
.setListener(new ViewPropertyAnimatorListener() {
public void onAnimationStart(View view) {
Behavior.this.isOuting = true;
}
public void onAnimationCancel(View view) {
Behavior.this.isOuting = false;
}
public void onAnimationEnd(View view) {
Behavior.this.isOuting = false;
view.setVisibility(View.GONE);
}
});
}
}
private static int calculateTranslation(View view) {
int height = view.getHeight();
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
int margins = params.topMargin + params.bottomMargin;
return height + margins;
}
}