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

Android动画效果之自定义ViewGroup添加布局动画(五)

这篇文章主要介绍了Android动画效果之自定义ViewGroup添加布局动画,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

前言:

前面几篇文章介绍了补间动画、逐帧动画、属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画。本文将通过对自定义图片选择控件设置动画为例来学习布局动画。

自定义一个显示多行图片的ViewGroup:

这里不再对自定义控件做解说,想了解的可以看下以下几篇文章
 •Android自定义控件之基本原理(一)
 •Android自定义控件之自定义属性(二)
 •Android自定义控件之自定义组合控件(三)
 •Android自定义控件之自定义ViewGroup实现标签云(四) 

声明几个属性值:

  
  
  
  
 

GridImageViewGroup.java 代码

public class GridImageViewGroup extends ViewGroup {
 private int childVerticalSpace = 0;
 private int childHorizOntalSpace= 0;
 private int columnNum = 3;
 private int childWidth = 0;
 private int childHeight = 0;


 public GridImageViewGroup(Context context, AttributeSet attrs) {
  super(context, attrs);
  TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.GridImageViewGroup);
  if (attributes != null) {
   childVerticalSpace = attributes.getDimensionPixelSize(R.styleable.GridImageViewGroup_childVerticalSpace, 0);
   childHorizOntalSpace= attributes.getDimensionPixelSize(R.styleable.GridImageViewGroup_childHorizontalSpace, 0);
   columnNum = attributes.getInt(R.styleable.GridImageViewGroup_columnNum, 3);
   attributes.recycle();
  }
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  int rw = MeasureSpec.getSize(widthMeasureSpec);
  int rh = MeasureSpec.getSize(heightMeasureSpec);
  int childCount = getChildCount();
  if (childCount > 0) {
   childWidth = (rw - (columnNum - 1) * childHorizontalSpace) / columnNum;

   childHeight = childWidth;

   int vw = rw;
   if (childCount  0 ? rowCount - 1 : 0) * childVerticalSpace;

   setMeasuredDimension(vw, vh);
  }
 }

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  int left = 0;
  int top = 0;
  int count = getChildCount();
  for (int i = 0; i 

在xml中引用: 





在Activity中调用:

private void initViews() {
  mImageViewGroup = (GridImageViewGroup) findViewById(R.id.image_layout);
  ImageView imageView = new ImageView(this);
  imageView.setImageResource(R.mipmap.add_image);
  imageView.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    addImageView();
   }
  });
  mImageViewGroup.addView(imageView);
 }

 public void addImageView() {
  final ImageView imageView = new ImageView(MainActivity4.this);
  imageView.setImageResource(R.mipmap.lottery);
  imageView.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    mImageViewGroup.removeView(imageView);
   }
  });
  mImageViewGroup.addView(imageView, 0);
 }

实现效果如下: 

布局动画产生的背景:

凡事总要问个明白,为何要引入布局动画呢?其实通过上面的实现效果可以看出,在添加和删除图片时都显得很突兀,不知道该用什么语言形容了,总之就是感觉不舒服。其实我平时在开发中调用View.setVisibility()方法时也会有这种感受,这也是布局动画产生的一个背景吧。 

布局动画:

布局动画是指ViewGroup在布局时产生的动画效果 。实现布局动画有如下几种方式 
第一种方式:在xml中,对ViewGrope设置android:animateLayoutChanges="true"属性: 



就这么简单的一句话实现的效果就可以实现了,看看效果如何

 

这种方式虽然简单但是实现的布局动画比较单一,下面看第二种方式。 

第二种方式:LayoutTransition实现 

 LayoutTransition mLayoutTransition = new LayoutTransition();

  //设置每个动画持续的时间
  mLayoutTransition.setStagger(LayoutTransition.CHANGE_APPEARING, 50);
  mLayoutTransition.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 50);
  mLayoutTransition.setStagger(LayoutTransition.APPEARING, 50);
  mLayoutTransition.setStagger(LayoutTransition.DISAPPEARING, 50);

  PropertyValuesHolder appearingScaleX = PropertyValuesHolder.ofFloat("scaleX", 0.5f, 1.0f);
  PropertyValuesHolder appearingScaleY = PropertyValuesHolder.ofFloat("scaleY", 0.5f, 1.0f);
  PropertyValuesHolder appearingAlpha = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);
  ObjectAnimator mAnimatorAppearing = ObjectAnimator.ofPropertyValuesHolder(this, appearingAlpha, appearingScaleX, appearingScaleY);
  //为LayoutTransition设置动画及动画类型
  mLayoutTransition.setAnimator(LayoutTransition.APPEARING, mAnimatorAppearing);


  PropertyValuesHolder disappearingAlpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);
  PropertyValuesHolder disappearingRotatiOnY= PropertyValuesHolder.ofFloat("rotationY", 0.0f, 90.0f);
  ObjectAnimator mAnimatorDisappearing = ObjectAnimator.ofPropertyValuesHolder(this, disappearingAlpha, disappearingRotationY);
  //为LayoutTransition设置动画及动画类型
  mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mAnimatorDisappearing);


  ObjectAnimator mAnimatorChangeDisappearing = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
  //为LayoutTransition设置动画及动画类型
  mLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mAnimatorChangeDisappearing);

  ObjectAnimator mAnimatorChangeAppearing = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
  //为LayoutTransition设置动画及动画类型
  mLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, mAnimatorChangeAppearing);

  //为mImageViewGroup设置mLayoutTransition对象
  mImageViewGroup.setLayoutTransition(mLayoutTransition);

