图片位移缩小到标题栏

202303_ei4t_3407708.png

202327_9uv9_3407708.png

为了这个我纠结好好久好久,废话不多说 直接上代码

其实只需要两个java类和一个xml布局

首先在main的xml

<?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>

下面是AvatarImageBehavior

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);
    }
}

这样就完成了

至于左上角github上有很多例子。这是往正中间位移。

转载于:https://my.oschina.net/u/3407708/blog/887899

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值