酷炫效果-仿网易新闻阅读偏好效果

自定义View

Posted by ChaserSheng on October 13, 2017
二话不说,先体验一下再看文章,二维码附上

Demo下载

2017-10-20更新,对代码进行了相关优化,封装和解耦更彻底 代码传送门

前段时间看到网易的阅读偏好页面很酷炫,很好奇网易是怎么绘制这种页面的,不知道你们的第一反应是什么,我看到的第一眼就觉得是自定义view。我们来验证一下,打开开发者选项中的显示布局边界,我们看到如下图所示的界面:

wangyi.png

我们看到网易是通过组合控件实现这种效果,哈哈,感觉不一定是准确的啊。根据经验,网易的做法应该是组合控件封装相同属性,然后加上动画。虽然思路还算清晰,但是作为一个爱折腾的程序员,我们开动一下脑筋,自定义view要实现这种效果,需要怎么做呢?

看看我折腾了两天所实现的效果:

自定义SurfaceView

gif展示

效果已经很像了,下面我来讲讲我的思路:

1.首先确定用什么控件绘制(View、SurfaceView、ViewGroup):

View:适合绘制静态的对内存要求不高图像,一些简单的动画效果;

SurfaceView:适合绘制复杂的动画预览界面,交互实时性较强,对性能要求较高的界面

ViewGroup:作为父控件,一般用在需要处理子控件的位置的场景

上面是对三种控件一点简要的说明,说法不标准,大家明白意思就行。可以看出SurfaceView对于这种不听变化的动画效果做了一定的优化,性能上会更好,但是使用会相对于View复杂一些。

给出项目结构:

项目结构.png

代码貌似很多,其实我这里为了让代码看起来清晰,根据面向对象的单一职责原则细分出来的,具体的每部分的功能代码中都有注释,github地址

这里贴出来部分代码

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //此处省略部分代码...
        floatingView.setDrawerType(BaseDrawer.Type.CIRCLE_FLOATING);
        floatingView.startFloating();
        rotationView.setOnAnimEndListener(new OnAnimEndListener() {
            @Override
            public void onAnimEnd() {
                animStart();
                floatingView.setStop(false);
            }
        });
        rotationView.setDistanceXYR(0,0.35f*width,0.3f*width,0.11f*width);
        rotationView.setDistanceXYR(1,0.75f*width,0.32f*width,0.105f*width);
        rotationView.setDistanceXYR(2,0.25f*width,0.57f*width,0.14f*width);
        rotationView.setDistanceXYR(3,0.68f*width,0.75f*width,0.12f*width);
        rotationView.setDistanceXYR(4,0.42f*width,0.8f*width,0.1f*width);
        rotationView.setDistanceXYR(5,0.57f*width,0.5f*width,0.13f*width);
        //此处省略部分代码...
    }

添加浮动小球的代码

@Override
    protected void setSize(int width, int height) {
        super.setSize(width, height);
        if (holders.size() == 0) {
            //这里你可以添加各种自定义的holder 但是如果你需要点击事件的话  你需要在
            holders.add(new CircleHolder.Builder()
                    .setCx(0.35f * width)
                    .setCy(0.3f * width)
                    .setDx(0.06f * width)
                    .setDy(0.022f * width)
                    .setRadius(0.11f * width)
                    .setPercentSpeed(0.0019f)
                    .setColor(Color.parseColor("#FFE2FFF8"))
                    .setName("情感星座")
                    .setRate(0.7f)
                    .setSmallColor(Color.parseColor("#FF59DABC"))
                    .setTranslateX(-20f)
                    .setTranslateY(50f)
                    .setThirdCircleAngle(135)
                    .addThirdCircle(new ThirdCircle(Color.parseColor("#FFE2FFF8"),"星座",0.3f,Color.parseColor("#FF59DABC")))
                    .addThirdCircle(new ThirdCircle(Color.parseColor("#FFE2FFF8"),"情感",0.4f,Color.parseColor("#FF59DABC")))
                    .addThirdCircle(new ThirdCircle(Color.parseColor("#FFE2FFF8"),"心理",0.5f,Color.parseColor("#FF59DABC")))
                    .addThirdCircle(new ThirdCircle(Color.parseColor("#FFE2FFF8"),"两性",0.6f,Color.parseColor("#FF59DABC")))
                    .build());
            //此处省略部分代码...
      }
}

细节处理部分你可以下载项目,欢迎提issue