Last active
April 4, 2024 12:13
-
-
Save zly394/6387f735d4161c625a06f5595c5cb8cd to your computer and use it in GitHub Desktop.
Overscroll AppBarLayout Behavior—— AppBarLayout越界弹性效果
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
<?xml version="1.0" encoding="utf-8"?> | |
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:fitsSystemWindows="true"> | |
<android.support.design.widget.AppBarLayout | |
android:id="@+id/appbar" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:fitsSystemWindows="true" | |
android:theme="@style/AppTheme.AppBarOverlay" | |
android:transitionName="picture" | |
app:layout_behavior="com.zly.exifviewer.widget.behavior.AppBarLayoutOverScrollViewBehavior" | |
tools:targetApi="lollipop"> | |
<android.support.design.widget.CollapsingToolbarLayout | |
android:id="@+id/collapsingToolbarLayout" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
app:contentScrim="@color/colorPrimary" | |
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" | |
app:statusBarScrim="@color/colorPrimaryDark"> | |
<ImageView | |
android:id="@+id/siv_picture" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:fitsSystemWindows="true" | |
android:foreground="@drawable/shape_fg_picture" | |
android:scaleType="centerCrop" | |
android:tag="overScroll" | |
app:layout_collapseMode="parallax" | |
tools:src="@android:drawable/sym_def_app_icon" /> | |
<android.support.v7.widget.Toolbar | |
android:id="@+id/toolbar" | |
android:layout_width="match_parent" | |
android:layout_height="?attr/actionBarSize" | |
app:contentInsetEnd="64dp" | |
app:layout_collapseMode="pin" | |
app:popupTheme="@style/AppTheme.PopupOverlay" /> | |
</android.support.design.widget.CollapsingToolbarLayout> | |
</android.support.design.widget.AppBarLayout> | |
<android.support.v4.widget.NestedScrollView | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
app:layout_behavior="@string/appbar_scrolling_view_behavior"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="vertical"> | |
<ImageView | |
android:layout_width="match_parent" | |
android:layout_height="200dp" | |
android:src="@mipmap/ic_launcher" /> | |
<ImageView | |
android:layout_width="match_parent" | |
android:layout_height="200dp" | |
android:src="@mipmap/ic_launcher" /> | |
<ImageView | |
android:layout_width="match_parent" | |
android:layout_height="200dp" | |
android:src="@mipmap/ic_launcher" /> | |
<ImageView | |
android:layout_width="match_parent" | |
android:layout_height="200dp" | |
android:src="@mipmap/ic_launcher" /> | |
<ImageView | |
android:layout_width="match_parent" | |
android:layout_height="200dp" | |
android:src="@mipmap/ic_launcher" /> | |
</LinearLayout> | |
</android.support.v4.widget.NestedScrollView> | |
<android.support.design.widget.FloatingActionButton | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="bottom|end" | |
android:layout_marginBottom="16dp" | |
android:layout_marginEnd="16dp" | |
android:clickable="true" | |
android:src="@drawable/ic_edit" /> | |
</android.support.design.widget.CoordinatorLayout> |
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
package com.zly.widget.behavior; | |
import android.animation.ValueAnimator; | |
import android.content.Context; | |
import android.support.design.widget.AppBarLayout; | |
import android.support.design.widget.CoordinatorLayout; | |
import android.support.v4.view.ViewCompat; | |
import android.util.AttributeSet; | |
import android.view.View; | |
/** | |
* Created by zhuleiyue on 2017/3/7. | |
*/ | |
public class AppBarLayoutOverScrollViewBehavior extends AppBarLayout.Behavior { | |
private static final String TAG = "overScroll"; | |
private static final float TARGET_HEIGHT = 500; | |
private View mTargetView; | |
private int mParentHeight; | |
private int mTargetViewHeight; | |
private float mTotalDy; | |
private float mLastScale; | |
private int mLastBottom; | |
private boolean isAnimate; | |
public AppBarLayoutOverScrollViewBehavior() { | |
} | |
public AppBarLayoutOverScrollViewBehavior(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
} | |
@Override | |
public boolean onLayoutChild(CoordinatorLayout parent, AppBarLayout abl, int layoutDirection) { | |
boolean handled = super.onLayoutChild(parent, abl, layoutDirection); | |
// 需要在调用过super.onLayoutChild()方法之后获取 | |
if (mTargetView == null) { | |
mTargetView = parent.findViewWithTag(TAG); | |
if (mTargetView != null) { | |
initial(abl); | |
} | |
} | |
return handled; | |
} | |
@Override | |
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) { | |
isAnimate = true; | |
return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes); | |
} | |
@Override | |
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) { | |
if (mTargetView != null && ((dy < 0 && child.getBottom() >= mParentHeight) || (dy > 0 && child.getBottom() > mParentHeight))) { | |
scale(child, target, dy); | |
} else { | |
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); | |
} | |
} | |
@Override | |
public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY) { | |
if (velocityY > 100) { | |
isAnimate = false; | |
} | |
return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY); | |
} | |
@Override | |
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout abl, View target) { | |
recovery(abl); | |
super.onStopNestedScroll(coordinatorLayout, abl, target); | |
} | |
private void initial(AppBarLayout abl) { | |
abl.setClipChildren(false); | |
mParentHeight = abl.getHeight(); | |
mTargetViewHeight = mTargetView.getHeight(); | |
} | |
private void scale(AppBarLayout abl, View target, int dy) { | |
mTotalDy += -dy; | |
mTotalDy = Math.min(mTotalDy, TARGET_HEIGHT); | |
mLastScale = Math.max(1f, 1f + mTotalDy / TARGET_HEIGHT); | |
ViewCompat.setScaleX(mTargetView, mLastScale); | |
ViewCompat.setScaleY(mTargetView, mLastScale); | |
mLastBottom = mParentHeight + (int) (mTargetViewHeight / 2 * (mLastScale - 1)); | |
abl.setBottom(mLastBottom); | |
target.setScrollY(0); | |
} | |
private void recovery(final AppBarLayout abl) { | |
if (mTotalDy > 0) { | |
mTotalDy = 0; | |
if (isAnimate) { | |
ValueAnimator anim = ValueAnimator.ofFloat(mLastScale, 1f).setDuration(200); | |
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
@Override | |
public void onAnimationUpdate(ValueAnimator animation) { | |
float value = (float) animation.getAnimatedValue(); | |
ViewCompat.setScaleX(mTargetView, value); | |
ViewCompat.setScaleY(mTargetView, value); | |
abl.setBottom((int) (mLastBottom - (mLastBottom - mParentHeight) * animation.getAnimatedFraction())); | |
} | |
}); | |
anim.start(); | |
} else { | |
ViewCompat.setScaleX(mTargetView, 1f); | |
ViewCompat.setScaleY(mTargetView, 1f); | |
abl.setBottom(mParentHeight); | |
} | |
} | |
} | |
} |
great
This is fantastic!!!!!
onStartNestedScroll、onNestedPreScroll、onStopNestedScroll was outdated, to lead the behavior was invalid,use the newest function was ok;
of me; thanks for your behavior;
i've updated it against androidx https://gist.github.com/kibotu/c1266c067543693c32d81eb5bcdcc5b2
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
that is what i want , and wonderful