[安卓]实现苹果实现的效果之 视错觉标题

前言

如你所见,本专栏的名称叫做《把苹果抄的裤衩子都不剩》
本文是其专栏系列的第一篇 。

为什么要写这个系列

究其原因,可以说有两个:
首先,实现这些炫酷的效果,可以锻炼自己的编程能力。
其次,苹果的这些炫酷效果让我眼前一新,我想用到自己的项目中。

我一直想打造一款音乐播放器。
为此,我实际体验了4天我的竞品—<Apple Music>
初入Apple Music,只觉得页面好土,一点炫酷的感觉也没有,加之黑色的状态栏,给我留下了不好的印象。
随着实际体验的增加,我发现了的确值得学习的效果。
本文实现的就是其标题所说的视错觉。
语言难以描述,让我们一起看图
Apple Music的效果

思路

先看一下布局:
两个View,分别是图中下面的TextView和上面的TextView,我们叫它们为tv1tv2
tv1展示的区域变少的同时,tv2展示的区域变多。
我们只需要知道tv1当前展示的区域和完全展示时区域的百分比,记为ratio
然后我们再记录tv2完全展示时的高度,记为dstTran
最后tv2.setTranslateY(ratio*dstTran);

具体实现

如何获取到ratio
可以说整个效果的难点莫过于此了
我们知道tv1在部分遮挡的时候,其布局的大小是发生过变化的
它的大小就是展示在屏幕的部分的大小
如果我们使用getGlobalVisibleRect拿到它的位置
其获得的rect.top就是上界,即图中的分界线位置
获得的rect.bottom就是下界,即图中tv1的下边界
我们使用(rect.bottom-rect.top)/tv1的高,这样获取到的就是前文说的ratio

上代码


public class SimonEdgeIllusion {
    private final View dst;
    private final View sel;
    private int dstTran, selHeight;
    private Rect rect;
    private OnRatioChangeListener listener;
    /**
     * 初始化
     * @param dst 偏移的View
     * @param sel 滑动的View
     */
    public SimonEdgeIllusion(View dst, View sel) {
        this.dst = dst;
        this.sel = sel;
        dst.post(() -> {
            dstTran = dst.getPaddingTop() + dst.getMeasuredHeight();
            selHeight = sel.getMeasuredHeight();
            rect = new Rect();
            dst.setTranslationY(dstTran);
        });
        sel.getViewTreeObserver().addOnDrawListener(this::check);
    }

    /**
     * 主动检查并重新绘制偏移量
     */
    public void check() {
        if (rect == null) return;
        sel.getGlobalVisibleRect(rect);
        float ratio = (rect.bottom - rect.top) / (float) selHeight;
        if (ratio != 1.0) {
            dst.setTranslationY(dstTran * ratio);
            if (listener != null) listener.onRatioChange(ratio);
        } else if (rect.bottom <= 0)
            dst.setTranslationY(0);
        else
            dst.setTranslationY(dstTran);
    }

    /**
     * 设置监听器
     *
     * @param listener 监听器
     */
    public SimonEdgeIllusion setListener(OnRatioChangeListener listener){
        this.listener = listener;
        return this;
    }

    public interface OnRatioChangeListener {
        void onRatioChange(float ratio);
    }
}

使用起来十分方便

new SimonEdgeIllusion(tv2,tv1).setListener((ratio)->{
//divider设置透明度的地方
});

我们的效果

渐变可以使用ratio监听器实现

欢迎各位关注本专栏,本专栏将会持续更新
如果各位有什么想法,可以在评论区留言

下期预告

实现<Apple Music>中播放页面的流光溢彩效果

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有头发的琦玉

打点钱,我会再努力的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值