• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android特效专辑(八)——实现心型起泡飞舞的特效,让你的APP瞬间暖心

Android特效专辑(八)——实现心型起泡飞舞的特效,让你的APP瞬间暖心

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android,android是什么意思,android studio,android多线程,android sdk等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android特效专辑(八)——实现心型起泡飞舞的特效,让你的APP瞬间暖心


Android特效专辑(八)——实现心型起泡飞舞的特效,让你的APP瞬间暖心


马上也要放年假了,家里估计会没网,更完这篇的话,可能要到年后了,不过在此期间会把更新内容都保存在本地,这样有网就可以发表了,也是极好的,今天说的这个特效,原本是Only上的一个小彩蛋的,我们来看看图片

这里写图片描述

只要我点击了Only这个字,下面就开始上升起起泡了,这个实现起来其实就是一个欲盖弥彰的动画而已,准备好三张颜色不一样的心型图片咯,这样的话,我们就开始动手来写一写吧!
首先新建一个工程——HeartFaom<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjxiciAvPg0KCde8sbi5pNf3vs3Kx9e8sbjNvMasv6k8L3A+DQo8L2Jsb2NrcXVvdGU+DQo8aDIgaWQ9"bezierevaluator">BezierEvaluator

单位转换以及计算轨迹
package com.lgl.heartfaom;

import android.animation.TypeEvaluator;
import android.graphics.PointF;

public class BezierEvaluator implements TypeEvaluator {

    private PointF pointF1;
    private PointF pointF2;

    public BezierEvaluator(PointF pointF1, PointF pointF2) {
        this.pointF1 = pointF1;
        this.pointF2 = pointF2;
    }

    @Override
    public PointF evaluate(float time, PointF startValue, PointF endValue) {

        float timeLeft = 1.0f - time;
        PointF point = new PointF();// 结果

        point.x = timeLeft * timeLeft * timeLeft * (startValue.x) + 3
                * timeLeft * timeLeft * time * (pointF1.x) + 3 * timeLeft
                * time * time * (pointF2.x) + time * time * time * (endValue.x);

        point.y = timeLeft * timeLeft * timeLeft * (startValue.y) + 3
                * timeLeft * timeLeft * time * (pointF1.y) + 3 * timeLeft
                * time * time * (pointF2.y) + time * time * time * (endValue.y);
        return point;
    }
}

PeriscopeLayout

贝塞尔曲线的计算以及气泡的实现
package com.lgl.heartfaom;

