Android 3D翻转效果

admin 2022年3月14日03:06:19评论45 views字数 5935阅读19分47秒阅读模式

移动端安全开发、移动端安全、网络安全视频课程
(1).移动安全App安全检测、渗透测试、风控、隐私合规、加固防护、病毒逆向的视频课程

(2).Android系统Framework、驱动、内核等模块的定制开发和Android APP开发以及鸿蒙APP开发的视频课程

(3).网络安全漏洞挖掘、Web安全、渗透测试、病毒逆向、溯源反制等系列视频课程


以上视频课程会在近期发布,欢迎各位扫码关注"哆啦安全"公众号、视频号

Android 3D翻转效果

最近刷B站看到一个比较有意思的图片切换效果,在查看一个用户发的图片的时候是平滑过渡,如果下一张图片是另一个用户发的,则会触发一个3D翻转的效果,不止是图片翻转,连带里面的布局也会一起翻转。

话不多说、先上效果图:

Android 3D翻转效果

先分析一下这个效果由哪几部分组成:

  • 1.左右平移。
  • 2.上下翻转。

咦。。就这,就这

真就这么简单,先看第一个左右平移,这是一个很普通的ViewPager可以做到的效果,直接使用ViewPager就可以了,下面是使用ViewPager的代码:


        ViewPager vPage = findViewById(R.id.vpage);

        List<Integer> mFragments = new ArrayList<>();
        mFragments.add(R.mipmap.one);
        mFragments.add(R.mipmap.two);
        mFragments.add(R.mipmap.three);
        mFragments.add(R.mipmap.four);
        mFragments.add(R.mipmap.five);

        BliPageAdapter pageAdapter = new BliPageAdapter(this, mFragments);
        vPage.setAdapter(pageAdapter);

这样就可以实现,左右平移的效果了(ViewPager的具体使用参考别的文章或官方文档)

那第二个翻转该怎么实现呢,这才是最主要的,在效果图中可以明显看到3D的效果,那么肯定会用到Camera(非相机)来做, 那么3D效果是作用在哪个控件上呢?如果作用到ViewPager上,那么看到的画面就全部是倾斜的,如果作用到图片上,那么只有】图片倾斜,里面的内容不会倾斜,所以判断3D效果是作用在ViewPager的每一个子View上,这样的话,看到的画面是正的,但里面的内容可倾斜可不倾斜,有了这个依据,就可以开始实现了:

1.给ViewPager设置PageTransformer用来监听滑动的位置,因为3D效果会根据滑动的位置来决定倾斜的角度。
 vPage.setPageTransformer(falsenew BliPageTransformer());
BliPageTransformer 实现了ViewPager.PageTransformer接口:

public class BliPageTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {
       
    }
}
2.自定义ViewPager子View,因为要在子View的dispatchDraw中对显示的内容做3D变换效果,

我使用的是ConstraintLayout为最外层的容器,所以我自定义BliConstraintLayout继承自ConstraintLayout, 重 写dispatchDraw方法:

