欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android動(dòng)畫效果之自定義ViewGroup添加布局動(dòng)畫(五)

 更新時(shí)間:2016年08月25日 09:09:09   作者:總李寫代碼  
這篇文章主要介紹了Android動(dòng)畫效果之自定義ViewGroup添加布局動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言:

前面幾篇文章介紹了補(bǔ)間動(dòng)畫、逐幀動(dòng)畫、屬性動(dòng)畫,大部分都是針對(duì)View來(lái)實(shí)現(xiàn)的動(dòng)畫,那么該如何為了一個(gè)ViewGroup添加動(dòng)畫呢?今天結(jié)合自定義ViewGroup來(lái)學(xué)習(xí)一下布局動(dòng)畫。本文將通過(guò)對(duì)自定義圖片選擇控件設(shè)置動(dòng)畫為例來(lái)學(xué)習(xí)布局動(dòng)畫。

自定義一個(gè)顯示多行圖片的ViewGroup:

這里不再對(duì)自定義控件做解說(shuō),想了解的可以看下以下幾篇文章
 •Android自定義控件之基本原理(一)
 •Android自定義控件之自定義屬性(二)
 •Android自定義控件之自定義組合控件(三)
 •Android自定義控件之自定義ViewGroup實(shí)現(xiàn)標(biāo)簽云(四) 

聲明幾個(gè)屬性值:

  <declare-styleable name="GridImageViewGroup">
  <attr name="childVerticalSpace" format="dimension"/>
  <attr name="childHorizontalSpace" format="dimension"/>
  <attr name="columnNum" format="integer"/>
 </declare-styleable>

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 < columnNum) {
    vw = childCount * (childHeight + childVerticalSpace);
   }
   int rowCount = childCount / columnNum + (childCount % columnNum != 0 ? 1 : 0);

   int vh = rowCount * childHeight + (rowCount > 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 < count; i++) {
   View child = getChildAt(i);
   left = (i % columnNum) * (childWidth + childHorizontalSpace);
   top = (i / columnNum) * (childHeight + childVerticalSpace);
   child.layout(left, top, left + childWidth, top + childHeight);
  }
 }

在xml中引用: 

<com.whoislcj.animation.GridImageViewGroup
   android:id="@+id/image_layout"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="10dp"
   android:animateLayoutChanges="true"
   lee:childHorizontalSpace="10dp"
   lee:childVerticalSpace="10dp"
   lee:columnNum="3"/>



在Activity中調(diào)用:

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);
 }

實(shí)現(xiàn)效果如下: 

布局動(dòng)畫產(chǎn)生的背景:

凡事總要問(wèn)個(gè)明白,為何要引入布局動(dòng)畫呢?其實(shí)通過(guò)上面的實(shí)現(xiàn)效果可以看出,在添加和刪除圖片時(shí)都顯得很突兀,不知道該用什么語(yǔ)言形容了,總之就是感覺(jué)不舒服。其實(shí)我平時(shí)在開(kāi)發(fā)中調(diào)用View.setVisibility()方法時(shí)也會(huì)有這種感受,這也是布局動(dòng)畫產(chǎn)生的一個(gè)背景吧。 

布局動(dòng)畫:

布局動(dòng)畫是指ViewGroup在布局時(shí)產(chǎn)生的動(dòng)畫效果 。實(shí)現(xiàn)布局動(dòng)畫有如下幾種方式 
第一種方式:在xml中,對(duì)ViewGrope設(shè)置android:animateLayoutChanges="true"屬性: 

<com.whoislcj.animation.GridImageViewGroup
   android:id="@+id/image_layout"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="10dp"
   android:animateLayoutChanges="true"
   lee:childHorizontalSpace="10dp"
   lee:childVerticalSpace="10dp"
   lee:columnNum="3"/>

就這么簡(jiǎn)單的一句話實(shí)現(xiàn)的效果就可以實(shí)現(xiàn)了,看看效果如何

 

