Android 属性动画 移动到指定坐标_android 属性动画 移动到指定坐标_嘤嘤嘤*的博客-程序员秘密

技术标签: 学习ing  

1.简单

 //将View 移动到(100,100)点

        final float x = view.getX();
        final float y = view.getY();

        final int targetX = 100;
        final int targetY = 100;

        // 第一种 无法改变 路径
        view.animate()
                .translationX(-(x - targetX))
                .translationY(-(y - targetY))
                .setDuration(2000)
                .setInterpolator(new AccelerateInterpolator())
                .withLayer()
                .start();


2.复杂

ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setDuration(2000);
        valueAnimator.setObjectValues(new PointF(x, y));
        valueAnimator.setInterpolator(new LinearInterpolator());


        //首先判断 目标点在上还是在下

        final boolean flagX = ((x - targetX) > 0) ? true : false;
        final boolean flagY = ((y - targetY) > 0) ? true : false;


        valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {

            @Override
            public PointF evaluate(float fraction, PointF startValue,
                                   PointF endValue) {
                //从0.0 --->>   1.0
//                System.out.println(" fraction :" + fraction);

                PointF point = new PointF();
                //这里是需要倒着来  最后要到达200 200 这个点

                float fractionNeed = 1 - fraction;

                if (flagX) {
                    float vX = x - targetX;
                    point.x = vX * fractionNeed + targetX;
                } else {
                    float vX = targetX - x;
                    point.x = x + vX * fraction;
                }

                if (flagY) {
                    float vY = y - targetY;
                    point.y = vY * fractionNeed + targetY;
                } else {
                    float vY = targetY - y;
                    point.y = y + vY * fraction;
                }
                return point;

            }
        });

        valueAnimator.start();
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF point = (PointF) animation.getAnimatedValue();
                float vX = point.x;
                float vY = point.y;
                //说明vx 最大值就是view原坐标
                if (flagX) {
                    if (vX <= x && vX >= targetX) {
                        view.setX(vX);
                    }
                } else {//说明vx 最小值就是view原坐标
                    if (vX >= x && vX <= targetX) {
                        view.setX(vX);
                    }
                }

                //说明vY 最大值就是view原坐标
                if (flagY) {
                    if (vY <= y && vY >= targetY) {
                        view.setY(vY);
                    }
                } else {//说明vx 最小值就是view原坐标
                    if (vY >= y && vY <= targetY) {
                        view.setY(vY);
                    }
                }

            }
        });

加点 弯曲效果

                //要让他有抛物线的感觉 那就改其中一个轴
                if (flagY) {
                    float vY = y - targetY;
//                    point.y = (vY * fractionNeed + targetY) * (1 + fractionNeed * fractionNeed);
                    if (fractionNeed > 0.5) {
                        point.y = vY * fractionNeed * fractionNeed + targetY;
                    } else {
                        point.y = vY * fractionNeed * (1 - fractionNeed) + targetY;

                    }
                } else {
                    float vY = targetY - y;
//                    point.y = (y + vY * fraction) * (1 + fraction * fractionNeed);
                    point.y = y + vY * fraction * fraction;
                }

最直接的是在

onAnimationUpdate 方法中 setX,setY时直接*int;无法控制到达指定坐标点

3.可用于购物车

 

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageEnd"
        android:background="#f00"
        android:layout_width="100dp"
        android:layout_height="100dp" />

    <ImageView
        android:id="@+id/imageStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:onClick="move"
        android:src="@mipmap/ic_launcher" />
</RelativeLayout>

2.main

