热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

自定义View时,用到PaintCanvas的一些温故,简单的ViewAnimation(动画二,“大大姐”的简单变动)

自定义View时,用到PaintCanvas的一些温故,简单的ViewAnimation(动画二,“大大姐”的简单变动)

转载请注明出处:王亟亟的大牛之路

上一篇讲了 Drawable Animation ,这一篇说的使用简单的View Animation,下一篇将会做一些深化的东西,上一篇的地址:(没看的小伙伴可以看下)

运行效果:

包结构:


一般来说动画需要以下属性:
1.初始状态;
2.结束状态;
3.持续时间;
4.Interpolator(插值器)

前几项的字面意思一目了然,最后一项是干什么呢?

通过设置插值器可以改变动画的速度,以及最终效果。

android sdk提供了几种默认插值器:

1.AccelerateDecelerateInterpolator 先加速后减速
2.AccelerateInterpolator 加速
3.AnticipateInterPolator
4.AnticipateOvershootInterpolator
5.BounceInterpolator
6.CycleInterpolator
7.LinearInterpolator
8.OvershootInterpolator
9.PathInterpolator

这部分内容会在下一篇详细讲,这边不做过多解释。

我们有哪些方式可以做实现一个动画?

1,JAVA代码

2,XML

我们有哪些可以实现的动画?

1.透明度变化(AlphaAnimation)
2.缩放(ScaleAnimation)
3.位移(TranslateAnimation)
4.旋转(RotateAnimation)

How to do?

先上代码然后一边看一边解释

public class MainActivity extends AppCompatActivity {    private ImageView imageView;    private ListView listView;    private ArrayList list = new ArrayList<>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        LogUtils.d("—>MainActivity onCreate");        imageView = (ImageView) findViewById(R.id.imageView);        listView = (ListView) findViewById(R.id.listView);        ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, getData());        listView.setAdapter(adapter);        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView parent, View view, int position, long id) {                makeAnim(position);            }        });    }    @Override    protected void onRestart() {        super.onRestart();        LogUtils.d("—>MainActivity onRestart");    }    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        LogUtils.d("—>MainActivity onWindowFocusChanged");    }    @Override    protected void onPause() {        super.onPause();        LogUtils.d("—>MainActivity onPause");    }    @Override    protected void onDestroy() {        super.onDestroy();        LogUtils.d("—>MainActivity onDestroy");    }    private List getData() {        list.add("平移效果");        list.add("根据左上角旋转效果");        list.add("放大效果");        list.add("渐渐消失");        list.add("5");        list.add("6");        list.add("7");        list.add("8");        list.add("9");        list.add("10");        list.add("11");        return list;    }    //演示动画效果    //注释掉的部分和现有实现统一效果    private void makeAnim(int pos) {        Animation animation;// TranslateAnimation translateAnimation;// RotateAnimation rotateAnimation;// ScaleAnimation scaleAnimation;// AlphaAnimation alphaAnimation;        switch (pos) {            case 0://平移效果                LogUtils.d("—>makeAnim 0 平移效果");// translateAnimation = new TranslateAnimation(0, 200, 0, 50);// translateAnimation.setDuration(2000);// imageView.startAnimation(translateAnimation);                animation = AnimationUtils.loadAnimation(this, R.anim.anim_test1);                animation.setDuration(2000);                imageView.startAnimation(animation);                break;            case 1:                LogUtils.d("—>makeAnim 1 旋转效果");// rotateAnimation = new RotateAnimation(0, 90);// rotateAnimation.setDuration(2000);// imageView.startAnimation(rotateAnimation);                animation = AnimationUtils.loadAnimation(this, R.anim.anim_test2);                animation.setDuration(2000);                imageView.startAnimation(animation);                break;            case 2:                LogUtils.d("—>makeAnim 2 放大效果");// scaleAnimation = new ScaleAnimation(0, 2, 0, 2);// scaleAnimation.setDuration(2000);// imageView.startAnimation(scaleAnimation);                animation = AnimationUtils.loadAnimation(this, R.anim.anim_test3);                imageView.startAnimation(animation);                break;            case 3:                LogUtils.d("—>makeAnim 3 渐渐消失效果");// alphaAnimation = new AlphaAnimation(1.0f, 0.2f);// alphaAnimation.setDuration(2000);// imageView.startAnimation(alphaAnimation);                animation = AnimationUtils.loadAnimation(this, R.anim.anim_test4);                imageView.startAnimation(animation);                break;        }    }}

以平移动画为例

先构建TranslateAnimation 对象 TranslateAnimation translateAnimation;

初始化他的一些位置参数translateAnimation = new TranslateAnimation(0, 200, 0, 50);

设置运行时间translateAnimation.setDuration(2000);