這種方式雖然簡(jiǎn)單但是實(shí)現(xiàn)的布局動(dòng)畫比較單一,下面看第二種方式。 

第二種方式:LayoutTransition實(shí)現(xiàn) 

 LayoutTransition mLayoutTransition = new LayoutTransition();

  //設(shè)置每個(gè)動(dòng)畫持續(xù)的時(shí)間
  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);
  //為L(zhǎng)ayoutTransition設(shè)置動(dòng)畫及動(dòng)畫類型
  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);
  //為L(zhǎng)ayoutTransition設(shè)置動(dòng)畫及動(dòng)畫類型
  mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mAnimatorDisappearing);


  ObjectAnimator mAnimatorChangeDisappearing = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
  //為L(zhǎng)ayoutTransition設(shè)置動(dòng)畫及動(dòng)畫類型
  mLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mAnimatorChangeDisappearing);

  ObjectAnimator mAnimatorChangeAppearing = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
  //為L(zhǎng)ayoutTransition設(shè)置動(dòng)畫及動(dòng)畫類型
  mLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, mAnimatorChangeAppearing);

  //為mImageViewGroup設(shè)置mLayoutTransition對(duì)象
  mImageViewGroup.setLayoutTransition(mLayoutTransition);

上面通過(guò)自定義LayoutTransition 修改系統(tǒng)提高的默認(rèn)動(dòng)畫效果,如果不需要自定義的動(dòng)畫效果的話,不調(diào)用mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, mAnimatorDisappearing);就行了。 
LayoutTransition 提供了以下幾種過(guò)渡類型:
 •APPEARING —— 元素在容器中顯現(xiàn)時(shí)需要?jiǎng)赢嬶@示。
 •CHANGE_APPEARING —— 由于容器中要顯現(xiàn)一個(gè)新的元素,其它元素的變化需要?jiǎng)赢嬶@示。
 •DISAPPEARING —— 元素在容器中消失時(shí)需要?jiǎng)赢嬶@示。
 •CHANGE_DISAPPEARING —— 由于容器中某個(gè)元素要消失,其它元素的變化需要?jiǎng)赢嬶@示。 

看下修改過(guò)的動(dòng)畫效果: 

第三種方式:通過(guò)設(shè)置LayoutAnimation來(lái)實(shí)現(xiàn)布局動(dòng)畫

 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//隨機(jī)顯示 

也可以通過(guò)xml實(shí)現(xiàn) 

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:delay="0.5"
 android:animationOrder="normal"
 android:animation="@anim/alpha"
 />

ViewGroup xml添加android:layoutAnimation屬性 

 <com.whoislcj.animation.GridImageViewGroup
   android:id="@+id/image_layout"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="10dp"
   android:layoutAnimation="@anim/layoutanimation"
   lee:childHorizontalSpace="10dp"
   lee:childVerticalSpace="10dp"
   lee:columnNum="3"/>

由于這種方式采用的是補(bǔ)間動(dòng)畫,個(gè)人不再推薦使用這種方式,原因很簡(jiǎn)單實(shí)現(xiàn)的動(dòng)畫效果相對(duì)單一。

總結(jié):

本篇學(xué)習(xí)了布局動(dòng)畫,自此Android的動(dòng)畫學(xué)習(xí)也將告一段落了,接下來(lái)準(zhǔn)備總結(jié)一下學(xué)習(xí)動(dòng)畫的過(guò)程中遇見(jiàn)的編程知識(shí),比如鏈?zhǔn)骄幊?,TreadLocal等。

