仿Boss直聘我的界面滑动效果

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

  

 

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

activity_main.xml布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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">
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        app:layout_behavior="com.zwl.mybossdemo.AppBarLayoutOverScrollViewBehavior">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/mCollapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <include
                android:id="@+id/topview"
                layout="@layout/layout_top_view"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.9" />
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>
    <include layout="@layout/layout_content" />
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="30dp"
        android:elevation="5dp"
        android:gravity="center"
        android:text="大白"
        android:textColor="@android:color/white"
        android:textSize="28sp"
        android:textStyle="bold"
        android:typeface="monospace" />
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:alpha="0"
        android:background="@color/colorAccent"
        app:layout_collapseMode="pin" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> 

layout_top_view.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
    android:background="@color/colorAccent"
    android:orientation="vertical"
    android:paddingTop="40dp"
    app:layout_collapseMode="parallax">
    <RelativeLayout
        android:id="@+id/top_view_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/top_view">
        <TextView
            android:id="@+id/jianli"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/name"
            android:layout_marginLeft="30dp"
            android:paddingTop="35dp"
            android:paddingBottom="15dp"
            android:text="我的在线简历 "
            android:textColor="@android:color/white" />
        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/me_icon"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentRight="true"
            android:layout_marginRight="30dp"
            android:layout_marginBottom="10dp"
            android:src="@drawable/boss_avatar_7" />
    </RelativeLayout>
    <LinearLayout
        android:id="@+id/top_view"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:layout_alignParentBottom="true"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:padding="15dp">
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="301\n沟通过"
            android:textColor="@android:color/white"
            android:textSize="16sp" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="301\n沟通过"
            android:textColor="@android:color/white"
            android:textSize="16sp" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="301\n沟通过"
            android:textColor="@android:color/white"
            android:textSize="16sp" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:text="301\n沟通过"
            android:textColor="@android:color/white"
            android:textSize="16sp" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/cardview"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal|bottom">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/boss_card_bg" />
    </LinearLayout>
</LinearLayout>

 

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

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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:background="@android:color/white"
    android:clickable="true"
    android:scrollbars="none"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/boss_user_bottom" />

</androidx.core.widget.NestedScrollView>

 

 上面的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项目

展开阅读全文

丑小鸭历险记——趣味玩转unity2d游戏开发(下)

10-17
故事简介 丑小鸭生来就很丑,谁都不喜欢它,从小被其他鸭子欺负。它无奈离开了妈妈,拿上一把猎枪,独自流浪,风餐露宿。每当遇到各种怪物而子弹不够用时,丑小鸭只能通过自己的血肉之躯踩死怪物。路上只能靠水果和蔬菜维持体力,无聊时也能抬头数星星。翻山越岭,逢水架桥,勇闯空中栈道和独木桥,踩过蹦床,躲过电锯,钻过加农炮,坐过火箭,穿过枪林弹雨,在极度艰苦的条件下大战终极BOSS。最终,丑小鸭占领了一座豪华城堡,里面住着它心仪的白富美(其实也是个丑小鸭),它在夜色降临之前,轻轻关上门,打开灯,结束了流浪生涯,此时天空绽放绚烂的烟花,拉开幸福生活的序幕...... 这个故事告诉我们:只要你肯奋斗,我命由我不由天 时长 课程分为上下两部,共64节课(21.1小时) 其中,上部29节课(8.5小时),下部35节课(12.6小时) 课程特色 对初学者友好,初次遇到新技术会详细讲解 全程播,坚决不在播外偷偷修改 展示所有细节,手把手教学 游戏元素完整丰富,共3张地图18个关卡 代码和文档开源,github托管地址 https://github.com/sailings/DuckAdventure 完善的售后支持 涵盖实战中常用的知识点 Physics,刚体,碰撞,弹簧体 Mecanim,动画状态机,动画融合,动画层 Animation,动画编辑与录制 单例模式 协程 Dotween 粒子特效 射线检测 键盘和移动端输入 Cinemachine相机跟随,Confiner扩展 UGUI常见控件,HUD 屏幕自适应 地图与关卡解锁 关卡滑动 背景滚动 子弹轨迹计算 音效管理 场景编辑 数据及上下文存储 大纲 丑小鸭历险记——趣味玩转unity2d游戏开发(下)   1.背景设置原理解析 2.背景设置以及云彩,山,树的滚动 3.游戏状态菜单 4.暂停、恢复、重新开始 5.主菜单的状态切换,地图选择 6.地图解锁 7.关卡列表展示 8.关卡列表左右滑动 9.关卡进入,解锁,关卡的最佳成绩设置 10.通关界面UI设计以及显示 11.通关界面的数值更新、加载下一关 12.通关界面动画效果 13.移动端输入控制 14.音效(上) 15.音效(下) 16.场景整理与规划,总分计算,地形编辑 17.关卡W1-1(丛林) 18.关卡W1-2 19.关卡W1-3 20.关卡W1-4 21.关卡W1-5 22.关卡W1-6 23.关卡W1-7 24.关卡W1-8 25.关卡W1-9 26.关卡W1-10 27.关卡W1-11 28.关卡W1-12 29.关卡W2-1(荒漠) 30.关卡W2-2 31.关卡W2-3 32.关卡W3-1(冰雪) 33.关卡W3-2 34.关卡W3-3 35.游戏打包、课程总结

Windows版YOLOv4目标检测实战:训练自己的数据集

04-26
©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值