让应该动的控件动起来,然后结束之后回到原位“`imageView.startAnimation(translateAnimation);

再来解释下,这些对象的构造函数

TranslateAnimation(Context context, AttributeSet attrs)

TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)

float fromXDelta:这个参数表示动画开始的点离当前View X坐标上的差值;

float toXDelta, 这个参数表示动画结束的点离当前View X坐标上的差值;

float fromYDelta, 这个参数表示动画开始的点离当前View Y坐标上的差值;

float toYDelta)这个参数表示动画开始的点离当前View Y坐标上的差值;

TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue) 我们最常用的一个

fromXType:第一个参数是x轴方向的值的参照(Animation.ABSOLUTE,Animation.RELATIVE_TO_SELF,or Animation.RELATIVE_TO_PARENT);

fromXValue:第二个参数是第一个参数类型的起始值;

toXType,toXValue:第三个参数与第四个参数是x轴方向的终点参照与对应值;

后面四个参数就不用解释了。如果全部选择Animation.ABSOLUTE,其实就是第二个构造函数。

RotateAnimation(Context context, AttributeSet attrs)

RotateAnimation(float fromDegrees, float toDegrees)

第一个参数fromDegrees为动画起始时的旋转角度 此角度是当前为0及360,设置其他值则先跳至该角度的位置再由from - to的值: 负则正向转,正则反向转
第二个参数toDegrees为动画旋转到的角度

RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)

第三个参数pivotXType为动画在X轴相对于物件位置类型
第四个参数pivotXValue为动画相对于物件的X坐标的开始位置 此值是以本身原始位置为原点,即如设为20%p,则向右移动父控件的20%位移,为负数则向左移

RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

第五个参数pivotXType为动画在Y轴相对于物件位置类型
第六个参数pivotYValue为动画相对于物件的Y坐标的开始位置 此值是以本身原始位置为原点,即如设为20%p,则向下移动父控件的20%位移,为负数则向上移

ScaleAnimation(Context context, AttributeSet attrs)

ScaleAnimation(float fromX, float toX, float fromY, float toY)

第一个参数fromX为动画起始时 X坐标上的伸缩尺寸 0.0表示收缩到没有
第二个参数toX为动画结束时 X坐标上的伸缩尺寸 1.0表示正常无伸缩
第三个参数fromY为动画起始时Y坐标上的伸缩尺寸 值小于1.0表示收缩
第四个参数toY为动画结束时Y坐标上的伸缩尺寸 值大于1.0表示放大

ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)

第五个参数pivotXType为动画在X轴相对于物件位置类型
第六个参数pivotXValue为动画相对于物件的X坐标的开始位置
  

ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

第七个参数pivotXType为动画在Y轴相对于物件位置类型
第八个参数pivotYValue为动画相对于物件的Y坐标的开始位置

AlphaAnimation(float fromAlpha, float toAlpha)

第一个参数fromAlpha为 动画开始时候透明度 0.0表示完全透明
第二个参数toAlpha为 动画结束时候透明度 1.0表示完全不透

基本上构造函数传完参设置个持续时间然后,start一下就OK了,非常简便。

提一下,这里面的一些坑

我们的缩放动画,一般都是左上角开始的,当然你想改,可以传参状态,有以下三个

Animation.ABSOLUTE(默认值) 相对于控件的0点的坐标值Animation.RELATIVE_TO_SELF相对于自己宽或者高的百分比(1.0表示100%)Animation.RELATIVE_TO_PARENT相对于父控件的宽或者高的百分比.

还有旋转也是,以左上角为起始点,如果要更改记得设置

那么再说下用XML的怎么做

首先你要在anim目录下建一个xml,我的例子里是像 anim_test1.xml这样的文件,然后你要把动画预设在XML里配置下即可

    

命名规则和前面的构造函数完全一致,猜也猜的出来就不多解释了。

然后这一类的xml比java代码多一些xml的标签

android:detachWallpaperandroid:durationandroid:fillAfterandroid:fillBeforeandroid:fillEnabledandroid:interpolatorandroid:repeatCountandroid:repeatMode INFINTE(无限期),RESTART(重新开始,默认值)android:startOffsetandroid:zAdjustment ZORDER_BOTTOM,ZORDER_NORMAL, ZORDER_TOP

这部分会在讲Property Animation时再加以解释。

那如何用XML内容来实现动画呢?

拿渐变动画为例

首先构造一个Animation对象 Animation animation

然后给它绑一个anim的XML

 animation = AnimationUtils.loadAnimation(this, R.anim.anim_test4);

然后让我们需要动的部分start一下imageView.startAnimation(animation);

跟java代码实现的也是一模一样。

是不是 SO EASY,这部分基础的只要熟悉一些参数和内容的意思效果就很容易实现。

推荐一些资料:

源码地址:https://github.com/ddwhan0123/BlogSample/blob/master/ViewAnimDemo.zip

记得点个赞哦

推荐阅读
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 解决微信电脑版无法刷朋友圈问题:使用安卓远程投屏方案
    在工作期间想要浏览微信和朋友圈却不太方便?虽然微信电脑版目前不支持直接刷朋友圈,但通过远程投屏技术,可以轻松实现在电脑上操作安卓设备的功能。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本文基于对相关论文和开源代码的研究,详细介绍了LOAM(激光雷达里程计与建图)的工作原理,并对其关键技术进行了分析。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 资源推荐 | TensorFlow官方中文教程助力英语非母语者学习
    来源:机器之心。本文详细介绍了TensorFlow官方提供的中文版教程和指南,帮助开发者更好地理解和应用这一强大的开源机器学习平台。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文介绍如何使用 Sortable.js 库实现元素的拖拽和位置交换功能。Sortable.js 是一个轻量级、无依赖的 JavaScript 库,支持拖拽排序、动画效果和多种插件扩展。通过简单的配置和事件处理,可以轻松实现复杂的功能。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • VSCode与Gitee集成:项目提交的高效实践
    本文介绍如何利用VSCode内置的Git工具将项目提交到Gitee,简化Git命令的使用,提升代码管理效率。同时分享一些常见的踩坑经验和解决方案。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文探讨了在通过 API 端点调用时,使用猫鼬(Mongoose)的 findOne 方法总是返回 null 的问题,并提供了详细的解决方案和建议。 ... [详细]
author-avatar
手机用户2502885123
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有