boss直聘Android找工作界面,仿Boss直聘我的界面滑动效果

好久没有写博客了,最近在找工作,我在使用boss投简历的时候,看到boss的我的界面蛮有意思的,就想如何去实现它,可能是职业病吧,所以就打算仿一下。先看下仿的效果。

其实我们拿到这个效果的时候,看到滑动,折叠等效果就应该想到了Material design,那么我们现在就可以基本的布局下。

activity_main.xml布局

layout_top_view.xml

layout_content.xml   这里就是一个图片 截取Boss的

上面的activity_main.xml中可以看到 我自定义了一个AppBarLayout的behavior, AppBarLayoutOverScrollViewBehavior 其实所有的效果都是这这里去实现的。

AppBarLayoutOverScrollViewBehavior

package com.zwl.mybossdemo;

import android.animation.ValueAnimator;

import android.content.Context;

import android.util.AttributeSet;

import android.view.View;

import androidx.coordinatorlayout.widget.CoordinatorLayout;

import com.google.android.material.appbar.AppBarLayout;

public class AppBarLayoutOverScrollViewBehavior extends AppBarLayout.Behavior {

private int mAppBarHeight;

private View mCardView;

private boolean isAnimate;

private float mTotalDy;

private float mLastScale;

private int mLastBottom;

private int mCardViewHeight;

private int mLimitHeight;

private ValueAnimator recoveryValueAnimator;

private View mToolBar;

private float scaleValue = 2f / 3;// 显示卡片的三分之一 所以抛出三分之二

private View mNameTitle;

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

if (null == mCardView) {

mCardView = parent.findViewById(R.id.cardview);

}

if (null == mToolBar) {

mToolBar = parent.findViewById(R.id.toolbar);

}

if (null == mNameTitle) {

mNameTitle = parent.findViewById(R.id.name);

}

init(abl);

return handled;

}

@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, int type) {

super.onStopNestedScroll(coordinatorLayout, abl, target, type);

//恢复位置

if (abl.getBottom() > mLimitHeight) {

recovery(abl);

}

}

@Override

public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) {

//开始滚动了 就动画归位

isAnimate = true;

return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type);

}

@Override

public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {

if (mCardView != null && ((dy <= 0 && child.getBottom() >= mLimitHeight) || (dy > 0 && child.getBottom() > mLimitHeight))) {

scrollY(child, target, dy);

} else {

setViewAlpha(child, dy);

super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);

}

}

/**

* 初始化数据

*

* @param appBarLayout

*/

private void init(final AppBarLayout appBarLayout) {

appBarLayout.setClipChildren(false);

//整个AppbarLayout高度

mAppBarHeight = appBarLayout.getMeasuredHeight();

//卡片的高度

mCardViewHeight = mCardView.getMeasuredHeight();

//折叠正常的高度

mLimitHeight = mAppBarHeight - (int) (mCardViewHeight * scaleValue);

//默认1s折叠

appBarLayout.postDelayed(new Runnable() {

@Override

public void run() {

ValueAnimator anim = ValueAnimator.ofFloat(0, 1f).setDuration(200);

anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float value = (float) animation.getAnimatedValue();

appBarLayout.setBottom((int) (mAppBarHeight - value * mCardViewHeight * scaleValue));

}

});

anim.start();

}

}, 1000);

}

/**

* 混动

*

* @param child

* @param target

* @param dy

*/

private void scrollY(AppBarLayout child, View target, int dy) {

mTotalDy += -dy;

mTotalDy = Math.min(mTotalDy, mLimitHeight);

mLastScale = Math.max(1f, 1f + (mTotalDy / mLimitHeight));

mLastBottom = mLimitHeight + (int) (mCardViewHeight * scaleValue * (mLastScale - 1));

child.setBottom(mLastBottom);

target.setScrollY(0);

}

/**

* 根据滑动设置 toolbar 名字显示效果

*

* @param target

* @param dy

*/

private void setViewAlpha(View target, int dy) {

float percent = Math.abs(target.getY() / mLimitHeight);

if (percent >= 1) {

percent = 1f;

}

//设置toolbar的透明度

mToolBar.setAlpha(percent);

//设置名字缩放

mNameTitle.setScaleX(Math.max(0.8f, 1 - percent));

mNameTitle.setScaleY(Math.max(0.8f, 1 - percent));

//设置名字平移

int offset = mNameTitle.getTop() - mToolBar.getTop();

mNameTitle.setTranslationY(-offset * percent);

}

/**

* 恢复位置

*

* @param abl

*/

private void recovery(final AppBarLayout abl) {

if (mTotalDy >= 0) {

mTotalDy = 0;

if (isAnimate) {

recoveryValueAnimator = ValueAnimator.ofFloat(0, 1f).setDuration(200);

recoveryValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float value = (float) animation.getAnimatedValue();

int offsetY = abl.getBottom() - mLimitHeight;

abl.setBottom((int) (abl.getBottom() - (value * offsetY)));

abl.setScrollY(0);

}

});

recoveryValueAnimator.start();

} else {

abl.setBottom(mLimitHeight);

abl.setScrollY(0);

}

}

}

}

其实代码很简单 ,所以就不在讲解了,主要就是通过监听滑动距离来设置空间的属性,这里附上github链接,可以直接下再看下。

github项目

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值