public class BliConstraintLayout extends ConstraintLayout 
   @Override
    protected void dispatchDraw(Canvas canvas
{
        //camera保存状态
        camera.save();
        //camera设置绕Y轴旋转角度
        camera.rotateY(rotateY);
        //将变换应用到canvas上
        camera.applyToCanvas(canvas);
        camera.getMatrix(matrix);
        if (!isLeftRotate){
            //设置靠左进行旋转
            matrix.preTranslate(- getWidth(), - getHeight() >> 1);
            matrix.postTranslate(getWidth(), getHeight() >> 1);
        } else {
            //设置靠右进行旋转
            matrix.preTranslate(0, - getHeight() >> 1);
            matrix.postTranslate(0, getHeight() >> 1);
        }
        canvas.setMatrix(matrix);
        //camera恢复状态
        camera.restore();
        super.dispatchDraw(canvas);
    }

ViewPager子View的xml文件外层容器替换成自定义的BliConstraintLayout

核心代码就在这里,Camera的用法可以参考其他博客或官方文档,

这里值得注意的是:

  • 1.camera需要保存和恢复状态,不然下一次绘制会拿到上一次改变过的状态。
  • 2.使用matrix对变换矩阵进行平移,因为默认变换都是针对坐标点(0,0)的,而上面的3D效果,需要的是x轴 靠左和靠右, y轴居中.
  • 3.这些设置都要放在 super.dispatchDraw(canvas)之前,因为在super.dispatchDraw(canvas)调用后表示界面已经开始绘制的,所以要在绘制之前给它设置成我们需要变换的样子。

在后头看看BliPageTransformer中该怎么设置根据滑动位置设置3D倾斜:

 @Override
    public void transformPage(@NonNull View page, float position) {
        BliConstraintLayout bliConstraintLayout = (BliConstraintLayout) page;
        /**
         * 倾斜度
         */

        int tiltDegree = 34;
        float v = position * tiltDegree;
        bliConstraintLayout.setRotateY(v);
        if (position > 0){
            bliConstraintLayout.setIsLeftRotate(true);
        }else{
            bliConstraintLayout.setIsLeftRotate(false);
        }
    }

先看看方法里的参数

  • page : 当前子View
  • position:先简单了解一下position:position = -1 当前显示页的上一页。position = 0 当前显示页。position = 1当前显示页的下一页。

那么在滑动到下一页的过程中position的变化就是:

0 -> -1 : 对应page为当前显示页

1 -> 0 :对应page为当前显示页的下一页

获取到对应View之后,再根据position计算对应值:

例如我设置的最大角度为34度, 那么在1->0的过程中,角度会由34 -> 0

再判断当前View是当前页,还是下一页,如果是当前页那么是相对布局的右边倾斜,如果是当前页的下一页那么应该相对布局的左边倾斜。

再将计算出的值设置到我们自定义的BliConstraintLayout 中,重绘画布。

下面就可以运行看看效果了:


Android 3D翻转效果

完美复刻,一键三连。

下面贴一下关键点完整代码:

public class BliPageTransformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {
        BliConstraintLayout bliConstraintLayout = (BliConstraintLayout) page;
        /**
         * 倾斜度
         */

        int tiltDegree = 34;
        float v = position * tiltDegree;
        bliConstraintLayout.setRotateY(v);
        if (position > 0){
            bliConstraintLayout.setIsLeftRotate(true);
        }else{
            bliConstraintLayout.setIsLeftRotate(false);
        }
    }
}
public class BliConstraintLayout extends ConstraintLayout {

    private float rotateY = 0;

    private boolean isLeftRotate = true;

    private Matrix matrix = new Matrix();

    private Camera camera = new Camera();

    public BliConstraintLayout(@NonNull Context context) {
        super(context);
    }

    public BliConstraintLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public BliConstraintLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        //camera保存状态
        camera.save();
        //camera设置绕Y轴旋转角度
        camera.rotateY(rotateY);
        //将变换应用到canvas上
        camera.applyToCanvas(canvas);
        camera.getMatrix(matrix);
        if (!isLeftRotate){
            //设置靠左进行旋转
            matrix.preTranslate(- getWidth(), - getHeight() >> 1);
            matrix.postTranslate(getWidth(), getHeight() >> 1);
        } else {
            //设置靠右进行旋转
            matrix.preTranslate(0, - getHeight() >> 1);
            matrix.postTranslate(0, getHeight() >> 1);
        }
        canvas.setMatrix(matrix);
        //camera恢复状态
        camera.restore();
        super.dispatchDraw(canvas);
    }

    public void setRotateY(float rotateY){
        this.rotateY = rotateY;
        invalidate();
    }

    public void setIsLeftRotate(boolean isLeft){
        this.isLeftRotate = isLeft;
    }
}


作者:小白彡原文:https://www.jianshu.com/p/aa6770d29376


Android 3D翻转效果


【推荐阅读】

Android10和11存储完全适配!

Android文件系统与Android11分区存储

Android11外部存储权限适配指南及方案


bundletool工具使用(Android aab包安装)

Google Play上架App之aab转apk和apk转aab的使用方法

Android App Bundle混淆加密加壳加固保护的解决方案(过Google App上架审核)


移动端过检测抓包最全解决方案


2022年岗位招聘第1期
Android Framework/驱动/内核中高级工程师


burpsuite在各场景下的抓包方法(建议收藏)


ASM插桩实现Android端无埋点性能监控

Gradle Plugin+Transform+ASM Hook并替换隐私方法调用(彻底解决隐私不合规问题)


Android 3D翻转效果

原文始发于微信公众号(哆啦安全):Android 3D翻转效果

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年3月14日03:06:19
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Android 3D翻转效果https://cn-sec.com/archives/827775.html

发表评论

匿名网友 填写信息