前言
如你所见,本专栏的名称叫做《把苹果抄的裤衩子都不剩》
。
本文是其专栏系列的第一篇 。
为什么要写这个系列
究其原因,可以说有两个:
首先,实现这些炫酷的效果,可以锻炼自己的编程能力。
其次,苹果的这些炫酷效果让我眼前一新,我想用到自己的项目中。
引
我一直想打造一款音乐播放器。
为此,我实际体验了4天我的竞品—<Apple Music>
初入Apple Music,只觉得页面好土,一点炫酷的感觉也没有,加之黑色的状态栏,给我留下了不好的印象。
随着实际体验的增加,我发现了的确值得学习的效果。
本文实现的就是其标题所说的视错觉。
语言难以描述,让我们一起看图
思路
先看一下布局:
两个View,分别是图中下面的TextView和上面的TextView,我们叫它们为tv1和tv2
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设置透明度的地方
});
我们的效果
结
欢迎各位关注本专栏,本专栏将会持续更新
如果各位有什么想法,可以在评论区留言
下期预告
实现<Apple Music>中播放页面的流光溢彩效果