实现自定义对话框中的属性动画-续

来源:互联网 发布:淘宝怎么改评价用手机 编辑:程序博客网 时间:2024/05/22 23:18

前言

前一篇文章讲解了在自定义对话框中加入属性动画。
但是有个小小缺憾,小飞机没有从屏幕边缘飞出,仅仅是在对话框的边缘消失。
那如何解决这个小问题呢?这是本篇要说明的重点。

其实,不复杂,只要在上篇对话框布局的基础上做一点改动。可见的区域还是那么大,其他部分只不过是半透明。飞机就可以飞出屏幕了。

目标

这篇blog解决上篇遇到的问题: “假如让这个曲线动画沿着自定义对话框的最上侧往上飞出屏幕或是往下飞出屏幕,该如何实现?”

图形分析

上篇的坐标系参考下图
平移坐标01

说明:
图中的原点(0,0)取的是相对坐标,而不是手机最左上角开始。
而是从对话框的最左上角开始的,然后沿着x轴飞上或飞下。

那回到这篇,我们的坐标系需要变化下, 如下图:
图形平移坐标02

说明:
这个是在上图的基础上,将X轴,Y轴分别往上,往左移动。两图相比,确实是可以这么理解。
但是为了分析这个问题, 还是需要依照图中的标记来说明。
因为对话框的布局撑满了屏幕宽度,背景使用白色,然后在可见区域还是之前的白色图片。
原点(0,0)是在外框的左上角,小飞机的坐标是(50dp, 80dp) 也就是图中的deltaX, deltaY值。

其中需要注意的是从原点(0,0)平移到原点(50dp, 80dp)后,要达到小飞机还是沿着y=80dp这条x轴线跑动往上飞,
需要将 -y值 + 2 * deltaY。

关键点

布局示意图

布局示意图

布局文件 layout.dlg_custom_dialog_fullscreen_anim

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/rl_dlg_container1"    android:layout_width="fill_parent"    android:layout_height="400dp"    android:layout_centerInParent="true"    android:layout_gravity="center" >    <RelativeLayout        android:id="@+id/rl_dlg_container"        android:layout_width="wrap_content"        android:layout_height="240dp"        android:layout_centerInParent="true"        android:layout_gravity="center"        android:background="@drawable/bg_dialog" >        <TextView            android:id="@+id/tv_dlg_title"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerHorizontal="true"            android:layout_marginTop="15dp"            android:clickable="true"            android:text="@string/tv_dlg_title" />        <TextView            android:id="@+id/tv_dlg_flyup"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_below="@+id/tv_dlg_title"            android:layout_centerHorizontal="true"            android:layout_marginTop="53dp"            android:clickable="true"            android:text="@string/tv_fly_up" />        <TextView            android:id="@+id/tv_dlg_flydown"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_below="@+id/tv_dlg_flyup"            android:layout_centerHorizontal="true"            android:layout_marginTop="29dp"            android:clickable="true"            android:text="@string/tv_fly_down" />    </RelativeLayout>    <ImageView        android:id="@+id/iv_small_plane"        android:layout_width="30dp"        android:layout_height="30dp"        android:layout_alignLeft="@id/rl_dlg_container"        android:layout_alignTop="@id/rl_dlg_container"        android:background="@drawable/plane"         android:visibility="invisible"/></RelativeLayout>

对话框宽度充满屏幕

DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();customDialog.getWindow().getAttributes().width = metrics.widthPixels;

坐标转换

// 坐标系xy 转换plane_start_x = Utils.dip2px(mContext,PLANE_START_POINTF_X);plane_start_y = Utils.dip2px(mContext,PLANE_START_POINTF_Y);

全屏动画时初始化贝塞尔的起点p0, p2

        // full screen anim        valueAnimator = ValueAnimator.ofObject(new PlaneEvaluator(type),                new PointF(plane_start_x, plane_start_y), new PointF(width                        + plane_start_x, height + plane_start_y));        // full screen anim end

PointF evaluate 中的变化

// full screen anim/* * if (this.type == 0) {// up point1.set(width_up, 0); } else {// * down point1.set(width_down, 0); } */if (this.type == 0) {// up    point1.set(width_up + plane_start_x, plane_start_y);} else {// down    point1.set(width_down + plane_start_x, plane_start_y);}point.x = oneMinusT * oneMinusT * (point0.x) + 2 * oneMinusT * t        * (point1.x) + t * t * (point2.x);point.y = oneMinusT * oneMinusT * (point0.y) + 2 * oneMinusT * t        * (point1.y) + t * t * (point2.y);/* * if (this.type == 0) { point.y = -point.y; } */if (this.type == 0) {// y值反向, 坐标系移位后,y值 * 2    point.y = -point.y + plane_start_y * 2;}// full screen anim end

小结

结合2篇blog,要实现能在各种屏幕下使用的曲线的属性动画,需要如下几个步骤:
1)对应的布局文件以及view
2)屏幕适应的长宽,需要调整最优的数字dp单位
3)实现属性动画的 TypeEvaluator
4)定义ValueAnimator valueAnimator; 然后使用类是的方式初始化:

ValueAnimator.ofObject(new PlaneEvaluator(type),new PointF(plane_start_x, plane_start_y), new PointF(width+ plane_start_x, height + plane_start_y));

5)设置特定的动画时间valueAnimator.setDuration(2000);
动画的addUpdateListener,
valueAnimator.addListener(new AnimatorListenerAdapter()

6) 以及动画的目标,重复次数,模式
valueAnimator.setTarget(mIvPlane);
valueAnimator.setRepeatCount(1);
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);

7)valueAnimator.start();

源码下载

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 8岁孩走路内八字怎么办 一岁宝宝足外翻怎么办 2岁宝宝小腿弯怎么办啊 一岁宝宝小腿弯怎么办 一岁小儿o型腿怎么办 两岁宝宝o型腿怎么办 狗狗前腿外八字怎么办 20岁走路内八字怎么办 9岁儿童脚内八字怎么办 5岁宝宝脚内八字怎么办 一岁宝宝内八字怎么办 两人八字合不合怎么办 考到不好的大学怎么办 考的大学不理想怎么办 只考上二本大学怎么办 w7电脑中病毒了怎么办 电脑中病毒了该怎么办 泰迪呼吸急促怎么办啊 狗狗呼吸急促是怎么办 狗狗着凉了呕吐怎么办 狗鼻子流黄鼻涕怎么办 刚出生婴儿睡觉不踏实怎么办 有人溺水后你该怎么办 借钱不还怎么办没欠条 私人欠货款不还怎么办 公司欠货款不还怎么办 两个人离婚一方不同意怎么办 比亚迪l3油耗高怎么办 u盘密码忘记了怎么办 主板没有m.2接口怎么办 点痣留下了疤怎么办 危险三角区长痘痘怎么办 挤了危险三角区怎么办 三角区长痘挤了怎么办 三角区发红长痘怎么办 激光祛斑碰水了怎么办 激光打痣留下坑怎么办 点痣之后留下坑怎么办 去痣留下的红印怎么办 激光点痦子留疤怎么办 激光点痣的疤痕怎么办