android高仿今日头条小视频转场切换效果

可以先看看今日头条效果

功能分析

点击列表上的一个item,该item会放大,最后直接全屏播放小视频,刚开始看上去,以为是个共享元素的转场动画, 后来想到,共享元素要在android 5.0以上支持,而今日头条显然不会只支持5.0版本以上

笔者想到的一种方案就是进入Activity之后,在onCreate的生命周期回调,,计算缩放的动画参数,思路如下

1.点击列表上的item,获取该view的屏幕位置信息,立即传入进入目标比如VideoPlayAcitvity中 2.在VideoPlayAcitvityonCreate生命周期方法中获取点击的view相关位置信息,进行动画播放

看上去也不难,但实际有几个问题,第一步需要设置VideoPlayAcitvity透明,并且去掉转场动画

功能使用

transitionController = new TransitionController.Builder()
        .with(findViewById(R.id.main_root_layer))
        //今日头条默认参数
        .setInterpolator(PathInterpolatorCompat.create(0.32F, 0.94F, 0.6F, 1.0F))
        .duration(320)
        .build();
transitionController.transitionEnter(targetAnimBean, new TransitionCallback() {
    @Override
    public void onTransitionStop() {
        //显示小视频界面评论等控件
    }
});
复制代码

来看看实际效果:

功能实现

给出部分关键的逻辑

/**
 * 进入和退出的动画
 * @param enterAnimation 是否入场动画
 * @param animatorListener 监听动画回调
 */
private void transitionStart(boolean enterAnimation, Animator.AnimatorListener animatorListener) {
    //标识我们点击的View在屏幕中可见的高度
    int visibleHeight = transitionParam.bottom - transitionParam.top;

    //计算缩放的宽和高起点,需要和外部的控件宽高看起来一致才比较细腻
    float scaleXStart = (float) transitionParam.width / targetWidth;
    float scaleYStart = (float) transitionParam.height / targetHeight;

    animView.setPivotX(0);
    animView.setPivotY(0);

    int startTransX = transitionParam.left;
    int startTransY;
    if (transitionParam.bottom == targetHeight) {
        //滑动到屏幕底部去了,这时候以点击的控件顶部为位移起始点
        startTransY = transitionParam.top;
    } else if (visibleHeight < transitionParam.height) {
        //滑动到屏幕顶部去了
        startTransY = transitionParam.bottom - transitionParam.height;
    } else {
        startTransY = transitionParam.top;
    }

    if (enterAnimation) {
        //显示动画设置移动的起始位置,关闭动画只指定目标位移位置
        animView.setTranslationX(startTransX);
        animView.setTranslationY(startTransY);
    }

    //设置缩放点
    animView.setScaleX(enterAnimation ? scaleXStart : 1.0F);
    animView.setScaleY(enterAnimation ? scaleYStart : 1.0F);

    viewAnimator = animView.animate();
    //头条参数
    viewAnimator.setInterpolator(timeInterpolator);
    animView.setVisibility(View.VISIBLE);
    viewAnimator.setDuration(duration)
            .setListener(animatorListener)
            .scaleX(enterAnimation ? 1.0F : scaleXStart)
            .scaleY(enterAnimation ? 1.0F : scaleYStart)
            .translationX(enterAnimation ? 0.0F : startTransX)
            .translationY(enterAnimation ? 0.0F : startTransY)
            .start();
}
复制代码

手势滑动

手势滑动主要也是拦截触摸事件,计算移动的距离,根据手指移动的距离,等比的缩放指定的容器 目前实现较为简单,待后续会更新

项目地址

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值