This repository has been archived by the owner on Jul 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 246
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Connection Status: Added Network Broadcast Receiver
Fixes #312
- Loading branch information
1 parent
a4374c1
commit bf9b221
Showing
4 changed files
with
207 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
app/src/main/java/com/zulip/android/util/RemoveFabOnScroll.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
package com.zulip.android.util; | ||
|
||
import android.animation.Animator; | ||
import android.annotation.SuppressLint; | ||
import android.content.Context; | ||
import android.support.design.widget.AppBarLayout; | ||
import android.support.design.widget.CoordinatorLayout; | ||
import android.support.design.widget.FloatingActionButton; | ||
import android.support.design.widget.Snackbar; | ||
import android.support.v4.view.ViewCompat; | ||
import android.support.v4.view.animation.FastOutSlowInInterpolator; | ||
import android.util.AttributeSet; | ||
import android.util.TypedValue; | ||
import android.view.View; | ||
import android.view.ViewPropertyAnimator; | ||
import android.view.animation.Interpolator; | ||
|
||
import com.zulip.android.R; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* This hides the {@link AppBarLayout} and {@link android.support.design.widget.FloatingActionButton} when the | ||
* recyclerView is scrolled, used in here {@link com.zulip.android.R.layout#main} as a behaviour. | ||
*/ | ||
public class RemoveFabOnScroll extends CoordinatorLayout.Behavior<FloatingActionButton> { | ||
private static final Interpolator FAST_OUT_SLOW_IN_INTERPOLATOR = new FastOutSlowInInterpolator(); | ||
private static float toolbarHeight; | ||
private int changeInYDir; | ||
private boolean mIsShowing; | ||
private boolean isViewHidden; | ||
private View chatBox; | ||
|
||
public RemoveFabOnScroll(Context context, AttributeSet attrs) { | ||
super(context, attrs); | ||
TypedValue tv = new TypedValue(); | ||
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) | ||
toolbarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics()); | ||
} | ||
|
||
@Override | ||
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) { | ||
return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0; | ||
} | ||
|
||
@SuppressLint("NewApi") | ||
@Override | ||
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dx, int dy, int[] consumed) { | ||
if (dy > 0 && changeInYDir < 0 || dy < 0 && changeInYDir > 0) { | ||
child.animate().cancel(); | ||
changeInYDir = 0; | ||
} | ||
|
||
changeInYDir += dy; | ||
if (changeInYDir > toolbarHeight && child.getVisibility() == View.VISIBLE && !isViewHidden) | ||
hideView(child); | ||
else if (changeInYDir < 0 && child.getVisibility() == View.GONE && !mIsShowing) { | ||
if (child instanceof FloatingActionButton) { | ||
if (chatBox == null) | ||
chatBox = coordinatorLayout.findViewById(R.id.messageBoxContainer); | ||
if (chatBox.getVisibility() == View.VISIBLE) { | ||
return; | ||
} | ||
} | ||
showView(child); | ||
} | ||
|
||
} | ||
|
||
@SuppressLint("NewApi") | ||
private void hideView(final View view) { | ||
isViewHidden = true; | ||
ViewPropertyAnimator animator = view.animate() | ||
.translationY((view instanceof AppBarLayout) ? -1 * view.getHeight() : view.getHeight()) | ||
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR) | ||
.setDuration(200); | ||
|
||
animator.setListener(new Animator.AnimatorListener() { | ||
@Override | ||
public void onAnimationStart(Animator animator) { | ||
} | ||
|
||
@Override | ||
public void onAnimationEnd(Animator animator) { | ||
isViewHidden = false; | ||
view.setVisibility(View.GONE); | ||
} | ||
|
||
@Override | ||
public void onAnimationCancel(Animator animator) { | ||
isViewHidden = false; | ||
if (!mIsShowing) | ||
showView(view); | ||
} | ||
|
||
@Override | ||
public void onAnimationRepeat(Animator animator) { | ||
} | ||
}); | ||
animator.start(); | ||
} | ||
|
||
@SuppressLint("NewApi") | ||
private void showView(final View view) { | ||
mIsShowing = true; | ||
ViewPropertyAnimator animator = view.animate() | ||
.translationY(0) | ||
.setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR) | ||
.setDuration(200); | ||
|
||
animator.setListener(new Animator.AnimatorListener() { | ||
@Override | ||
public void onAnimationStart(Animator animator) { | ||
view.setVisibility(View.VISIBLE); | ||
} | ||
|
||
@Override | ||
public void onAnimationEnd(Animator animator) { | ||
mIsShowing = false; | ||
} | ||
|
||
@Override | ||
public void onAnimationCancel(Animator animator) { | ||
mIsShowing = false; | ||
if (!isViewHidden) | ||
hideView(view); | ||
} | ||
|
||
@Override | ||
public void onAnimationRepeat(Animator animator) { | ||
} | ||
}); | ||
animator.start(); | ||
} | ||
|
||
@Override | ||
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) { | ||
return dependency instanceof Snackbar.SnackbarLayout; | ||
} | ||
|
||
@Override | ||
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) { | ||
float translationY = getFabTranslationYForSnackbar(parent, child); | ||
float percentComplete = -translationY / dependency.getHeight(); | ||
float scaleFactor = 1 - percentComplete; | ||
|
||
child.setScaleX(scaleFactor); | ||
child.setScaleY(scaleFactor); | ||
return false; | ||
} | ||
|
||
private float getFabTranslationYForSnackbar(CoordinatorLayout parent, | ||
FloatingActionButton fab) { | ||
float minOffset = 0; | ||
final List<View> dependencies = parent.getDependencies(fab); | ||
for (int i = 0, z = dependencies.size(); i < z; i++) { | ||
final View view = dependencies.get(i); | ||
if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(fab, view)) { | ||
minOffset = Math.min(minOffset, | ||
ViewCompat.getTranslationY(view) - view.getHeight()); | ||
} | ||
} | ||
|
||
return minOffset; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters