当前位置: 首页 > news >正文

设计模式(三)Animation中的策略模式

一、基本概念

1、定义:

定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变换。

2、类图:

  • Context对象: 封装可能存在的策略变化,屏蔽其他模块对算法的直接访问
  • Stategy抽象策略:定义通用算法规则
  • ConcreteStategy具体策略:含有具体的算法

3、应用场景:

  • 对调用者隐藏算法具体实现细节
  • 针对同一问题有多种处理方式,需要通过if else等形式选择某一种方式

4、优点:

  • 避免多种处理方式存在的if else语句。方便拓展,多一种处理方式,就多加一个实现类
  • 结构比较清晰,封装性更好

5、缺点:

算法过多会造成多个算法实现类。Context需要了解所有的算法,并做出相应的调用。

二、实例:

例如租房可以通过各种途径,包括中介、房东、朋友等。每一种途径都可以当成一种策略,可以互相切换。

1、抽象策略:

public interface RentingStrategy {
    void renting();
}
复制代码

2、具体策略

中介:

public class AgencyStrategy implements RentingStrategy {
    @Override
    public void renting() {
        System.out.println("通过中介租房");
    }
}
复制代码

房东:

public class LandlordStrategy implements RentingStrategy {
    @Override
    public void renting() {
        System.out.println("通过房东租房");
    }
}
复制代码

朋友:

public class FriendStrategy implements RentingStrategy {
    @Override
    public void renting() {
        System.out.println("通过朋友租房");
    }
}
复制代码

3、Context

public class Context {
    private RentingStrategy mRentingStrategy;

    public Context(RentingStrategy rentingStrategy) {
        this.mRentingStrategy = rentingStrategy;
    }

    public void rentHouse() {
        this.mRentingStrategy.renting();
    }
}
复制代码

4、调用

public class StrategyTest{
    public static void main(String[] args) {
        RentingStrategy friendStrategy = new FriendStrategy();
        Context context = new Context(friendStrategy);
        context.rentHouse();
    }
}
复制代码

三、动画插值器

动画插值器的作用就是根据时间流逝的百分比来来计算出当前属性值改变的百分比。比如LinearInterpolator用于匀速动画、AccelerateDecelerateInterpolator用于加速减速动画等等。

1、Interpolator

public interface Interpolator extends TimeInterpolator { }

public interface TimeInterpolator {

    /**
     * 返回流逝时间的百分比
     */
    float getInterpolation(float input);
}
复制代码

定义接口和策略可提供的方法

2、LinearInterpolator

@HasNativeInterpolator
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {

    public LinearInterpolator() {
    }

    public LinearInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return input;
    }

}
复制代码

3、AccelerateDecelerateInterpolator

@HasNativeInterpolator
public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }
    
}
复制代码

不同的插值器区别在于getInterpolation返回值不同,也就是说算法不同。

4、插值器调用

(1)setInterpolator设置插值器

#Animation
public void setInterpolator(Interpolator i) {
    mInterpolator = i;
}
复制代码

通过setInterpolator设置某个插值器(某种策略)

(2)View的startAnimation

#View
public void startAnimation(Animation animation) {
    animation.setStartTime(Animation.START_ON_FIRST_FRAME);
    //设置动画
    setAnimation(animation);
    //刷新父类缓存
    invalidateParentCaches();
    //刷新View跟子View
    invalidate(true);
}
复制代码

invalidate会对View进行重绘,调用View的draw方法
(3)draw

boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {
    ......
    final Animation a = getAnimation();
    if (a != null) {
        more = applyLegacyAnimation(parent, drawingTime, a, scalingRequired);
        ......
    }
}
复制代码
private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime,
        Animation a, boolean scalingRequired) {
        ......
        //设置动画开始监听
        onAnimationStart();
    }

        ......
        invalidationTransform = parent.mInvalidationTransformation;
        //获取到动画的相关值
        a.getTransformation(drawingTime, invalidationTransform, 1f);
    } else {
        invalidationTransform = t;
    }

    if (more) {
            ......
            // 获取重绘的区域
            final RectF region = parent.mInvalidateRegion;
            a.getInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop, region,
                    invalidationTransform);

            parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
            // 重新计算区域
            final int left = mLeft + (int) region.left;
            final int top = mTop + (int) region.top;
            // 进行更新
            parent.invalidate(left, top, left + (int) (region.width() + .5f),
                    top + (int) (region.height() + .5f));
        }
    }
    return more;
}
复制代码

(4)Animation.getTransformation
里面实现了动画的具体值的改变

public boolean getTransformation(long currentTime, Transformation outTransformation) {
    ......
        //通过插值器获取动画执行百分比
        final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
        applyTransformation(interpolatedTime, outTransformation);
    }
    ......

    return mMore;
}

复制代码

内部通过调用Interpolator的getInterpolation方法来获取动画执行百分比

转载于:https://juejin.im/post/5c7f68696fb9a049c966704d

相关文章:

  • 手写springmvc框架
  • 你炒的肉丝为何又柴又老又难吃?
  • 刷新三观的几个网站,个个超厉害
  • 解决在V2.0中子组件使用v-model接收来自父组件的值异常
  • 商城系统 DBShop V1.3 Release 20190309 发布
  • HCL远程登陆(telnet)
  • 大数据会取代传统BI吗
  • 网络流基础
  • 不要自建Kubernetes
  • 容器镜像
  • C++智能指针与类模板
  • React 优秀插件记录
  • chrome浏览器的两个坑,以及其他
  • Visual Studio Community 2017 配置 OpenGL 环境 (NuGet)
  • 华为传输千兆5G光端机 PTN960
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Map集合、散列表、红黑树介绍
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • SpringCloud集成分布式事务LCN (一)
  • TypeScript实现数据结构(一)栈,队列,链表
  • Vue官网教程学习过程中值得记录的一些事情
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 自动记录MySQL慢查询快照脚本
  • MPAndroidChart 教程:Y轴 YAxis
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • #、%和$符号在OGNL表达式中经常出现
  • $.ajax()
  • (ibm)Java 语言的 XPath API
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .NetCore部署微服务(二)
  • .net反混淆脱壳工具de4dot的使用
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [04]Web前端进阶—JS伪数组
  • [ABC294Ex] K-Coloring
  • [BZOJ1008][HNOI2008]越狱
  • [C++] 统计程序耗时
  • [CSDN首发]鱿鱼游戏的具体玩法详细介绍
  • [hadoop读书笔记] 第十五章 sqoop1.4.6小实验 - 将mysq数据导入HBASE
  • [J2ME]如何替换Google Map静态地图自带的Marker
  • [JavaWeb]——过滤器filter与拦截器Interceptor的使用、执行过程、区别
  • [Java安全入门]三.CC1链
  • [linux] shell中的()和{}
  • [Operating System] {ud923} P4L4: Datacenter Technologies
  • [PHP]实体类基类和序列化__sleep问题
  • [SpringBoot] AOP-AspectJ 切面技术