相關(guān)文章

  • android幫助文檔打開(kāi)慢的三種解決方法

    android幫助文檔打開(kāi)慢的三種解決方法

    本文介紹了“android幫助文檔打開(kāi)慢的三種解決方法”,需要的朋友可以參考一下
    2013-03-03
  • Android 網(wǎng)絡(luò)圖片查看器與網(wǎng)頁(yè)源碼查看器

    Android 網(wǎng)絡(luò)圖片查看器與網(wǎng)頁(yè)源碼查看器

    本篇文章主要介紹了Android 網(wǎng)絡(luò)圖片查看器與網(wǎng)頁(yè)源碼查看器的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-04-04
  • 基于Android代碼實(shí)現(xiàn)常用布局

    基于Android代碼實(shí)現(xiàn)常用布局

    大家在日常中經(jīng)常見(jiàn)到用xml文件實(shí)現(xiàn)android常用布局,但是大家知道如何用代碼實(shí)現(xiàn)呢?使用代碼實(shí)現(xiàn)可以幫助我們學(xué)習(xí)sdk api,所以小編把我日常整理些關(guān)于android常用布局代碼實(shí)現(xiàn)分享給大家
    2015-11-11
  • AndroidStudio更新出現(xiàn)Refreshing ''xxx'' Gradle Project狀態(tài)解決辦法

    AndroidStudio更新出現(xiàn)Refreshing ''xxx'' Gradle Project狀態(tài)解決辦法

    這篇文章主要介紹了AndroidStudio更新出現(xiàn)Refreshing 'xxx' Gradle Project狀態(tài)解決辦法的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Android實(shí)現(xiàn)掃描二維碼功能

    Android實(shí)現(xiàn)掃描二維碼功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)掃描二維碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Android實(shí)現(xiàn)滑動(dòng)加載數(shù)據(jù)的方法

    Android實(shí)現(xiàn)滑動(dòng)加載數(shù)據(jù)的方法

    這篇文章主要介紹了Android實(shí)現(xiàn)滑動(dòng)加載數(shù)據(jù)的方法,實(shí)例分析了Android通過(guò)滑動(dòng)實(shí)現(xiàn)動(dòng)態(tài)加載數(shù)據(jù)的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • Android源碼中final關(guān)鍵字的用法及final,finally,finalize的區(qū)別

    Android源碼中final關(guān)鍵字的用法及final,finally,finalize的區(qū)別

    Android的源碼中很多地方對(duì)final關(guān)鍵字的用法很是“別出心裁”,之所以這么說(shuō)是因?yàn)槲覐臎](méi)看過(guò)是這么使用final關(guān)鍵字的,通過(guò)本文給大家分享Android源碼中final關(guān)鍵字的用法及final,finally,finalize的區(qū)別,感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • Flutter應(yīng)用框架搭建實(shí)現(xiàn)屏幕適配方案詳解

    Flutter應(yīng)用框架搭建實(shí)現(xiàn)屏幕適配方案詳解

    移動(dòng)設(shè)備多樣性,特別是Android的碎片化嚴(yán)重,存在各種各樣的分辨率,flutter跨平臺(tái)開(kāi)發(fā)又需要同時(shí)支持Android和IOS,為盡可能的還原設(shè)計(jì)圖效果提升用戶的體驗(yàn),根據(jù)設(shè)計(jì)稿設(shè)計(jì)屏幕ui的時(shí)候我們需要考慮到屏幕適配的問(wèn)題
    2022-11-11
  • Android 進(jìn)度條顯示在標(biāo)題欄的實(shí)現(xiàn)方法

    Android 進(jìn)度條顯示在標(biāo)題欄的實(shí)現(xiàn)方法

    android進(jìn)度條顯示在標(biāo)題欄的實(shí)現(xiàn)方法,大概分文xml文件和java文件,具體代碼內(nèi)容大家可以通過(guò)本文學(xué)習(xí)下
    2017-01-01
  • Android Jetpack庫(kù)剖析之Lifecycle組件篇

    Android Jetpack庫(kù)剖析之Lifecycle組件篇

    本章也是帶來(lái)了Jetpack中我認(rèn)為最重要的架構(gòu)組件Lifecycle的原理探索,至于為什么覺(jué)得它是最重要是因?yàn)橄馰iewModel,LiveData這些組件也依賴于Lifecycle來(lái)感知宿主的生命周期,那么本章我們帶著幾個(gè)問(wèn)題來(lái)探索一下這個(gè)組件
    2022-07-07

最新評(píng)論