import java.util.Random;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class PeriscopeLayout extends RelativeLayout {

    private Interpolator line = new LinearInterpolator();// 线性
    private Interpolator acc = new AccelerateInterpolator();// 加速
    private Interpolator dce = new DecelerateInterpolator();// 减速
    private Interpolator accdec = new AccelerateDecelerateInterpolator();// 先加速后减速
    private Interpolator[] interpolators;

    private int mHeight;
    private int mWidth;
    private LayoutParams lp;
    private Drawable[] drawables;
    private Random random = new Random();

    private int dHeight;
    private int dWidth;

    public PeriscopeLayout(Context context) {
        super(context);
        init();
    }

    public PeriscopeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PeriscopeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public PeriscopeLayout(Context context, AttributeSet attrs,
            int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {

        // 初始化显示的图片
        drawables = new Drawable[3];
        Drawable red = getResources().getDrawable(R.drawable.pl_red);
        Drawable yellow = getResources().getDrawable(R.drawable.pl_yellow);
        Drawable blue = getResources().getDrawable(R.drawable.pl_blue);

        drawables[0] = red;
        drawables[1] = yellow;
        drawables[2] = blue;
        // 获取图的宽高 用于后面的计算
        // 注意 我这里3张图片的大小都是一样的,所以我只取了一个
        dHeight = red.getIntrinsicHeight();
        dWidth = red.getIntrinsicWidth();

        // 底部 并且 水平居中
        lp = new LayoutParams(dWidth, dHeight);
        lp.addRule(CENTER_HORIZONTAL, TRUE);// 这里的TRUE 要注意 不是true
        lp.addRule(ALIGN_PARENT_BOTTOM, TRUE);

        // 初始化插补器
        interpolators = new Interpolator[4];
        interpolators[0] = line;
        interpolators[1] = acc;
        interpolators[2] = dce;
        interpolators[3] = accdec;

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
    }

    public void addHeart() {

        ImageView imageView = new ImageView(getContext());
        // 随机选一个
        imageView.setImageDrawable(drawables[random.nextInt(3)]);
        imageView.setLayoutParams(lp);

        addView(imageView);

        Animator set = getAnimator(imageView);
        set.addListener(new AnimEndListener(imageView));
        set.start();

    }

    private Animator getAnimator(View target) {
        AnimatorSet set = getEnterAnimtor(target);

        ValueAnimator bezierValueAnimator = getBezierValueAnimator(target);

        AnimatorSet finalSet = new AnimatorSet();
        finalSet.playSequentially(set);
        finalSet.playSequentially(set, bezierValueAnimator);
        finalSet.setInterpolator(interpolators[random.nextInt(4)]);
        finalSet.setTarget(target);
        return finalSet;
    }

    private AnimatorSet getEnterAnimtor(final View target) {

        ObjectAnimator alpha = ObjectAnimator.ofFloat(target, View.ALPHA, 0.2f,
                1f);
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X,
                0.2f, 1f);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y,
                0.2f, 1f);
        AnimatorSet enter = new AnimatorSet();
        enter.setDuration(500);
        enter.setInterpolator(new LinearInterpolator());
        enter.playTogether(alpha, scaleX, scaleY);
        enter.setTarget(target);
        return enter;
    }

    private ValueAnimator getBezierValueAnimator(View target) {

        // 初始化一个贝塞尔计算器- - 传入
        BezierEvaluator evaluator = new BezierEvaluator(getPointF(2),
                getPointF(1));

        // 这里最好画个图 理解一下 传入了起点 和 终点
        ValueAnimator animator = ValueAnimator.ofObject(evaluator, new PointF(
                (mWidth - dWidth) / 2, mHeight - dHeight),
                new PointF(random.nextInt(getWidth()), 0));
        animator.addUpdateListener(new BezierListenr(target));
        animator.setTarget(target);
        animator.setDuration(3000);
        return animator;
    }

    /**
     * 获取中间的两个 点
     *
     * @param scale
     */
    private PointF getPointF(int scale) {

        PointF pointF = new PointF();
        pointF.x = random.nextInt((mWidth - 100));// 减去100 是为了控制 x轴活动范围,看效果 随意~~
        // 再Y轴上 为了确保第二个点 在第一个点之上,我把Y分成了上下两半 这样动画效果好一些 也可以用其他方法
        



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android:手把手教你 实现Activity 与 Fragment 相互通信(含Demo)
  • android自定义圆角背景实现富文本标题展示
  • 自定义收集用户行为统计库 (非常方便 可以自己拓展)
  • Android 6.0 Phone"通话显示"查询流程
  • Android缓存处理
  • 自定义进度条PictureProgressBar——从开发到开源发布全过程
  • 详解Android中的SQLite数据库存储
  • Android设备上获取照片、裁剪图片、压缩图片
  • Android触摸事件分发机制完全解析《一》
  • Android-SQLite和SQLiteOpenHelper

相关文章

  • 2017-05-26onInterceptTouchEvent与onTouchEvent默认返回值,ontouchevent返回值
  • 2017-05-26硅谷新闻4--解决页签手指按下从左到右滑动的bug,硅谷4--
  • 2017-05-26Android 环境搭建 以及 第一个android 程序的编写,搭建android
  • 2017-05-26Android Studio 优秀插件(二): Parcelable Code Generator,androidparcelable
  • 2017-05-26Android初级教程_获取Android控件的宽和高,初级教程android
  • 2017-05-26Android中使用GridView和ImageViewSwitcher实现电子相册简单功能,gridviewimageview
  • 2017-05-26Android Studio中使用AIDL进行进程间通信
  • 2017-05-26手机APP创建桌面快捷方式,app创建快捷方式
  • 2017-05-26Android之文件数据存储,android数据存储
  • 2017-05-26android测试工具MonkeyRunner--google官网翻译

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 安卓开源项目周报0117,安卓开源项目0117
    • Android 无标题 全屏设置,android无标题全屏
    • 安卓第十三天笔记-服务(Service),安卓第十三天
    • Android种使用Notification实现通知管理以及自定义通知栏(Notification示例四),自定义notification
    • 仿拉手团购App9-- 产品详情界面,团购app9--
    • ArcGIS Android工程迁移到其他电脑不能打开的问题,arcgisandroid
    • Android焦点事件分发与传递机制
    • Android 自定义View之自绘控件,androidview绘控件
    • Android Studio安装,androidstudio安装
    • 基于zookeeper的主备切换方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有