圖片位移縮小到標題欄

爲了這個我糾結好很久很久,廢話很少說 直接上代碼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

相關文章
相關標籤/搜索