爲了這個我糾結好很久很久,廢話很少說 直接上代碼java
其實只須要兩個java類和一個xml佈局android
首先在main的xmlgit
<?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" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_tool_bar" android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="@color/bar_orange" app:expandedTitleGravity="bottom|center_horizontal" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> <ImageView android:id="@+id/iv_head" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/info_img_pic" app:layout_collapseMode="parallax" app:layout_collapseParallaxMultiplier="0.6" /> <!-- 設置app:navigationIcon="@android:color/transparent"給頭像預留位置 --> <android.support.v7.widget.Toolbar android:id="@+id/tool_bar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/bar_orange" app:theme="@style/ThemeOverlay.AppCompat.Dark"> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="match_parent"> <ImageView android:layout_gravity="center" android:id="@+id/main.textview.title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="left" android:background="@drawable/tab_btn_eyes" /> </LinearLayout> </android.support.v7.widget.Toolbar> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <include layout="@layout/fragment_home_layout_liao" /> 這個是下面的一個 </android.support.v4.widget.NestedScrollView> <!-- layout_anchor屬性5.0以上須要設置爲CollapsingToolbarLayout,否則頭像最後會被覆蓋 --> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/cl_home_xtx" android:layout_width="100dp" android:layout_height="100dp" android:layout_margin="16dp" android:src="@drawable/common_img_user" app:border_color="@android:color/white" app:border_width="1dp" app:layout_anchor="@id/collapsing_tool_bar" app:layout_anchorGravity="center_vertical|center_horizontal|" app:layout_behavior="lib.view.touxiang.AvatarImageBehavior" />這一行很重要 </android.support.design.widget.CoordinatorLayout>
下面是AvatarImageBehaviorgithub
package lib.view.touxiang; import android.content.Context; import android.content.res.TypedArray; import android.os.Build; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.CoordinatorLayout; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import de.hdodenhof.circleimageview.CircleImageView; /** * Created by lsy on 2017/4/25. */ public class AvatarImageBehavior extends CoordinatorLayout.Behavior<CircleImageView> { // 縮放動畫變化的支點 private static final float ANIM_CHANGE_POINT = 0.2f; private Context mContext; // 整個滾動的範圍 private int mTotalScrollRange; // AppBarLayout高度 private int mAppBarHeight; // AppBarLayout寬度 private int mAppBarWidth; // 控件原始大小 private int mOriginalSize; // 控件最終大小 private int mFinalSize; // 控件最終縮放的尺寸,設置座標值須要算上該值 private float mScaleSize; // 原始x座標 private float mOriginalX; // 最終x座標 private float mFinalX; // 起始y座標 private float mOriginalY; // 最終y座標 private float mFinalY; // ToolBar高度 private int mToolBarHeight; // AppBar的起始Y座標 private float mAppBarStartY; // 滾動執行百分比[0~1] private float mPercent; // Y軸移動插值器 private DecelerateInterpolator mMoveYInterpolator; // X軸移動插值器 private AccelerateInterpolator mMoveXInterpolator; // 最終變換的視圖,由於在5.0以上AppBarLayout在收縮到最終狀態會覆蓋變換後的視圖,因此添加一個最終顯示的圖片 private CircleImageView mFinalView; // 最終變換的視圖離底部的大小 private int mFinalViewMarginBottom; public AvatarImageBehavior(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mMoveYInterpolator = new DecelerateInterpolator(); mMoveXInterpolator = new AccelerateInterpolator(); } @Override public boolean layoutDependsOn(CoordinatorLayout parent, CircleImageView child, View dependency) { return dependency instanceof AppBarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, CircleImageView child, View dependency) { if (dependency instanceof AppBarLayout) { _initVariables(child, dependency); mPercent = (mAppBarStartY - dependency.getY()) * 1.0f / mTotalScrollRange; Log.e("ff", "appnarStart: " + mAppBarStartY + "dependey: " + dependency.getY() + " prencernt: " + mPercent); float percentY = mMoveYInterpolator.getInterpolation(mPercent); AnimHelper.setViewY(child, mOriginalY, mFinalY - mScaleSize, percentY); if (mPercent > ANIM_CHANGE_POINT) { float scalePercent = (mPercent - ANIM_CHANGE_POINT) / (1 - ANIM_CHANGE_POINT); float percentX = mMoveXInterpolator.getInterpolation(scalePercent); AnimHelper.scaleView(child, mOriginalSize, mFinalSize, scalePercent); AnimHelper.setViewX(child, mOriginalX, mFinalX - mScaleSize, percentX); } else { AnimHelper.scaleView(child, mOriginalSize, mFinalSize, 0); AnimHelper.setViewX(child, mOriginalX, mFinalX - mScaleSize, 0); } if (mFinalView != null) { if (percentY == 1.0f) { // 滾動到頂時才顯示 mFinalView.setVisibility(View.VISIBLE); } else { mFinalView.setVisibility(View.GONE); } } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && dependency instanceof CollapsingToolbarLayout) { // 大於5.0才生成新的最終的頭像,由於5.0以上AppBarLayout會覆蓋變換後的頭像 if (mFinalView == null && mFinalSize != 0 && mFinalX != 0) { mFinalView = new CircleImageView(mContext); mFinalView.setVisibility(View.GONE); // 添加爲CollapsingToolbarLayout子視圖 ((CollapsingToolbarLayout) dependency).addView(mFinalView); FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mFinalView.getLayoutParams(); // 設置大小 params.width = mFinalSize; params.height = mFinalSize; // 設置位置,最後顯示時至關於變換後的頭像位置 params.gravity = Gravity.BOTTOM; params.leftMargin = (int) mFinalX; params.bottomMargin = mFinalViewMarginBottom; mFinalView.setLayoutParams(params); mFinalView.setImageDrawable(child.getDrawable()); mFinalView.setBorderColor(child.getBorderColor()); int borderWidth = (int) ((mFinalSize * 1.0f / mOriginalSize) * child.getBorderWidth()); mFinalView.setBorderWidth(borderWidth); } } return true; } /** * 初始化變量 * * @param child * @param dependency */ private void _initVariables(CircleImageView child, View dependency) { if (mToolBarHeight == 0) { mToolBarHeight = getToolBarHeight(); } if (mFinalSize == 0) { mFinalSize = getToolBarHeight(); } if (mFinalX == 0) { mFinalX = getScreenWidth(mContext) / 2 - mFinalSize / 2; } if (mAppBarHeight == 0) { mAppBarHeight = dependency.getHeight(); mAppBarStartY = dependency.getY(); } if (mTotalScrollRange == 0) { mTotalScrollRange = ((AppBarLayout) dependency).getTotalScrollRange(); } if (mOriginalSize == 0) { mOriginalSize = child.getWidth(); } if (mFinalSize == 0) { mFinalSize = getToolBarHeight(); } if (mAppBarWidth == 0) { mAppBarWidth = dependency.getWidth(); } if (mOriginalX == 0) { mOriginalX = child.getX(); } if (mOriginalY == 0) { mOriginalY = child.getY(); } if (mFinalY == 0) { if (mToolBarHeight == 0) { mToolBarHeight = getToolBarHeight(); } mFinalY = (getToolBarHeight() - mFinalSize) / 2; } if (mScaleSize == 0) { mScaleSize = (mOriginalSize - mFinalSize) * 1.0f / 2; } if (mFinalViewMarginBottom == 0) { mFinalViewMarginBottom = (mToolBarHeight - mFinalSize) / 2; } } private int getToolBarHeight() { int[] attrs = {android.R.attr.actionBarSize}; TypedArray values = mContext.getTheme().obtainStyledAttributes(attrs); try { return values.getDimensionPixelSize(0, 0);//第一個參數數組索引,第二個參數 默認值 } finally { values.recycle(); } } public int getScreenWidth(Context mContext) { DisplayMetrics dm = mContext.getResources().getDisplayMetrics(); return dm.widthPixels; }}
AnimHelper.java數組
package lib.view.touxiang; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.view.View; import android.view.animation.AccelerateInterpolator; public class AnimHelper { private AnimHelper() { throw new RuntimeException("AnimHelper cannot be initialized!"); } public static void zoomOut(View view) { ObjectAnimator alpha = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f); ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0f); AnimatorSet set = new AnimatorSet(); set.playTogether(alpha, scaleX, scaleY); set.setDuration(300); set.setInterpolator(new AccelerateInterpolator()); set.start(); } public static void zoomIn(View view) { ObjectAnimator alpha = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f); ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 0f, 1f); ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 0f, 1f); AnimatorSet set = new AnimatorSet(); set.playTogether(alpha, scaleX, scaleY); set.setDuration(300); set.setInterpolator(new AccelerateInterpolator()); set.start(); } public static void setViewX(View view, float originalX, float finalX, float percent) { float calcX = (finalX - originalX) * percent + originalX; view.setX(calcX); } public static void setViewY(View view, float originalY, float finalY, float percent) { float calcY = (finalY - originalY) * percent + originalY; view.setY(calcY); } public static void scaleView(View view, float originalSize, float finalSize, float percent) { float calcSize = (finalSize - originalSize) * percent + originalSize; float caleScale = calcSize / originalSize; // view.setScaleType(ImageView.ScaleType.CENTER); view.setScaleX(caleScale); view.setScaleY(caleScale); } }
這樣就完成了app
至於左上角github上有不少例子。這是往正中間位移。ide