private ImageView imageEnd;
    private float[] mCurrentPosition = new float[2];
    private RelativeLayout parent;
    private ImageView imageStart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageStart = findViewById(R.id.imageStart);
        imageEnd = findViewById(R.id.imageEnd);
        parent = findViewById(R.id.parent);


    }

    public void move(final View view) {

        final ImageView imageView = new ImageView(this);
        imageView.setImageDrawable(imageStart.getDrawable());

        parent.addView(imageView, 80, 80);

        int[] parentLoc = new int[2];
        parent.getLocationInWindow(parentLoc);

        //将View 移动到(100,100)点

        int[] startLoc = new int[2];
        view.getLocationInWindow(startLoc);


        int[] endLoc = new int[2];
        imageEnd.getLocationInWindow(endLoc);

        //开始掉落的商品的起始点:商品起始点-父布局起始点+该商品图片的一半
        float startX = startLoc[0] - parentLoc[0]+view.getWidth()/2;
        float startY = startLoc[1] - parentLoc[1]+view.getWidth()/2;

        //商品掉落后的终点坐标:购物车起始点-父布局起始点+购物车图片的1/5
        float toX = endLoc[0] - parentLoc[0] + imageEnd.getWidth() / 2;
        float toY = endLoc[1] - parentLoc[1] + imageEnd.getHeight() / 2;

        Path path = new Path();
        //移动到起始点(贝塞尔曲线的起点)
        path.moveTo(startX, startY);

        //使用二次萨贝尔曲线:注意第一个起始坐标越大,贝塞尔曲线的横向距离就会越大,一般按照下面的式子取即可
        path.quadTo((startX + toX) / 2+200, startLoc[1], toX, toY);
        //mPathMeasure用来计算贝塞尔曲线的曲线长度和贝塞尔曲线中间插值的坐标,
        // 如果是true,path会形成一个闭环
        final PathMeasure mPathMeasure = new PathMeasure(path, false);

        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, mPathMeasure.getLength());
        valueAnimator.setDuration(1000);

        // 匀速线性插值器
        valueAnimator.setInterpolator(new BounceInterpolator());

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 当插值计算进行时,获取中间的每个值,
                // 这里这个值是中间过程中的曲线长度(下面根据这个值来得出中间点的坐标值)
                float value = (Float) animation.getAnimatedValue();

                //mCurrentPosition此时就是中间距离点的坐标值
                mPathMeasure.getPosTan(value, mCurrentPosition, null);

                // 移动的商品图片(动画图片)的坐标设置为该中间点的坐标
                imageView.setTranslationX(mCurrentPosition[0]);
                imageView.setTranslationY(mCurrentPosition[1]);
            }
        });
        valueAnimator.start();

    }
imageStart.setVisibility(View.GONE);
imageEnd.setVisibility(View.GONE);

直接隐藏就会有那种单身狗的赶脚了.

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/FlyPig_Vip/article/details/98070578

智能推荐

spark 大型项目实战(七):用户访问session分析(七) --数据库连接池原理_spark 数据库连接池_WQ同学的博客-程序员秘密

1.谈谈数据库连接池的原理这次我们采取技术演进的方式来谈谈数据库连接池的技术出现过程及其原理,以及当下最流行的开源数据库连接池jar包。一.早期我们怎么进行数据库操作 1.原理:一般来说,java应用程序访问数据库的过程是:  ①装载数据库驱动程序;  ②通过jdbc建立数据库连接;  ③访问数据库,执行sql语句;  ④断开数据库连接。2.代码 ...

Pepper机器人的背后,孙正义的情怀和梦想_weixin_34318956的博客-程序员秘密

奥尔德巴伦机器人研究公司潜心两年终于秘密研发成功类人型机器人 Pepper,现如今日本电信巨头软银公司准备在明年将 Pepper 卖给日本消费者!Pepper 机器人似乎想博得大家一乐,它问「你是发自内心的微笑吗?」对面的人忍不住乐出声来。Pepper 吊高嗓门又放出一句妙语,「你看看,果不其然吧9Pepper 认为自己不太礼貌,于是乎弯下它的塑料脑袋道歉说,「我是不是对我们的首席执行官做的太过了...

dockerfile中的env指令,Dockerfile中的条件ENV_weixin_39566578的博客-程序员秘密

Is it possible to conditionally set an ENV variable in a Dockerfile based on the value of a build ARG?Ex: something likeARG BUILDVAR=sadENV SOMEVAR=if $BUILDVAR -eq "SO"; then echo "hello"; else echo ...