上面通过自定义LayoutTransition 修改系统提高的默认动画效果,如果不需要自定义的动画效果的话,不调用mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mAnimatorDisappearing);就行了。 
LayoutTransition 提供了以下几种过渡类型:
 •APPEARING —— 元素在容器中显现时需要动画显示。
 •CHANGE_APPEARING —— 由于容器中要显现一个新的元素,其它元素的变化需要动画显示。
 •DISAPPEARING —— 元素在容器中消失时需要动画显示。
 •CHANGE_DISAPPEARING —— 由于容器中某个元素要消失,其它元素的变化需要动画显示。 

看下修改过的动画效果: 

第三种方式:通过设置LayoutAnimation来实现布局动画

 AlphaAnimation alphaAnimation = new AlphaAnimation(0f, 1f);
  alphaAnimation.setDuration(200);
  LayoutAnimationController animatiOnController= new LayoutAnimationController(alphaAnimation, 0.5f);
  animationController.setOrder(LayoutAnimationController.ORDER_NORMAL);
  mImageViewGroup.setLayoutAnimation(animationController); 

 显示顺序有以下几种:
 • ORDER_NORMAL;//顺序显示
 • ORDER_REVERSE;//反显示
 • ORDER_RANDOM//随机显示 

也可以通过xml实现 

<&#63;xml version="1.0" encoding="utf-8"&#63;>


ViewGroup xml添加android:layoutAnimation属性 

 

由于这种方式采用的是补间动画,个人不再推荐使用这种方式,原因很简单实现的动画效果相对单一。

总结:

本篇学习了布局动画,自此Android的动画学习也将告一段落了,接下来准备总结一下学习动画的过程中遇见的编程知识,比如链式编程,TreadLocal等。


推荐阅读
  • ECharts 基础使用指南
    本文档提供了一个简单的 ECharts 使用示例,帮助初学者快速了解如何在网页中集成和使用 ECharts 创建图表。更多详细信息请参阅官方文档:https://www.echartsjs.com/zh/tutorial.html#5%20分钟上手%20ECharts ... [详细]
  • 本文介绍了ADB(Android Debug Bridge)的基本概念、安装方法、环境配置、连接真机步骤以及常用命令和高级技巧。ADB是一个强大的工具,适用于Android设备的开发和调试。 ... [详细]
  • 目录介绍01.CoordinatorLayout滑动抖动问题描述02.滑动抖动问题分析03.自定义AppBarLayout.Behavior说明04.CoordinatorLayo ... [详细]
  • 本文介绍了两种有效的方法来检查Android应用是否拥有特定权限,如媒体读写权限(media_rw)。通过这些方法,开发者和安全人员可以更好地了解应用的行为,确保其不会滥用权限。 ... [详细]
  • 本文详细介绍了ejabberd中的验证码服务、接收器以及服务器间通信的监督者和工作进程,包括它们的启动方式和主要功能。 ... [详细]
  • 本文探讨了如何在Android框架下通过自定义资源文件实现系统风格的统一,包括系统资源文件的位置、引用方法、系统主题的设置及修改等内容。 ... [详细]
  • 深入理解Django中的AJAX应用
    本文详细介绍了AJAX技术及其在Django框架中的应用。AJAX,即异步JavaScript和XML,允许网页在不重新加载整个页面的情况下与服务器交换数据并更新部分网页。 ... [详细]
  • Gradle基础概念与实践指南
    本文详细介绍了Gradle的基本概念、Groovy语言基础、Gradle的生命周期、项目管理以及任务配置等内容,旨在帮助开发者更好地理解和使用Gradle构建工具。 ... [详细]
  • 展望Kotlin未来发展:可能引入的新特性
    随着Kotlin社区的不断壮大,用户对于语言新特性的需求也在日益增长。本文基于YouTrack上的热门议题,探讨了Kotlin未来可能引入的一些新功能。 ... [详细]
  • Solr的安装与部署指南
    Solr作为一款独立的企业级搜索应用服务器,支持Web-service风格的API接口,允许用户通过HTTP请求提交XML文件以创建索引或执行搜索操作。本文将详细介绍Solr的安装步骤及配置方法。 ... [详细]
  • 企业级 Java 应用的关键性能指标解析
    本文探讨了衡量企业级 Java 应用性能的四大核心指标:商业事务、外部服务、垃圾回收及应用布局。这些指标不仅直接影响用户体验,还关系到系统的稳定性和效率。 ... [详细]
  • Docker基础指南与核心命令解析
    本文全面介绍了Docker的基本概念、安装方法、核心命令及其用法,并深入探讨了Docker容器的数据卷管理及应用部署策略,适合初学者快速掌握Docker技术。 ... [详细]
  • 本文介绍了数字音视频编解码技术标准,特别是中国自主研发的AVS标准,及其在短视频软件开发中的应用。文章探讨了AVS标准的发展历程、技术特点以及与国际标准的对比。 ... [详细]
  • Java性能优化指南 | 制定有效的性能优化策略
    探讨Java应用性能优化的方法与策略,包括性能测试技巧、常见问题及解决方案,旨在帮助开发者提升系统性能。 ... [详细]
  • 本文详细介绍了Flutter中的Stack、IndexedStack以及Positioned三个布局组件的使用方法和应用场景。Stack允许开发者以堆叠的方式展示多个子组件;IndexedStack则提供了一种仅显示指定索引子组件的方法;而Positioned则是Stack的子组件,用于精确定位子组件的位置。 ... [详细]
author-avatar
Hmily-西瓜先生
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有