语音识别的端点检测_语音端点检测_Holidaylovesam的博客-程序员秘密

端点检测的概念端点检测,也叫语音活动检测,Voice Activity Detection,VAD,它的目的是对语音和非语音的区域进行区分。通俗来理解,端点检测就是为了从带有噪声的语音中准确的定位出语音的开始点,和结束点,去掉静音的部分,去掉噪声的部分,找到一段语音真正有效的内容。在噪声环境下使用语音识别系统,或者讲话人产生情绪或心里上的变化,导致发音失真、发音速度和音调改变,都会产生Lo...

Java 学习笔记(基本概念)_先有数据结构_刘云的博客-程序员秘密

1,基本概念          面向过程的思想:由过程、步骤、函数组成,以过程为核心。先有算法,后有数据结构。        面向对象的思想:以对象为中心,先开发类,得到对象,通过对象之间相互通信实现功能。先有数据结构,后有算法。2,名门规则类: 类中单词的首字母大写局部变量:定义在方法之中的变量,要先赋值再进行运算实例变量:定义在类中,但在方法之外,实例变量的对象

最大半连通子图_goto_1600的博客-程序员秘密

解题思路:只要找一个最长的链,因为不需要两个点互相到达,只需要一个点能到另一个点就行了,但是这条链不能分叉,先tarjan,缩点,建新图,然后用递推思想,从ssc_cnt开始递减,按照拓扑序做,g[]数组代表以i点为终点的方案数,f[]数组代表以i为终点集合中点的数量。如果f[k]&lt;f[i]+size[k]g[k]=g[i],更新f[k],如果相等g方案数相加就行了。#include&l...

随便推点

spark 大型项目实战(二十三):用户访问session分析(二十三) --session随机抽取之根据随机索引进行抽取_WQ同学的博客-程序员秘密

项目源码:https://github.com/haha174/spark-session.git /** * 第五步:遍历每天每小时的session,然后根据随机索引进行抽取 */ // 执行groupByKey算子,得到&amp;amp;lt;dateHour,(session aggrInfo)&amp;amp;gt; JavaPairRDD&amp;amp;...

MongoCollection 实现 JAVA API 模糊匹配 查询_稚枭天卓的博客-程序员秘密

MongoCollection&amp;lt;Document&amp;gt; collection = mongoBase.getCollection(colName);List&amp;lt;Object&amp;gt; ObjList = new LinkedList&amp;lt;&amp;gt;();Bson f = Filters.and(Filters.eq(&quot;domain&quot;, &quot;test&quot;), Filters.eq(&quot;p...

ogg oracle hadoop,基于OGG的Oracle与Hadoop集群/kafka准实时同步_ying侨的博客-程序员秘密

Oracle里存储的结构化数据导出到Hadoop体系做离线计算是一种常见数据处置手段。近期有场景需要做Oracle到Hadoop体系的实时导入,这里以此案例做以介绍。Oracle作为商业化的数据库解决方案,自发性的获取数据库事务日志等比较困难,故选择官方提供的同步工具OGG(Oracle GoldenGate)来解决。安装与基本配置环境说明软件配置角色数据存储服务及版本OGG版本IP源服务器Ora...

聚类算法_则聚类算法将样本集d划分为k个不相交的簇_qq_16608563的博客-程序员秘密

聚类任务在“无监督学习”中,训练样本的标记信息是未知的,目标是通过对无标记样本的学习揭示数据的内在性质及规律,为进一步的数据分析提供基础。“无监督学习”任务中,研究最多、应用最广的是“聚类”。聚类试图将数据集中的样本划分成若干个通常是不相交的子集,每个子集称为一个“簇”。通过这样的划分,每个簇可能对应于一些潜在的概念(比如类别)。注意:这些概念对于聚类算法而言事先是未知的,聚类过程仅能自动...

springMVC 异常_meililiuwei的博客-程序员秘密

1. org.aopalliance.intercept.MethodInterceptor ClassNotFoundException   缺少 aopalliance-1.0.jar  Caused by: java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor at java.