├── .gitignore ├── README.md ├── build.gradle ├── coreanimator2androidlib ├── .gitignore ├── build.gradle ├── libs │ └── okio-1.6.0.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── org │ │ └── limlee │ │ └── coreanimator2androidlib │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── org │ │ │ └── limlee │ │ │ └── coreanimator2androidlib │ │ │ ├── AnimatorImageView.java │ │ │ ├── AnimatorLayout.java │ │ │ ├── AnimatorTextView.java │ │ │ ├── AnimatorUIGroup.java │ │ │ ├── AnimatorUIImage.java │ │ │ ├── AnimatorUIView.java │ │ │ ├── AnimatorViewGroup.java │ │ │ ├── BitmapLoader.java │ │ │ ├── KeyFrameAnimation.java │ │ │ └── UIViewHelper.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── org │ └── limlee │ └── coreanimator2androidlib │ └── ExampleUnitTest.java ├── demo.gif ├── demo ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── demo │ │ └── org │ │ └── limlee │ │ └── demo │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── huiji │ │ │ ├── huabanfen.png │ │ │ ├── huabanfen_1.png │ │ │ ├── huabanfen_2.png │ │ │ ├── huabanfen_3.png │ │ │ ├── huabanfen_4.png │ │ │ ├── huabanlv.png │ │ │ ├── huabanlv_1.png │ │ │ ├── huabanlv_2.png │ │ │ ├── huabanzi.png │ │ │ ├── huabanzi_1.png │ │ │ ├── huiji.png │ │ │ ├── luoxuanjiang_1.png │ │ │ └── luoxuanjiang_2.png │ ├── java │ │ └── demo │ │ │ └── org │ │ │ └── limlee │ │ │ └── demo │ │ │ ├── MainActivity.java │ │ │ └── gift │ │ │ └── HuijiGiftAnimatorView.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── demo │ └── org │ └── limlee │ └── demo │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | 10 | .idea/compiler.xml 11 | 12 | .idea/copyright/profiles_settings.xml 13 | 14 | .idea/gradle.xml 15 | 16 | .idea/misc.xml 17 | 18 | .idea/modules.xml 19 | 20 | .idea/runConfigurations.xml 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CoreAnimator2Android 2 | 直播大礼物实现方案,使用core aminator制作动画,把导出的oc代码翻译为android这边的动画实现 3 | 4 | ![image](https://github.com/hidaron/CoreAnimator2Android/blob/master/demo.gif) 5 | 6 | ## 飞机大礼物实现解析 7 | 8 | ```` 9 | public class HuijiGiftAnimatorView extends AnimatorLayout { //所有的大动画礼物都需要继承AnimatorLayout 10 | 11 | .... 12 | @Override 13 | protected RectF initFrame() { //初始化动画画布 14 | return new RectF(0, 0, 750f, 680f); 15 | } 16 | 17 | @Override 18 | protected long duration() { //动画时长 19 | return 5700; 20 | } 21 | 22 | @Override 23 | protected boolean setupHierarchy() { //添加动画视图,这些参数都是由core aminator生成(导出OC代码)的,在这里就直接搬过来用就行了 24 | AnimatorImageView huabanfen_2 = mUIViewHelper.newImageView(); 25 | huabanfen_2.bounds = new RectF(0, 0, 62.0f, 60.0f); 26 | huabanfen_2.position = new PointF(375.000f, 340.000f); 27 | huabanfen_2.alpha = 0.0f; 28 | huabanfen_2.image = "huabanfen_2"; 29 | addViewWithName(huabanfen_2, "huabanfen_2"); 30 | 31 | /** 32 | **这部分是core aminator导出的代码,上面的是翻译使用Android api实现的代码 33 | **/ 34 | //UIImageView *花瓣粉2 = [UIImageView new]; 35 | //花瓣粉2.bounds = CGRectMake(0, 0, 62.0, 60.0); 36 | //UIImage *img花瓣粉2 = [UIImage imageWithContentsOfFile:[bundle pathForResource:@"花瓣粉_2.png" ofType:nil]]; 37 | //if ( img花瓣粉2 == nil ) { NSLog(@"** Warning: Could not create image from '花瓣粉_2.png'. 38 | //Please make sure that it is added to the project directly (not in a folder reference)."); } 39 | //花瓣粉2.image = img花瓣粉2; 40 | //花瓣粉2.contentMode = UIViewContentModeCenter; 41 | //花瓣粉2.layer.position = CGPointMake(375.000, 340.000); 42 | //[__scaling__ addSubview:花瓣粉2]; 43 | //viewsByName[@"花瓣粉_2"] = 花瓣粉2; 44 | 45 | .... 46 | return true; 47 | } 48 | 49 | @Override 50 | protected boolean addAnimation() { //为每一个动画视图添加动画属性 51 | KeyFrameAnimation 花瓣绿1RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 52 | 花瓣绿1RotationAnimation.duration = 0.750f; 53 | 花瓣绿1RotationAnimation.values = new float[]{0.000f, 6.283f}; 54 | 花瓣绿1RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 55 | 花瓣绿1RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 56 | 花瓣绿1RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 57 | addAnimation(findViewsByName("huabanlv_1"), 花瓣绿1RotationAnimation); 58 | 59 | /** 60 | **这部分是core aminator导出的代码,上面的是翻译使用Android api实现的代码 61 | **/ 62 | //CAKeyframeAnimation *花瓣绿1RotationAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; 63 | //花瓣绿1RotationAnimation.duration = 0.750; 64 | //花瓣绿1RotationAnimation.values = @[@(0.000), @(6.283)]; 65 | //花瓣绿1RotationAnimation.keyTimes = @[@(0.000), @(1.000)]; 66 | //花瓣绿1RotationAnimation.timingFunctions = @[linearTiming]; 67 | //花瓣绿1RotationAnimation.repeatCount = HUGE_VALF; 68 | //花瓣绿1RotationAnimation.beginTime = beginTime; 69 | //花瓣绿1RotationAnimation.fillMode = fillMode; 70 | //花瓣绿1RotationAnimation.removedOnCompletion = removedOnCompletion; 71 | //[[self.viewsByName[@"花瓣绿_1"] layer] addAnimation:花瓣绿1RotationAnimation forKey:@"Untitled Animation_Rotation"]; 72 | 73 | .... 74 | return true; 75 | } 76 | } 77 | ```` 78 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /coreanimator2androidlib/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /coreanimator2androidlib/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(include: ['*.jar'], dir: 'libs') 23 | testCompile 'junit:junit:4.12' 24 | compile 'com.android.support:appcompat-v7:23.4.0' 25 | compile files('libs/okio-1.6.0.jar') 26 | 27 | compile 'io.reactivex:rxjava:1.1.6' 28 | compile 'io.reactivex:rxandroid:1.2.1' 29 | } 30 | -------------------------------------------------------------------------------- /coreanimator2androidlib/libs/okio-1.6.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/coreanimator2androidlib/libs/okio-1.6.0.jar -------------------------------------------------------------------------------- /coreanimator2androidlib/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Volumes/files1/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/androidTest/java/org/limlee/coreanimator2androidlib/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/AnimatorImageView.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.content.Context; 4 | import android.graphics.PointF; 5 | import android.graphics.RectF; 6 | import android.renderscript.Float2; 7 | import android.util.AttributeSet; 8 | import android.widget.ImageView; 9 | 10 | public class AnimatorImageView extends ImageView implements AnimatorUIImage { 11 | public RectF bounds; 12 | public PointF position; 13 | public Float2 scale; 14 | public String image; 15 | public float rotation; 16 | public PointF anchorPoint; 17 | public float alpha = 1.0f; 18 | 19 | public AnimatorImageView(Context context) { 20 | super(context); 21 | } 22 | 23 | public AnimatorImageView(Context context, AttributeSet attrs) { 24 | super(context, attrs); 25 | } 26 | 27 | public AnimatorImageView(Context context, AttributeSet attrs, int defStyleAttr) { 28 | super(context, attrs, defStyleAttr); 29 | } 30 | 31 | @Override 32 | public RectF getUIBounds() { 33 | return bounds; 34 | } 35 | 36 | @Override 37 | public Float2 getUIScale() { 38 | return scale; 39 | } 40 | 41 | @Override 42 | public PointF getUIPosition() { 43 | return position; 44 | } 45 | 46 | @Override 47 | public float getUIRotation() { 48 | return rotation; 49 | } 50 | 51 | @Override 52 | public PointF getUIAnchorPoint() { 53 | return anchorPoint; 54 | } 55 | 56 | @Override 57 | public float getUIAlpha() { 58 | return alpha; 59 | } 60 | 61 | @Override 62 | public String getImage() { 63 | return image; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/AnimatorLayout.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorListenerAdapter; 5 | import android.animation.AnimatorSet; 6 | import android.animation.ObjectAnimator; 7 | import android.animation.PropertyValuesHolder; 8 | import android.animation.TimeAnimator; 9 | import android.animation.ValueAnimator; 10 | import android.annotation.TargetApi; 11 | import android.content.Context; 12 | import android.graphics.Bitmap; 13 | import android.graphics.Color; 14 | import android.graphics.PointF; 15 | import android.graphics.RectF; 16 | import android.os.Build; 17 | import android.renderscript.Float2; 18 | import android.support.annotation.IntDef; 19 | import android.support.annotation.NonNull; 20 | import android.support.v4.view.animation.PathInterpolatorCompat; 21 | import android.text.TextUtils; 22 | import android.util.AttributeSet; 23 | import android.util.DisplayMetrics; 24 | import android.util.Log; 25 | import android.view.Gravity; 26 | import android.view.View; 27 | import android.view.ViewGroup; 28 | import android.view.ViewTreeObserver; 29 | import android.view.animation.DecelerateInterpolator; 30 | import android.view.animation.Interpolator; 31 | import android.view.animation.LinearInterpolator; 32 | import android.widget.FrameLayout; 33 | import android.widget.ImageView; 34 | 35 | import java.lang.annotation.Retention; 36 | import java.lang.annotation.RetentionPolicy; 37 | import java.util.ArrayList; 38 | import java.util.HashMap; 39 | import java.util.List; 40 | import java.util.Map; 41 | 42 | import rx.Observable; 43 | import rx.Subscription; 44 | import rx.android.schedulers.AndroidSchedulers; 45 | import rx.functions.Action1; 46 | import rx.functions.Func1; 47 | import rx.schedulers.Schedulers; 48 | 49 | public abstract class AnimatorLayout extends FrameLayout implements AnimatorUIGroup { 50 | private static final String TAG = AnimatorLayout.class.getSimpleName(); 51 | @ContentMode.Type 52 | private int contentMode; 53 | private AnimatorViewGroup mScalingView; 54 | protected UIViewHelper mUIViewHelper; 55 | protected BitmapLoader mBitmapLoader; 56 | protected boolean mIsSetupFinished; 57 | protected boolean mIsAddedAnimator; 58 | protected boolean mIsPlayingAnim; 59 | private List mViewAnimators = new ArrayList<>(); 60 | private AnimatorSet mAnimatorSet = new AnimatorSet(); 61 | private Runnable mPostAnimRunnable = new Runnable() { 62 | @Override 63 | public void run() { 64 | mAnimatorSet.start(); 65 | } 66 | }; 67 | private Subscription mLoadUIResSubscription; 68 | private AnimatorTextView mTitleView; 69 | 70 | /** 71 | * abstract 72 | */ 73 | /** 74 | * 动画播放区域 75 | * 76 | * @return 77 | */ 78 | protected abstract RectF initFrame(); 79 | 80 | /** 81 | * 动画名字 82 | * 83 | * @return 84 | */ 85 | protected abstract String name(); 86 | 87 | /** 88 | * 在这里添加动画所需要的视图 89 | * 90 | * @return 91 | */ 92 | protected abstract boolean setupHierarchy(); 93 | 94 | /** 95 | * 为已经添加的视图添加动画 96 | * 97 | * @return 98 | */ 99 | protected abstract boolean addAnimation(); 100 | 101 | /** 102 | * 动画的时长 103 | * 104 | * @return 105 | */ 106 | protected abstract long duration(); 107 | 108 | 109 | /** 110 | * do not implement 111 | */ 112 | @Override 113 | public RectF getUIBounds() { 114 | return null; 115 | } 116 | 117 | @Override 118 | public Float2 getUIScale() { 119 | return null; 120 | } 121 | 122 | @Override 123 | public PointF getUIPosition() { 124 | return null; 125 | } 126 | 127 | @Override 128 | public float getUIRotation() { 129 | return 0; 130 | } 131 | 132 | @Override 133 | public PointF getUIAnchorPoint() { 134 | return null; 135 | } 136 | 137 | @Override 138 | public float getUIAlpha() { 139 | return 0; 140 | } 141 | 142 | /** 143 | * timing funs 144 | */ 145 | protected final Interpolator linearTiming = new LinearInterpolator(); 146 | protected final Interpolator defaultTiming = PathInterpolatorCompat.create(0.25f, 0.1f, 0.25f, 1f); 147 | protected final Interpolator easeInOutTiming = PathInterpolatorCompat.create(0.42f, 0f, 0.58f, 1f); 148 | protected final Interpolator easeInTiming = PathInterpolatorCompat.create(0.42f, 0f, 1f, 1f); 149 | protected final Interpolator easeOutTiming = PathInterpolatorCompat.create(0f, 0f, 0.58f, 1.0f); 150 | protected final Interpolator instantTiming = PathInterpolatorCompat.create(0.25f, 0.10f, 0.25f, 1.0f); 151 | protected final Interpolator anticipateTiming = PathInterpolatorCompat.create(0.42f, 0f, 1.00f, 1.00f); 152 | protected final Interpolator accelerateTiming = new DecelerateInterpolator(); 153 | 154 | public AnimatorLayout(Context context) { 155 | this(context, null); 156 | } 157 | 158 | public AnimatorLayout(Context context, AttributeSet attrs) { 159 | this(context, attrs, 0); 160 | } 161 | 162 | public AnimatorLayout(Context context, AttributeSet attrs, int defStyleAttr) { 163 | super(context, attrs, defStyleAttr); 164 | if (isInEditMode()) return; 165 | if (isDebug()) { 166 | setClipChildren(false); 167 | setClipToPadding(false); 168 | } 169 | mUIViewHelper = new UIViewHelper(context); 170 | mBitmapLoader = new BitmapLoader(context, name(), DisplayMetrics.DENSITY_XHIGH); //默认是2倍图资源 171 | mScalingView = new AnimatorViewGroup(getContext()); 172 | mIsSetupFinished = setupHierarchy(); 173 | if (mIsSetupFinished) { 174 | addScalingView(); 175 | mIsAddedAnimator = addAnimation() && !mViewAnimators.isEmpty(); 176 | initAnimator(); 177 | } 178 | } 179 | 180 | protected int contentMode() { 181 | return contentMode; 182 | } 183 | 184 | protected boolean isDebug() { 185 | return true; 186 | } 187 | 188 | /** 189 | * 动画播放速率 190 | * 191 | * @return 192 | */ 193 | protected int rate() { 194 | return 1; 195 | } 196 | 197 | public void setTitle(CharSequence title) { 198 | if (mTitleView != null) { 199 | mTitleView.setText(title); 200 | } 201 | } 202 | 203 | private void initAnimator() { 204 | mAnimatorSet.playTogether(mViewAnimators); 205 | mAnimatorSet.addListener(new AnimatorListenerAdapter() { 206 | private TimeAnimator mTimeAnimator = new TimeAnimator(); 207 | 208 | @Override 209 | public void onAnimationStart(Animator animation) { 210 | final long duration = duration() * rate(); 211 | mTimeAnimator.setTimeListener(new TimeAnimator.TimeListener() { 212 | @Override 213 | public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) { 214 | if (totalTime >= duration) { 215 | mAnimatorSet.cancel(); 216 | } 217 | } 218 | }); 219 | mTimeAnimator.addListener(new AnimatorListenerAdapter() { 220 | @Override 221 | public void onAnimationEnd(Animator animation) { 222 | mTimeAnimator.setTimeListener(null); 223 | mTimeAnimator.removeAllListeners(); 224 | } 225 | 226 | @Override 227 | public void onAnimationCancel(Animator animation) { 228 | mTimeAnimator.setTimeListener(null); 229 | mTimeAnimator.removeAllListeners(); 230 | } 231 | }); 232 | mTimeAnimator.start(); 233 | } 234 | 235 | @Override 236 | public void onAnimationCancel(Animator animation) { 237 | } 238 | 239 | @Override 240 | public void onAnimationEnd(Animator animation) { 241 | clearUIImageBitmap(); 242 | mTimeAnimator.cancel(); 243 | mIsPlayingAnim = false; 244 | mLoadUIResSubscription = null; 245 | } 246 | }); 247 | } 248 | 249 | @Override 250 | protected void onDetachedFromWindow() { 251 | super.onDetachedFromWindow(); 252 | stop(); 253 | mAnimatorSet.removeAllListeners(); 254 | mViewAnimators.clear(); 255 | } 256 | 257 | protected void addScalingView() { 258 | if (isDebug()) { 259 | mScalingView.setBackgroundColor(Color.parseColor("#0D000000")); 260 | } 261 | setViewsByName(mScalingView, "__scaling__"); 262 | mScalingView.setClipChildren(false); 263 | mScalingView.setClipToPadding(false); 264 | LayoutParams scalingViewLp = generateDefaultLayoutParams(); 265 | RectF scalingRect = initFrame(); 266 | if (null != scalingRect) { 267 | scalingViewLp = new LayoutParams((int) scalingRect.width(), 268 | (int) scalingRect.height()); 269 | } 270 | scalingViewLp.gravity = Gravity.CENTER; 271 | mScalingView.getViewTreeObserver().addOnGlobalLayoutListener( 272 | new ViewTreeObserver.OnGlobalLayoutListener() { 273 | @Override 274 | public void onGlobalLayout() { 275 | if (!mIsSetupFinished) return; 276 | mScalingView.getViewTreeObserver().removeOnGlobalLayoutListener(this); 277 | final int parentWidth = getWidth(); 278 | final int parentHeight = getHeight(); 279 | float xScale = (float) parentWidth / mScalingView.getWidth(); 280 | float yScale = (float) parentHeight / mScalingView.getHeight(); 281 | float scale; 282 | switch (contentMode) { 283 | case ContentMode.CONTENT_MODE_SCALETOFILL: 284 | break; 285 | case ContentMode.CONTENT_MODE_SCALEASPECTFILL: 286 | scale = Math.max(xScale, yScale); 287 | xScale = scale; 288 | yScale = scale; 289 | break; 290 | default: 291 | scale = Math.min(xScale, yScale); 292 | xScale = scale; 293 | yScale = scale; 294 | break; 295 | } 296 | if (isDebug()) { 297 | xScale = 1.0f; 298 | yScale = 1.0f; 299 | } 300 | mScalingView.setScaleX(xScale); 301 | mScalingView.setScaleY(yScale); 302 | final float titleScaleX = 1.0f / xScale; 303 | final float titleScaleY = 1.0f / yScale; 304 | if (null != mTitleView) { 305 | mTitleView.setScaleX(titleScaleX); 306 | mTitleView.setScaleY(titleScaleY); 307 | } 308 | } 309 | }); 310 | addView(mScalingView, scalingViewLp); 311 | } 312 | 313 | public void play() { 314 | if (!mIsSetupFinished 315 | || !mIsAddedAnimator 316 | || mIsPlayingAnim 317 | || mAnimatorSet.isStarted() 318 | || mAnimatorSet.isRunning()) { 319 | return; 320 | } 321 | mIsPlayingAnim = true; 322 | mLoadUIResSubscription = loadUIImageBitmap() 323 | .observeOn(AndroidSchedulers.mainThread()) 324 | .subscribe(new Action1() { 325 | @Override 326 | public void call(Boolean aBoolean) { 327 | if (aBoolean) { 328 | postOnAnimation(mPostAnimRunnable); 329 | } else { 330 | mIsPlayingAnim = false; 331 | } 332 | } 333 | }, new Action1() { 334 | @Override 335 | public void call(Throwable throwable) { 336 | mIsPlayingAnim = false; 337 | } 338 | }); 339 | } 340 | 341 | public void stop() { 342 | if (null != mLoadUIResSubscription 343 | && !mLoadUIResSubscription.isUnsubscribed()) { 344 | mLoadUIResSubscription.unsubscribe(); 345 | } 346 | removeCallbacks(mPostAnimRunnable); 347 | mAnimatorSet.cancel(); 348 | } 349 | 350 | public boolean isRunning() { 351 | return (mAnimatorSet.isStarted() 352 | || mAnimatorSet.isRunning()) 353 | && mIsPlayingAnim; 354 | } 355 | 356 | @TargetApi(Build.VERSION_CODES.KITKAT) 357 | public void pause() { 358 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 359 | mAnimatorSet.pause(); 360 | } 361 | } 362 | 363 | @TargetApi(Build.VERSION_CODES.KITKAT) 364 | public void resume() { 365 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 366 | mAnimatorSet.resume(); 367 | } 368 | } 369 | 370 | @Override 371 | public View findViewsByName(@NonNull String name) { 372 | return findViewWithTag(name); 373 | } 374 | 375 | @Override 376 | public void setViewsByName(@NonNull View view, @NonNull String name) { 377 | view.setTag(name); 378 | } 379 | 380 | @Override 381 | public void addViewWithName(@NonNull View view, @NonNull String name) { 382 | setViewsByName(view, name); 383 | addViewToScalingView(view); 384 | } 385 | 386 | private Map loadChildUIImageBitmap(ViewGroup viewGroup) { 387 | final int childCount = viewGroup.getChildCount(); 388 | final Map viewBitmapMap = new HashMap<>(); 389 | for (int i = 0; i < childCount; i++) { 390 | View view = viewGroup.getChildAt(i); 391 | if (view instanceof ViewGroup 392 | && view instanceof AnimatorUIGroup) { 393 | Map viewGroupBitmapMap = loadChildUIImageBitmap((ViewGroup) view); 394 | if (!viewGroupBitmapMap.isEmpty()) { 395 | viewBitmapMap.putAll(viewGroupBitmapMap); 396 | } 397 | } else { 398 | if (view instanceof ImageView 399 | && view instanceof AnimatorUIImage) { 400 | final String imageName = ((AnimatorUIImage) view).getImage(); 401 | if (!TextUtils.isEmpty(imageName)) { 402 | Bitmap imageBitmap = mBitmapLoader.load(imageName); 403 | if (null != imageBitmap) { 404 | viewBitmapMap.put(view, imageBitmap); 405 | } else { 406 | Log.w(TAG, "** Warning: Could not create image from " + imageName + 407 | ". Please make sure that it is added to the project directly (not in a folder reference)."); 408 | } 409 | } 410 | } 411 | } 412 | } 413 | return viewBitmapMap; 414 | } 415 | 416 | private Observable loadUIImageBitmap() { 417 | return Observable.just((Void) null) 418 | .observeOn(Schedulers.io()) 419 | .map(new Func1>() { 420 | @Override 421 | public Map call(Void aVoid) { 422 | return loadChildUIImageBitmap(mScalingView); 423 | } 424 | }) 425 | .observeOn(AndroidSchedulers.mainThread()) 426 | .map(new Func1, Boolean>() { 427 | @Override 428 | public Boolean call(Map viewBitmapMap) { 429 | for (Map.Entry entry : viewBitmapMap.entrySet()) { 430 | ((ImageView) entry.getKey()).setImageBitmap(entry.getValue()); 431 | } 432 | return !viewBitmapMap.isEmpty(); 433 | } 434 | }); 435 | } 436 | 437 | protected void clearUIImageBitmap() { 438 | clearChildUIImageBitmap(mScalingView); 439 | } 440 | 441 | protected void clearChildUIImageBitmap(ViewGroup viewGroup) { 442 | final int childCount = viewGroup.getChildCount(); 443 | for (int i = 0; i < childCount; i++) { 444 | View view = viewGroup.getChildAt(i); 445 | if (view instanceof ViewGroup 446 | && view instanceof AnimatorUIGroup) { 447 | clearChildUIImageBitmap((ViewGroup) view); 448 | } else { 449 | if (view instanceof ImageView 450 | && view instanceof AnimatorUIImage) { 451 | ((ImageView) view).setImageBitmap(null); 452 | } 453 | } 454 | } 455 | } 456 | 457 | private void addViewToScalingView(View view) { 458 | mScalingView.addAnimatorUIView(view); 459 | } 460 | 461 | public void addAnimation(View view, @NonNull KeyFrameAnimation keyFrameAnimation) { 462 | if (null != view) { 463 | PropertyValuesHolder propertyValuesHolder = keyFrameAnimation.toPropertValuesHolder(); 464 | if (null != propertyValuesHolder) { 465 | ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, propertyValuesHolder); 466 | objectAnimator.setStartDelay((long) (keyFrameAnimation.beginTime * 1000f) * rate()); 467 | objectAnimator.setDuration((long) (keyFrameAnimation.duration * 1000f) * rate()); 468 | objectAnimator.setRepeatCount(keyFrameAnimation.repeatCount); 469 | if (keyFrameAnimation.repeatCount == ValueAnimator.INFINITE) { 470 | objectAnimator.setRepeatMode(ValueAnimator.RESTART); 471 | } 472 | if (keyFrameAnimation.autoreverses) { 473 | objectAnimator.setRepeatMode(ValueAnimator.REVERSE); 474 | } 475 | objectAnimator.addListener(new AnimatorListenerAdapter() { 476 | @Override 477 | public void onAnimationCancel(Animator animation) { 478 | super.onAnimationCancel(animation); 479 | } 480 | 481 | @Override 482 | public void onAnimationEnd(Animator animation) { 483 | super.onAnimationEnd(animation); 484 | } 485 | 486 | @Override 487 | public void onAnimationStart(Animator animation) { 488 | super.onAnimationStart(animation); 489 | } 490 | }); 491 | mViewAnimators.add(objectAnimator); 492 | } 493 | } 494 | } 495 | 496 | protected AnimatorTextView getTitleView() { 497 | mTitleView = mUIViewHelper.newTextView(); 498 | mTitleView.setLines(2); 499 | mTitleView.setEllipsize(TextUtils.TruncateAt.END); 500 | mTitleView.setTextSize(14); 501 | mTitleView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP); 502 | mTitleView.setTextColor(getResources().getColor(android.R.color.white)); 503 | return mTitleView; 504 | } 505 | 506 | public static class ContentMode { 507 | public static final int CONTENT_MODE_SCALETOFILL = 1; 508 | public static final int CONTENT_MODE_SCALEASPECTFILL = 2; 509 | 510 | @IntDef({CONTENT_MODE_SCALETOFILL, CONTENT_MODE_SCALEASPECTFILL}) 511 | @Retention(RetentionPolicy.SOURCE) 512 | public @interface Type { 513 | } 514 | } 515 | 516 | } 517 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/AnimatorTextView.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.content.Context; 4 | import android.graphics.PointF; 5 | import android.graphics.RectF; 6 | import android.renderscript.Float2; 7 | import android.util.AttributeSet; 8 | import android.widget.TextView; 9 | 10 | public class AnimatorTextView extends TextView implements AnimatorUIView { 11 | 12 | public RectF bounds; 13 | public PointF position; 14 | public Float2 scale; 15 | public float rotation; 16 | public PointF anchorPoint; 17 | public float alpha = 1.0f; 18 | 19 | public AnimatorTextView(Context context) { 20 | super(context); 21 | } 22 | 23 | public AnimatorTextView(Context context, AttributeSet attrs) { 24 | super(context, attrs); 25 | } 26 | 27 | public AnimatorTextView(Context context, AttributeSet attrs, int defStyleAttr) { 28 | super(context, attrs, defStyleAttr); 29 | } 30 | 31 | @Override 32 | public RectF getUIBounds() { 33 | return bounds; 34 | } 35 | 36 | @Override 37 | public Float2 getUIScale() { 38 | return scale; 39 | } 40 | 41 | @Override 42 | public PointF getUIPosition() { 43 | return position; 44 | } 45 | 46 | @Override 47 | public float getUIRotation() { 48 | return rotation; 49 | } 50 | 51 | @Override 52 | public PointF getUIAnchorPoint() { 53 | return anchorPoint; 54 | } 55 | 56 | @Override 57 | public float getUIAlpha() { 58 | return alpha; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/AnimatorUIGroup.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.view.View; 4 | 5 | public interface AnimatorUIGroup extends AnimatorUIView { 6 | 7 | void addViewWithName(View view, String name); 8 | 9 | View findViewsByName(String name); 10 | 11 | void setViewsByName(View view, String name); 12 | } 13 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/AnimatorUIImage.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | public interface AnimatorUIImage extends AnimatorUIView { 4 | 5 | /** 6 | * 图片名 7 | * 8 | * @return 9 | */ 10 | String getImage(); 11 | } 12 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/AnimatorUIView.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.graphics.PointF; 4 | import android.graphics.RectF; 5 | import android.renderscript.Float2; 6 | 7 | public interface AnimatorUIView { 8 | 9 | /** 10 | * view的约束 11 | * 12 | * @return 13 | */ 14 | RectF getUIBounds(); 15 | 16 | /** 17 | * 缩放 18 | * 19 | * @return 20 | */ 21 | Float2 getUIScale(); 22 | 23 | /** 24 | * 初始位置 25 | * 26 | * @return 27 | */ 28 | PointF getUIPosition(); 29 | 30 | /** 31 | * 旋转 32 | * 33 | * @return 34 | */ 35 | float getUIRotation(); 36 | 37 | /** 38 | * 锚点 39 | * 40 | * @return 41 | */ 42 | PointF getUIAnchorPoint(); 43 | 44 | /** 45 | * alpha 46 | * 47 | * @return 48 | */ 49 | float getUIAlpha(); 50 | } 51 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/AnimatorViewGroup.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.content.Context; 4 | import android.graphics.PointF; 5 | import android.graphics.RectF; 6 | import android.renderscript.Float2; 7 | import android.support.v4.view.ViewCompat; 8 | import android.util.AttributeSet; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.view.ViewTreeObserver; 12 | import android.widget.FrameLayout; 13 | 14 | public class AnimatorViewGroup extends FrameLayout implements AnimatorUIGroup { 15 | private static final String TAG = AnimatorViewGroup.class.getSimpleName(); 16 | 17 | public RectF bounds; 18 | public PointF position; 19 | public Float2 scale; 20 | public float rotation; 21 | public PointF anchorPoint; 22 | public float alpha = 1.0f; 23 | 24 | public AnimatorViewGroup(Context context) { 25 | super(context); 26 | } 27 | 28 | public AnimatorViewGroup(Context context, AttributeSet attrs) { 29 | super(context, attrs); 30 | } 31 | 32 | public AnimatorViewGroup(Context context, AttributeSet attrs, int defStyleAttr) { 33 | super(context, attrs, defStyleAttr); 34 | } 35 | 36 | @Override 37 | public RectF getUIBounds() { 38 | return bounds; 39 | } 40 | 41 | @Override 42 | public Float2 getUIScale() { 43 | return scale; 44 | } 45 | 46 | @Override 47 | public PointF getUIPosition() { 48 | return position; 49 | } 50 | 51 | @Override 52 | public float getUIRotation() { 53 | return rotation; 54 | } 55 | 56 | @Override 57 | public PointF getUIAnchorPoint() { 58 | return anchorPoint; 59 | } 60 | 61 | @Override 62 | public float getUIAlpha() { 63 | return alpha; 64 | } 65 | 66 | @Override 67 | public void addViewWithName(View view, String name) { 68 | setViewsByName(view, name); 69 | addAnimatorUIView(view); 70 | } 71 | 72 | @Override 73 | public View findViewsByName(String name) { 74 | return findViewWithTag(name); 75 | } 76 | 77 | @Override 78 | public void setViewsByName(View view, String name) { 79 | view.setTag(name); 80 | } 81 | 82 | protected void addAnimatorUIView(final View view) { 83 | if (!(view instanceof AnimatorUIView)) return; 84 | final RectF bounds = ((AnimatorUIView) view).getUIBounds(); 85 | if (null != bounds) { 86 | float viewWidth = bounds.width(); 87 | float viewHeight = bounds.height(); 88 | if ((int) viewWidth >= 0 89 | && (int) viewHeight >= 0) { 90 | final ViewGroup.LayoutParams layoutParams = generateDefaultLayoutParams(); 91 | layoutParams.width = (int) viewWidth; 92 | layoutParams.height = (int) viewHeight; 93 | final PointF position = ((AnimatorUIView) view).getUIPosition(); //centerPoint 94 | PointF correctPointF = null; 95 | float positionX; 96 | float positionY; 97 | if (null != position) { 98 | positionX = position.x; 99 | positionY = position.y; 100 | //修正后的坐标 101 | correctPointF = new PointF(positionX - layoutParams.width / 2.0f 102 | , positionY - layoutParams.height / 2.0f); 103 | } 104 | final float correctLeft = null != correctPointF ? correctPointF.x : 0f; 105 | final float correctTop = null != correctPointF ? correctPointF.y : 0f; 106 | view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 107 | @Override 108 | public void onGlobalLayout() { 109 | //修正位置 110 | if (view.getLeft() != correctLeft 111 | || view.getTop() != correctTop) { 112 | final float offsetX = correctLeft - view.getLeft(); 113 | final float offsetY = correctTop - view.getTop(); 114 | view.layout((int) correctLeft, (int) correctTop, view.getRight() + (int) offsetX 115 | , view.getBottom() + (int) offsetY); 116 | } 117 | } 118 | }); 119 | final float rotationF = ((AnimatorUIView) view).getUIRotation(); 120 | if (rotationF > 0) { 121 | ViewCompat.setRotation(view, (float) (rotationF / Math.PI * 180d)); 122 | } 123 | final PointF anchorPoint = ((AnimatorUIView) view).getUIAnchorPoint(); 124 | if (null != anchorPoint) { 125 | view.setPivotX(anchorPoint.x); 126 | view.setPivotY(anchorPoint.y); 127 | } 128 | if (view instanceof AnimatorUIGroup 129 | && view instanceof ViewGroup) { 130 | ((ViewGroup) view).setClipChildren(false); 131 | } 132 | ViewCompat.setAlpha(view, ((AnimatorUIView) view).getUIAlpha()); 133 | Float2 scale = ((AnimatorUIView) view).getUIScale(); 134 | if (null != scale) { 135 | ViewCompat.setScaleX(view, scale.x); 136 | ViewCompat.setScaleY(view, scale.y); 137 | } 138 | addView(view, layoutParams); 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/BitmapLoader.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.util.DisplayMetrics; 7 | 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.util.WeakHashMap; 11 | 12 | import okio.BufferedSource; 13 | import okio.Okio; 14 | 15 | 16 | final public class BitmapLoader { 17 | private WeakHashMap mBitmapCaches = new WeakHashMap<>(); 18 | private Context mContext; 19 | private String mImageDir; 20 | private int mInDensity = DisplayMetrics.DENSITY_XHIGH; 21 | 22 | /** 23 | * @param context 24 | * @param dir 资源所在目录名 25 | * @param inDensity 资源图片的密度 26 | */ 27 | public BitmapLoader(Context context, String dir, int inDensity) { 28 | mContext = context; 29 | mImageDir = dir; 30 | mInDensity = inDensity; 31 | } 32 | 33 | public Bitmap load(String imageName) { 34 | Bitmap bitmap = mBitmapCaches.get(imageName); 35 | if (null == bitmap) { 36 | String framePath = String.format("%s/%s.png", mImageDir, imageName); 37 | BufferedSource bufferedSource = null; 38 | try { 39 | final InputStream bitmapInputStream = mContext.getAssets().open(framePath); 40 | bufferedSource = Okio.buffer(Okio.source(bitmapInputStream)); 41 | final byte[] imagebytes = bufferedSource.readByteArray(); 42 | if (null != imagebytes 43 | && imagebytes.length > 0) { 44 | bitmap = decodeBytes(imagebytes); 45 | if (null != bitmap) { 46 | mBitmapCaches.put(imageName, bitmap); 47 | } 48 | } 49 | } catch (IOException e) { 50 | if (null != bufferedSource) { 51 | try { 52 | bufferedSource.close(); 53 | } catch (IOException e1) { 54 | e1.printStackTrace(); 55 | } 56 | } 57 | } 58 | } 59 | return bitmap; 60 | } 61 | 62 | private Bitmap decodeBytes(byte[] imageBytes) { 63 | BitmapFactory.Options options = new BitmapFactory.Options(); 64 | options.inDensity = mInDensity; 65 | options.inTargetDensity = mContext.getResources().getDisplayMetrics().densityDpi; 66 | options.inScaled = true; 67 | options.inPreferredConfig = Bitmap.Config.RGB_565; 68 | options.inSampleSize = 1; 69 | return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/KeyFrameAnimation.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.animation.Keyframe; 4 | import android.animation.PropertyValuesHolder; 5 | import android.animation.TimeInterpolator; 6 | import android.animation.ValueAnimator; 7 | import android.text.TextUtils; 8 | import android.util.Property; 9 | import android.view.View; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class KeyFrameAnimation { 15 | private static final String TAG = KeyFrameAnimation.class.getSimpleName(); 16 | public static final int HUGE_VALF = ValueAnimator.INFINITE; 17 | private Property mProperty; 18 | public float duration; 19 | public float[] values; 20 | public float[] keyTimes; 21 | public TimeInterpolator[] timingFunctions; 22 | public float beginTime; 23 | public int repeatCount; //HUGE_VALE 无限循环 24 | public boolean autoreverses; 25 | 26 | private KeyFrameAnimation(Property property) { 27 | this.mProperty = property; 28 | } 29 | 30 | public static KeyFrameAnimation newKeyFrameAnimationWithIOSKeyPath(String keyPathOfIOS) { 31 | Property property = getPropertOfAnd(keyPathOfIOS); 32 | KeyFrameAnimation keyFrameAnimation = new KeyFrameAnimation(property); 33 | return keyFrameAnimation; 34 | } 35 | 36 | private static Property getPropertOfAnd(String propertyNameOfIOS) { 37 | Property property = null; 38 | if (propertyNameOfIOS.equals("transform.rotation.z") 39 | || propertyNameOfIOS.equals("transform.rotation")) { 40 | property = View.ROTATION; 41 | } else if (propertyNameOfIOS.equals("transform.rotation.x")) { 42 | property = View.ROTATION_X; 43 | } else if (propertyNameOfIOS.equals("transform.rotation.y")) { 44 | property = View.ROTATION_Y; 45 | } else if (propertyNameOfIOS.equals("transform.translation.x")) { 46 | property = View.TRANSLATION_X; 47 | } else if (propertyNameOfIOS.equals("transform.translation.y")) { 48 | property = View.TRANSLATION_Y; 49 | } else if (propertyNameOfIOS.equals("transform.scale.z") 50 | || propertyNameOfIOS.equals("transform.scale")) { 51 | property = SCALE; 52 | } else if (propertyNameOfIOS.equals("transform.scale.x")) { 53 | property = View.SCALE_X; 54 | } else if (propertyNameOfIOS.equals("transform.scale.y")) { 55 | property = View.SCALE_Y; 56 | } else if (propertyNameOfIOS.equals("opacity")) { 57 | property = View.ALPHA; 58 | } 59 | return property; 60 | } 61 | 62 | public static Property SCALE = new Property(Float.class, "scale") { 63 | 64 | @Override 65 | public void set(View object, Float value) { 66 | object.setScaleX(value); 67 | object.setScaleY(value); 68 | } 69 | 70 | @Override 71 | public Float get(View object) { 72 | return object.getScaleX(); //or object.getScaleY(); 73 | } 74 | }; 75 | 76 | public PropertyValuesHolder toPropertValuesHolder() { 77 | if (null == keyTimes 78 | || null == values 79 | || keyTimes.length == 0 80 | || values.length == 0 81 | || keyTimes.length != values.length) { 82 | throw new IllegalArgumentException("error KeyFrame params!"); 83 | } 84 | Property property = mProperty; 85 | if (null == property 86 | || TextUtils.isEmpty(property.getName())) { 87 | throw new IllegalArgumentException("error KeyFrame property!"); 88 | } 89 | List keframeList = new ArrayList<>(); 90 | Keyframe keyframe; 91 | for (int i = 0; i < keyTimes.length; i++) { 92 | if (property.getName().equals(View.ROTATION.getName()) 93 | || property.getName().equals(View.ROTATION_X.getName()) 94 | || property.getName().equals(View.ROTATION_Y.getName())) { 95 | int rotation = (int) (values[i] / Math.PI * 180d); 96 | keyframe = Keyframe.ofFloat(keyTimes[i], (float) rotation); 97 | } else { 98 | keyframe = Keyframe.ofFloat(keyTimes[i], values[i]); 99 | } 100 | keframeList.add(keyframe); 101 | if (null != timingFunctions) { 102 | final TimeInterpolator timeInterpolator = timingFunctions[i]; 103 | if (null != timeInterpolator) { 104 | keyframe.setInterpolator(timeInterpolator); 105 | } 106 | } 107 | } 108 | Keyframe[] keyFrames = new Keyframe[keframeList.size()]; 109 | return PropertyValuesHolder.ofKeyframe(mProperty, keframeList.toArray(keyFrames)); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/java/org/limlee/coreanimator2androidlib/UIViewHelper.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import android.content.Context; 4 | 5 | final public class UIViewHelper { 6 | private Context mContext; 7 | 8 | public UIViewHelper(Context context) { 9 | mContext = context; 10 | } 11 | 12 | public AnimatorImageView newImageView() { 13 | return new AnimatorImageView(mContext); 14 | } 15 | 16 | public AnimatorViewGroup newViewGroup() { 17 | return new AnimatorViewGroup(mContext); 18 | } 19 | 20 | public AnimatorTextView newTextView() { 21 | return new AnimatorTextView(mContext); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | CoreAnimator2Androidlib 3 | 4 | -------------------------------------------------------------------------------- /coreanimator2androidlib/src/test/java/org/limlee/coreanimator2androidlib/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package org.limlee.coreanimator2androidlib; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo.gif -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /demo/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | 7 | defaultConfig { 8 | applicationId "demo.org.limlee.demo" 9 | minSdkVersion 16 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.4.0' 26 | compile project(path: ':coreanimator2androidlib') 27 | } 28 | -------------------------------------------------------------------------------- /demo/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Volumes/files1/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /demo/src/androidTest/java/demo/org/limlee/demo/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package demo.org.limlee.demo; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /demo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanfen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanfen.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanfen_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanfen_1.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanfen_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanfen_2.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanfen_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanfen_3.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanfen_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanfen_4.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanlv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanlv.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanlv_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanlv_1.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanlv_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanlv_2.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanzi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanzi.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huabanzi_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huabanzi_1.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/huiji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/huiji.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/luoxuanjiang_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/luoxuanjiang_1.png -------------------------------------------------------------------------------- /demo/src/main/assets/huiji/luoxuanjiang_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hidaron/CoreAnimator2Android/55cc5da62a09c5fe9d920c30e4d7bf3235e7848a/demo/src/main/assets/huiji/luoxuanjiang_2.png -------------------------------------------------------------------------------- /demo/src/main/java/demo/org/limlee/demo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package demo.org.limlee.demo; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.View; 6 | import android.widget.Button; 7 | 8 | import demo.org.limlee.demo.gift.HuijiGiftAnimatorView; 9 | 10 | public class MainActivity extends AppCompatActivity { 11 | 12 | private HuijiGiftAnimatorView mHuijiGiftAnimatorView; 13 | private Button mPlayBtn; 14 | private Button mStopBtn; 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_main); 20 | mHuijiGiftAnimatorView = (HuijiGiftAnimatorView) findViewById(R.id.huiji); 21 | mPlayBtn = (Button) findViewById(R.id.play); 22 | mStopBtn = (Button) findViewById(R.id.stop); 23 | mPlayBtn.setOnClickListener(new View.OnClickListener() { 24 | @Override 25 | public void onClick(View v) { 26 | mHuijiGiftAnimatorView.play(); 27 | } 28 | }); 29 | mStopBtn.setOnClickListener(new View.OnClickListener() { 30 | @Override 31 | public void onClick(View v) { 32 | mHuijiGiftAnimatorView.stop(); 33 | } 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /demo/src/main/java/demo/org/limlee/demo/gift/HuijiGiftAnimatorView.java: -------------------------------------------------------------------------------- 1 | package demo.org.limlee.demo.gift; 2 | 3 | import android.animation.TimeInterpolator; 4 | import android.content.Context; 5 | import android.graphics.PointF; 6 | import android.graphics.RectF; 7 | import android.renderscript.Float2; 8 | import android.util.AttributeSet; 9 | 10 | import org.limlee.coreanimator2androidlib.AnimatorImageView; 11 | import org.limlee.coreanimator2androidlib.AnimatorLayout; 12 | import org.limlee.coreanimator2androidlib.AnimatorTextView; 13 | import org.limlee.coreanimator2androidlib.KeyFrameAnimation; 14 | 15 | 16 | public class HuijiGiftAnimatorView extends AnimatorLayout { 17 | 18 | public HuijiGiftAnimatorView(Context context) { 19 | super(context); 20 | } 21 | 22 | public HuijiGiftAnimatorView(Context context, AttributeSet attrs) { 23 | super(context, attrs); 24 | } 25 | 26 | public HuijiGiftAnimatorView(Context context, AttributeSet attrs, int defStyleAttr) { 27 | super(context, attrs, defStyleAttr); 28 | } 29 | 30 | @Override 31 | protected RectF initFrame() { 32 | return new RectF(0, 0, 750f, 680f); 33 | } 34 | 35 | protected String name() { 36 | return "huiji"; 37 | } 38 | 39 | @Override 40 | protected boolean isDebug() { 41 | return false; 42 | } 43 | 44 | @Override 45 | protected long duration() { 46 | return 5700; 47 | } 48 | 49 | @Override 50 | protected boolean setupHierarchy() { 51 | 52 | //core animator自动生成的oc代码 53 | // UIImageView *花瓣粉2 = [UIImageView new]; 54 | // 花瓣粉2.bounds = CGRectMake(0, 0, 62.0, 60.0); 55 | // UIImage *img花瓣粉2 = [UIImage imageWithContentsOfFile:[bundle pathForResource:@"花瓣粉_2.png" ofType:nil]]; 56 | // if ( img花瓣粉2 == nil ) { NSLog(@"** Warning: Could not create image from '花瓣粉_2.png'. Please make sure that it is added to the project directly (not in a folder reference)."); } 57 | // 花瓣粉2.image = img花瓣粉2; 58 | // 花瓣粉2.contentMode = UIViewContentModeCenter; 59 | // 花瓣粉2.layer.position = CGPointMake(375.000, 340.000); 60 | // [__scaling__ addSubview:花瓣粉2]; 61 | // viewsByName[@"花瓣粉_2"] = 花瓣粉2; 62 | 63 | AnimatorImageView huabanfen_2 = mUIViewHelper.newImageView(); 64 | huabanfen_2.bounds = new RectF(0, 0, 62.0f, 60.0f); 65 | huabanfen_2.position = new PointF(375.000f, 340.000f); 66 | huabanfen_2.alpha = 0.0f; 67 | huabanfen_2.image = "huabanfen_2"; 68 | addViewWithName(huabanfen_2, "huabanfen_2"); 69 | 70 | AnimatorImageView huabanlv_1 = mUIViewHelper.newImageView(); 71 | huabanlv_1.bounds = new RectF(0, 0, 62.0f, 60.0f); 72 | huabanlv_1.position = new PointF(449.370f, 367.589f); 73 | huabanlv_1.scale = new Float2(0.58f, 0.58f); 74 | huabanlv_1.alpha = 0.0f; 75 | huabanlv_1.image = "huabanlv_1"; 76 | addViewWithName(huabanlv_1, "huabanlv_1"); 77 | 78 | AnimatorImageView huabanfen_3 = mUIViewHelper.newImageView(); 79 | huabanfen_3.bounds = new RectF(0, 0, 62.0f, 60.0f); 80 | huabanfen_3.position = new PointF(232.844f, 249.307f); 81 | huabanfen_3.scale = new Float2(0.58f, 0.58f); 82 | huabanfen_3.alpha = 0.0f; 83 | huabanfen_3.image = "huabanfen_3"; 84 | addViewWithName(huabanfen_3, "huabanfen_3"); 85 | 86 | AnimatorImageView huabanfen_4 = mUIViewHelper.newImageView(); 87 | huabanfen_4.bounds = new RectF(0, 0, 62.0f, 60.0f); 88 | huabanfen_4.position = new PointF(612.812f, 193.818f); 89 | huabanfen_4.scale = new Float2(0.58f, 0.58f); 90 | huabanfen_4.alpha = 0.0f; 91 | huabanfen_4.image = "huabanfen_4"; 92 | addViewWithName(huabanfen_4, "huabanfen_4"); 93 | 94 | AnimatorImageView huabanlv_2 = mUIViewHelper.newImageView(); 95 | huabanlv_2.bounds = new RectF(0, 0, 62.0f, 60.0f); 96 | huabanlv_2.position = new PointF(552.167f, 249.896f); 97 | huabanlv_2.scale = new Float2(0.58f, 0.58f); 98 | huabanlv_2.alpha = 0.0f; 99 | huabanlv_2.image = "huabanlv_2"; 100 | addViewWithName(huabanlv_2, "huabanlv_2"); 101 | 102 | AnimatorImageView huabanzi_1 = mUIViewHelper.newImageView(); 103 | huabanzi_1.bounds = new RectF(0, 0, 62.0f, 60.0f); 104 | huabanzi_1.position = new PointF(127.286f, 276.745f); 105 | huabanzi_1.scale = new Float2(0.58f, 0.58f); 106 | huabanzi_1.alpha = 0.0f; 107 | huabanzi_1.image = "huabanzi_1"; 108 | addViewWithName(huabanzi_1, "huabanzi_1"); 109 | 110 | AnimatorImageView huabanzi = mUIViewHelper.newImageView(); 111 | huabanzi.bounds = new RectF(0, 0, 62.0f, 60.0f); 112 | huabanzi.position = new PointF(645.896f, 283.349f); 113 | huabanzi.scale = new Float2(0.58f, 0.58f); 114 | huabanzi.alpha = 0.0f; 115 | huabanzi.image = "huabanzi"; 116 | addViewWithName(huabanzi, "huabanzi"); 117 | 118 | AnimatorImageView huabanlv = mUIViewHelper.newImageView(); 119 | huabanlv.bounds = new RectF(0, 0, 62.0f, 60.0f); 120 | huabanlv.position = new PointF(645.896f, 283.349f); 121 | huabanlv.scale = new Float2(0.58f, 0.58f); 122 | huabanlv.alpha = 0.0f; 123 | huabanlv.image = "huabanlv"; 124 | addViewWithName(huabanlv, "huabanlv"); 125 | 126 | AnimatorImageView huabanfen = mUIViewHelper.newImageView(); 127 | huabanfen.bounds = new RectF(0, 0, 62.0f, 60.0f); 128 | huabanfen.position = new PointF(645.896f, 283.349f); 129 | huabanfen.scale = new Float2(0.58f, 0.58f); 130 | huabanfen.alpha = 0.0f; 131 | huabanfen.image = "huabanfen"; 132 | addViewWithName(huabanfen, "huabanfen"); 133 | 134 | AnimatorImageView huabanfen_1 = mUIViewHelper.newImageView(); 135 | huabanfen_1.bounds = new RectF(0, 0, 62.0f, 60.0f); 136 | huabanfen_1.position = new PointF(326.115f, 273.443f); 137 | huabanfen_1.scale = new Float2(0.58f, 0.58f); 138 | huabanfen_1.alpha = 0.0f; 139 | huabanfen_1.image = "huabanfen_1"; 140 | addViewWithName(huabanfen_1, "huabanfen_1"); 141 | 142 | AnimatorImageView huiji = mUIViewHelper.newImageView(); 143 | huiji.bounds = new RectF(0, 0, 850.0f, 600.0f); 144 | huiji.position = new PointF(976.027f, 149.898f); 145 | huiji.scale = new Float2(0.48f, 0.48f); 146 | huiji.image = "huiji"; 147 | addViewWithName(huiji, "huiji"); 148 | 149 | AnimatorImageView luoxuanjiang_2 = mUIViewHelper.newImageView(); 150 | luoxuanjiang_2.bounds = new RectF(0, 0, 850.0f, 600.0f); 151 | luoxuanjiang_2.position = new PointF(976.027f, 149.898f); 152 | luoxuanjiang_2.scale = new Float2(0.48f, 0.48f); 153 | luoxuanjiang_2.image = "luoxuanjiang_2"; 154 | addViewWithName(luoxuanjiang_2, "luoxuanjiang_2"); 155 | 156 | AnimatorImageView luoxuanjiang_1 = mUIViewHelper.newImageView(); 157 | luoxuanjiang_1.bounds = new RectF(0, 0, 850.0f, 600.0f); 158 | luoxuanjiang_1.position = new PointF(976.027f, 149.898f); 159 | luoxuanjiang_1.scale = new Float2(0.48f, 0.48f); 160 | luoxuanjiang_1.image = "luoxuanjiang_1"; 161 | addViewWithName(luoxuanjiang_1, "luoxuanjiang_1"); 162 | 163 | AnimatorTextView afont = getTitleView(); 164 | afont.bounds = new RectF(0, 0, 803.0f, 140.0f); 165 | afont.position = new PointF(-220.685f, 39.945f); 166 | afont.scale = new Float2(0.93f, 0.93f); 167 | addViewWithName(afont, "afont"); 168 | return true; 169 | } 170 | 171 | @Override 172 | protected boolean addAnimation() { 173 | 174 | //core animator自动生成的oc代码 175 | // CAKeyframeAnimation *花瓣绿1RotationAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; 176 | // 花瓣绿1RotationAnimation.duration = 0.750; 177 | // 花瓣绿1RotationAnimation.values = @[@(0.000), @(6.283)]; 178 | // 花瓣绿1RotationAnimation.keyTimes = @[@(0.000), @(1.000)]; 179 | // 花瓣绿1RotationAnimation.timingFunctions = @[linearTiming]; 180 | // 花瓣绿1RotationAnimation.repeatCount = HUGE_VALF; 181 | // 花瓣绿1RotationAnimation.beginTime = beginTime; 182 | // 花瓣绿1RotationAnimation.fillMode = fillMode; 183 | // 花瓣绿1RotationAnimation.removedOnCompletion = removedOnCompletion; 184 | // [[self.viewsByName[@"花瓣绿_1"] layer] addAnimation:花瓣绿1RotationAnimation forKey:@"Untitled Animation_Rotation"]; 185 | 186 | KeyFrameAnimation 花瓣绿1RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 187 | 花瓣绿1RotationAnimation.duration = 0.750f; 188 | 花瓣绿1RotationAnimation.values = new float[]{0.000f, 6.283f}; 189 | 花瓣绿1RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 190 | 花瓣绿1RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 191 | 花瓣绿1RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 192 | addAnimation(findViewsByName("huabanlv_1"), 花瓣绿1RotationAnimation); 193 | 194 | KeyFrameAnimation 花瓣绿1OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 195 | 花瓣绿1OpacityAnimation.duration = 5.700f; 196 | 花瓣绿1OpacityAnimation.values = new float[]{0.000f, 0.000f, 0.000f, 1.000f, 1.000f}; 197 | 花瓣绿1OpacityAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.368f, 0.368f, 1.000f}; 198 | 花瓣绿1OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming}; 199 | addAnimation(findViewsByName("huabanlv_1"), 花瓣绿1OpacityAnimation); 200 | 201 | KeyFrameAnimation 花瓣绿1TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 202 | 花瓣绿1TranslationXAnimation.duration = 5.700f; 203 | 花瓣绿1TranslationXAnimation.values = new float[]{0.000f, -59.708f, -59.708f, -91.953f, -153.516f, -153.516f}; 204 | 花瓣绿1TranslationXAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.368f, 0.368f, 0.860f, 1.000f}; 205 | 花瓣绿1TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 206 | addAnimation(findViewsByName("huabanlv_1"), 花瓣绿1TranslationXAnimation); 207 | 208 | KeyFrameAnimation 花瓣绿1TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 209 | 花瓣绿1TranslationYAnimation.duration = 5.700f; 210 | 花瓣绿1TranslationYAnimation.values = new float[]{0.000f, -104.729f, -104.729f, -142.823f, 376.740f, 376.740f}; 211 | 花瓣绿1TranslationYAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.368f, 0.368f, 0.860f, 1.000f}; 212 | 花瓣绿1TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 213 | addAnimation(findViewsByName("huabanlv_1"), 花瓣绿1TranslationYAnimation); 214 | 215 | KeyFrameAnimation 花瓣粉1RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 216 | 花瓣粉1RotationAnimation.duration = 0.750f; 217 | 花瓣粉1RotationAnimation.values = new float[]{0.000f, 6.283f}; 218 | 花瓣粉1RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 219 | 花瓣粉1RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 220 | 花瓣粉1RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 221 | addAnimation(findViewsByName("huabanfen_1"), 花瓣粉1RotationAnimation); 222 | 223 | KeyFrameAnimation 花瓣粉1OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 224 | 花瓣粉1OpacityAnimation.duration = 5.700f; 225 | 花瓣粉1OpacityAnimation.values = new float[]{0.000f, 0.000f, 1.000f, 1.000f}; 226 | 花瓣粉1OpacityAnimation.keyTimes = new float[]{0.000f, 0.254f, 0.254f, 1.000f}; 227 | 花瓣粉1OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming}; 228 | addAnimation(findViewsByName("huabanfen_1"), 花瓣粉1OpacityAnimation); 229 | 230 | KeyFrameAnimation 花瓣粉1TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 231 | 花瓣粉1TranslationXAnimation.duration = 5.700f; 232 | 花瓣粉1TranslationXAnimation.values = new float[]{0.000f, 0.000f, -1.589f, -12.927f, -12.927f}; 233 | 花瓣粉1TranslationXAnimation.keyTimes = new float[]{0.000f, 0.254f, 0.254f, 0.860f, 1.000f}; 234 | 花瓣粉1TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming, linearTiming}; 235 | addAnimation(findViewsByName("huabanfen_1"), 花瓣粉1TranslationXAnimation); 236 | 237 | KeyFrameAnimation 花瓣粉1TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 238 | 花瓣粉1TranslationYAnimation.duration = 5.700f; 239 | 花瓣粉1TranslationYAnimation.values = new float[]{0.000f, 0.000f, -54.123f, 424.547f, 424.547f}; 240 | 花瓣粉1TranslationYAnimation.keyTimes = new float[]{0.000f, 0.254f, 0.254f, 0.860f, 1.000f}; 241 | 花瓣粉1TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming, linearTiming}; 242 | addAnimation(findViewsByName("huabanfen_1"), 花瓣粉1TranslationYAnimation); 243 | 244 | KeyFrameAnimation 花瓣绿2RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 245 | 花瓣绿2RotationAnimation.duration = 0.750f; 246 | 花瓣绿2RotationAnimation.values = new float[]{0.000f, 6.283f}; 247 | 花瓣绿2RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 248 | 花瓣绿2RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 249 | 花瓣绿2RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 250 | addAnimation(findViewsByName("huabanlv_2"), 花瓣绿2RotationAnimation); 251 | 252 | KeyFrameAnimation 花瓣绿2OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 253 | 花瓣绿2OpacityAnimation.duration = 5.700f; 254 | 花瓣绿2OpacityAnimation.values = new float[]{0.000f, 0.000f, 1.000f, 1.000f}; 255 | 花瓣绿2OpacityAnimation.keyTimes = new float[]{0.000f, 0.131f, 0.132f, 1.000f}; 256 | 花瓣绿2OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming}; 257 | addAnimation(findViewsByName("huabanlv_2"), 花瓣绿2OpacityAnimation); 258 | 259 | KeyFrameAnimation 花瓣绿2TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 260 | 花瓣绿2TranslationXAnimation.duration = 5.700f; 261 | 花瓣绿2TranslationXAnimation.values = new float[]{0.000f, -8.031f, -8.031f, -5.167f, -36.542f, -36.542f}; 262 | 花瓣绿2TranslationXAnimation.keyTimes = new float[]{0.000f, 0.001f, 0.088f, 0.088f, 0.500f, 1.000f}; 263 | 花瓣绿2TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 264 | addAnimation(findViewsByName("huabanlv_2"), 花瓣绿2TranslationXAnimation); 265 | 266 | KeyFrameAnimation 花瓣绿2TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 267 | 花瓣绿2TranslationYAnimation.duration = 5.700f; 268 | 花瓣绿2TranslationYAnimation.values = new float[]{0.000f, -21.957f, -21.957f, -48.469f, 452.474f, 452.474f}; 269 | 花瓣绿2TranslationYAnimation.keyTimes = new float[]{0.000f, 0.001f, 0.088f, 0.088f, 0.500f, 1.000f}; 270 | 花瓣绿2TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 271 | addAnimation(findViewsByName("huabanlv_2"), 花瓣绿2TranslationYAnimation); 272 | 273 | KeyFrameAnimation 花瓣粉2RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 274 | 花瓣粉2RotationAnimation.duration = 0.750f; 275 | 花瓣粉2RotationAnimation.values = new float[]{0.000f, 6.283f}; 276 | 花瓣粉2RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 277 | 花瓣粉2RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 278 | 花瓣粉2RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 279 | addAnimation(findViewsByName("huabanfen_2"), 花瓣粉2RotationAnimation); 280 | 281 | KeyFrameAnimation 花瓣粉2OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 282 | 花瓣粉2OpacityAnimation.duration = 5.700f; 283 | 花瓣粉2OpacityAnimation.values = new float[]{0.000f, 0.000f, 0.000f, 0.000f, 1.000f, 1.000f}; 284 | 花瓣粉2OpacityAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.000f, 0.342f, 0.342f, 1.000f}; 285 | 花瓣粉2OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, instantTiming, instantTiming, linearTiming}; 286 | addAnimation(findViewsByName("huabanfen_2"), 花瓣粉2OpacityAnimation); 287 | 288 | KeyFrameAnimation 花瓣粉2ScaleXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.scale.x"); 289 | 花瓣粉2ScaleXAnimation.duration = 5.700f; 290 | 花瓣粉2ScaleXAnimation.values = new float[]{1.000f, 0.580f, 0.580f}; 291 | 花瓣粉2ScaleXAnimation.keyTimes = new float[]{0.000f, 0.000f, 1.000f}; 292 | 花瓣粉2ScaleXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming}; 293 | addAnimation(findViewsByName("huabanfen_2"), 花瓣粉2ScaleXAnimation); 294 | 295 | KeyFrameAnimation 花瓣粉2ScaleYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.scale.y"); 296 | 花瓣粉2ScaleYAnimation.duration = 5.700f; 297 | 花瓣粉2ScaleYAnimation.values = new float[]{1.000f, 0.580f, 0.580f}; 298 | 花瓣粉2ScaleYAnimation.keyTimes = new float[]{0.000f, 0.000f, 1.000f}; 299 | 花瓣粉2ScaleYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming}; 300 | addAnimation(findViewsByName("huabanfen_2"), 花瓣粉2ScaleYAnimation); 301 | 302 | KeyFrameAnimation 花瓣粉2TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 303 | 花瓣粉2TranslationXAnimation.duration = 5.700f; 304 | 花瓣粉2TranslationXAnimation.values = new float[]{0.000f, -110.911f, -110.911f, -130.693f, -205.073f, -205.073f}; 305 | 花瓣粉2TranslationXAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.342f, 0.342f, 0.851f, 1.000f}; 306 | 花瓣粉2TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 307 | addAnimation(findViewsByName("huabanfen_2"), 花瓣粉2TranslationXAnimation); 308 | 309 | KeyFrameAnimation 花瓣粉2TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 310 | 花瓣粉2TranslationYAnimation.duration = 5.700f; 311 | 花瓣粉2TranslationYAnimation.values = new float[]{0.000f, -61.948f, -61.948f, -104.063f, 367.359f, 367.359f}; 312 | 花瓣粉2TranslationYAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.342f, 0.342f, 0.851f, 1.000f}; 313 | 花瓣粉2TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 314 | addAnimation(findViewsByName("huabanfen_2"), 花瓣粉2TranslationYAnimation); 315 | 316 | KeyFrameAnimation 花瓣紫RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 317 | 花瓣紫RotationAnimation.duration = 0.750f; 318 | 花瓣紫RotationAnimation.values = new float[]{0.000f, 6.283f}; 319 | 花瓣紫RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 320 | 花瓣紫RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 321 | 花瓣紫RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 322 | addAnimation(findViewsByName("huabanzi"), 花瓣紫RotationAnimation); 323 | 324 | KeyFrameAnimation 花瓣紫OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 325 | 花瓣紫OpacityAnimation.duration = 5.700f; 326 | 花瓣紫OpacityAnimation.values = new float[]{0.000f, 0.000f, 0.000f, 1.000f, 1.000f}; 327 | 花瓣紫OpacityAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.162f, 0.162f, 1.000f}; 328 | 花瓣紫OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming}; 329 | addAnimation(findViewsByName("huabanzi"), 花瓣紫OpacityAnimation); 330 | 331 | KeyFrameAnimation 花瓣紫TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 332 | 花瓣紫TranslationXAnimation.duration = 5.700f; 333 | 花瓣紫TranslationXAnimation.values = new float[]{0.000f, -181.000f, -181.000f, -257.184f, -251.969f, -251.969f}; 334 | 花瓣紫TranslationXAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.162f, 0.162f, 0.789f, 1.000f}; 335 | 花瓣紫TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 336 | addAnimation(findViewsByName("huabanzi"), 花瓣紫TranslationXAnimation); 337 | 338 | KeyFrameAnimation 花瓣紫TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 339 | 花瓣紫TranslationYAnimation.duration = 5.700f; 340 | 花瓣紫TranslationYAnimation.values = new float[]{0.000f, -43.005f, -43.005f, -75.281f, 431.255f, 431.255f}; 341 | 花瓣紫TranslationYAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.162f, 0.162f, 0.789f, 1.000f}; 342 | 花瓣紫TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, easeOutTiming, linearTiming}; 343 | addAnimation(findViewsByName("huabanzi"), 花瓣紫TranslationYAnimation); 344 | 345 | KeyFrameAnimation 花瓣紫1OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 346 | 花瓣紫1OpacityAnimation.duration = 5.700f; 347 | 花瓣紫1OpacityAnimation.values = new float[]{0.000f, 0.000f, 0.000f, 1.000f, 1.000f}; 348 | 花瓣紫1OpacityAnimation.keyTimes = new float[]{0.000f, 0.001f, 0.342f, 0.342f, 1.000f}; 349 | 花瓣紫1OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming}; 350 | addAnimation(findViewsByName("huabanzi_1"), 花瓣紫1OpacityAnimation); 351 | 352 | KeyFrameAnimation 花瓣紫1TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 353 | 花瓣紫1TranslationXAnimation.duration = 5.700f; 354 | 花瓣紫1TranslationXAnimation.values = new float[]{0.000f, 0.000f, 189.776f, 131.849f, 131.849f}; 355 | 花瓣紫1TranslationXAnimation.keyTimes = new float[]{0.000f, 0.342f, 0.342f, 0.833f, 1.000f}; 356 | 花瓣紫1TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming, linearTiming}; 357 | addAnimation(findViewsByName("huabanzi_1"), 花瓣紫1TranslationXAnimation); 358 | 359 | KeyFrameAnimation 花瓣紫1TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 360 | 花瓣紫1TranslationYAnimation.duration = 5.700f; 361 | 花瓣紫1TranslationYAnimation.values = new float[]{0.000f, 0.000f, -38.620f, 436.750f, 436.750f}; 362 | 花瓣紫1TranslationYAnimation.keyTimes = new float[]{0.000f, 0.342f, 0.342f, 0.833f, 1.000f}; 363 | 花瓣紫1TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming, linearTiming}; 364 | addAnimation(findViewsByName("huabanzi_1"), 花瓣紫1TranslationYAnimation); 365 | 366 | KeyFrameAnimation 飞机动画素材ScaleXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.scale.x"); 367 | 飞机动画素材ScaleXAnimation.duration = 5.700f; 368 | 飞机动画素材ScaleXAnimation.values = new float[]{0.483f, 0.542f, 0.636f, 0.636f}; 369 | 飞机动画素材ScaleXAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 1.000f}; 370 | 飞机动画素材ScaleXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming}; 371 | addAnimation(findViewsByName("huiji"), 飞机动画素材ScaleXAnimation); 372 | 373 | KeyFrameAnimation 飞机动画素材ScaleYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.scale.y"); 374 | 飞机动画素材ScaleYAnimation.duration = 5.700f; 375 | 飞机动画素材ScaleYAnimation.values = new float[]{0.483f, 0.542f, 0.636f, 0.636f}; 376 | 飞机动画素材ScaleYAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 1.000f}; 377 | 飞机动画素材ScaleYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming}; 378 | addAnimation(findViewsByName("huiji"), 飞机动画素材ScaleYAnimation); 379 | 380 | KeyFrameAnimation 飞机动画素材TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 381 | 飞机动画素材TranslationXAnimation.duration = 5.700f; 382 | 飞机动画素材TranslationXAnimation.values = new float[]{0.000f, -435.579f, -654.424f, -1533.303f, -1533.303f}; 383 | 飞机动画素材TranslationXAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 0.877f, 1.000f}; 384 | 飞机动画素材TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming}; 385 | addAnimation(findViewsByName("huiji"), 飞机动画素材TranslationXAnimation); 386 | 387 | KeyFrameAnimation 飞机动画素材TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 388 | 飞机动画素材TranslationYAnimation.duration = 5.700f; 389 | 飞机动画素材TranslationYAnimation.values = new float[]{0.000f, 48.051f, 89.648f, 118.563f, 118.563f}; 390 | 飞机动画素材TranslationYAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 0.877f, 1.000f}; 391 | 飞机动画素材TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming}; 392 | addAnimation(findViewsByName("huiji"), 飞机动画素材TranslationYAnimation); 393 | 394 | KeyFrameAnimation 花瓣粉3RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 395 | 花瓣粉3RotationAnimation.duration = 0.750f; 396 | 花瓣粉3RotationAnimation.values = new float[]{0.000f, 6.283f}; 397 | 花瓣粉3RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 398 | 花瓣粉3RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 399 | 花瓣粉3RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 400 | addAnimation(findViewsByName("huabanfen_3"), 花瓣粉3RotationAnimation); 401 | 402 | KeyFrameAnimation 花瓣粉3OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 403 | 花瓣粉3OpacityAnimation.duration = 5.700f; 404 | 花瓣粉3OpacityAnimation.values = new float[]{0.000f, 0.000f, 0.000f, 1.000f, 1.000f}; 405 | 花瓣粉3OpacityAnimation.keyTimes = new float[]{0.000f, 0.001f, 0.658f, 0.658f, 1.000f}; 406 | 花瓣粉3OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming}; 407 | addAnimation(findViewsByName("huabanfen_3"), 花瓣粉3OpacityAnimation); 408 | 409 | KeyFrameAnimation 花瓣粉3TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 410 | 花瓣粉3TranslationXAnimation.duration = 5.700f; 411 | 花瓣粉3TranslationXAnimation.values = new float[]{0.000f, 0.000f, -22.229f, -16.193f}; 412 | 花瓣粉3TranslationXAnimation.keyTimes = new float[]{0.000f, 0.526f, 0.526f, 1.000f}; 413 | 花瓣粉3TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming}; 414 | addAnimation(findViewsByName("huabanfen_3"), 花瓣粉3TranslationXAnimation); 415 | 416 | KeyFrameAnimation 花瓣粉3TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 417 | 花瓣粉3TranslationYAnimation.duration = 5.700f; 418 | 花瓣粉3TranslationYAnimation.values = new float[]{0.000f, 0.000f, -7.589f, 453.589f}; 419 | 花瓣粉3TranslationYAnimation.keyTimes = new float[]{0.000f, 0.526f, 0.526f, 1.000f}; 420 | 花瓣粉3TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming}; 421 | addAnimation(findViewsByName("huabanfen_3"), 花瓣粉3TranslationYAnimation); 422 | 423 | KeyFrameAnimation 花瓣粉4RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 424 | 花瓣粉4RotationAnimation.duration = 0.750f; 425 | 花瓣粉4RotationAnimation.values = new float[]{0.000f, 6.283f}; 426 | 花瓣粉4RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 427 | 花瓣粉4RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 428 | 花瓣粉4RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 429 | addAnimation(findViewsByName("huabanfen_4"), 花瓣粉4RotationAnimation); 430 | 431 | KeyFrameAnimation 花瓣粉4OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 432 | 花瓣粉4OpacityAnimation.duration = 5.700f; 433 | 花瓣粉4OpacityAnimation.values = new float[]{0.000f, 0.000f, 0.000f, 1.000f, 1.000f}; 434 | 花瓣粉4OpacityAnimation.keyTimes = new float[]{0.000f, 0.001f, 0.079f, 0.079f, 1.000f}; 435 | 花瓣粉4OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming}; 436 | addAnimation(findViewsByName("huabanfen_4"), 花瓣粉4OpacityAnimation); 437 | 438 | KeyFrameAnimation 花瓣粉4TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 439 | 花瓣粉4TranslationXAnimation.duration = 5.700f; 440 | 花瓣粉4TranslationXAnimation.values = new float[]{0.000f, 0.000f, 6.318f, 11.875f, 11.875f}; 441 | 花瓣粉4TranslationXAnimation.keyTimes = new float[]{0.000f, 0.053f, 0.053f, 0.482f, 1.000f}; 442 | 花瓣粉4TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming, linearTiming}; 443 | addAnimation(findViewsByName("huabanfen_4"), 花瓣粉4TranslationXAnimation); 444 | 445 | KeyFrameAnimation 花瓣粉4TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 446 | 花瓣粉4TranslationYAnimation.duration = 5.700f; 447 | 花瓣粉4TranslationYAnimation.values = new float[]{0.000f, 0.000f, -11.464f, 510.870f, 510.870f}; 448 | 花瓣粉4TranslationYAnimation.keyTimes = new float[]{0.000f, 0.053f, 0.053f, 0.482f, 1.000f}; 449 | 花瓣粉4TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, instantTiming, instantTiming, linearTiming, linearTiming}; 450 | addAnimation(findViewsByName("huabanfen_4"), 花瓣粉4TranslationYAnimation); 451 | 452 | KeyFrameAnimation 螺旋桨02OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 453 | 螺旋桨02OpacityAnimation.duration = 5.700f; 454 | 螺旋桨02OpacityAnimation.values = new float[]{0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 0.000f}; 455 | 螺旋桨02OpacityAnimation.keyTimes = new float[]{0.000f, 0.044f, 0.088f, 0.132f, 0.175f, 0.219f, 0.263f, 0.307f, 0.351f, 0.395f, 0.439f, 0.482f, 0.526f, 0.570f, 0.614f, 0.658f, 0.702f, 0.746f, 0.789f, 0.833f, 0.877f, 1.000f}; 456 | 螺旋桨02OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming}; 457 | addAnimation(findViewsByName("luoxuanjiang_2"), 螺旋桨02OpacityAnimation); 458 | 459 | KeyFrameAnimation 螺旋桨02ScaleXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.scale.x"); 460 | 螺旋桨02ScaleXAnimation.duration = 5.700f; 461 | 螺旋桨02ScaleXAnimation.values = new float[]{0.483f, 0.542f, 0.636f, 0.636f}; 462 | 螺旋桨02ScaleXAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 1.000f}; 463 | 螺旋桨02ScaleXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming}; 464 | addAnimation(findViewsByName("luoxuanjiang_2"), 螺旋桨02ScaleXAnimation); 465 | 466 | KeyFrameAnimation 螺旋桨02ScaleYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.scale.y"); 467 | 螺旋桨02ScaleYAnimation.duration = 5.700f; 468 | 螺旋桨02ScaleYAnimation.values = new float[]{0.483f, 0.542f, 0.636f, 0.636f}; 469 | 螺旋桨02ScaleYAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 1.000f}; 470 | 螺旋桨02ScaleYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming}; 471 | addAnimation(findViewsByName("luoxuanjiang_2"), 螺旋桨02ScaleYAnimation); 472 | 473 | KeyFrameAnimation 螺旋桨02TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 474 | 螺旋桨02TranslationXAnimation.duration = 5.700f; 475 | 螺旋桨02TranslationXAnimation.values = new float[]{0.000f, -435.579f, -654.424f, -1533.303f, -1533.303f}; 476 | 螺旋桨02TranslationXAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 0.877f, 1.000f}; 477 | 螺旋桨02TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming}; 478 | addAnimation(findViewsByName("luoxuanjiang_2"), 螺旋桨02TranslationXAnimation); 479 | 480 | KeyFrameAnimation 螺旋桨02TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 481 | 螺旋桨02TranslationYAnimation.duration = 5.700f; 482 | 螺旋桨02TranslationYAnimation.values = new float[]{0.000f, 48.051f, 89.648f, 118.563f, 118.563f}; 483 | 螺旋桨02TranslationYAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 0.877f, 1.000f}; 484 | 螺旋桨02TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming}; 485 | addAnimation(findViewsByName("luoxuanjiang_2"), 螺旋桨02TranslationYAnimation); 486 | 487 | KeyFrameAnimation 花瓣粉RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 488 | 花瓣粉RotationAnimation.duration = 0.750f; 489 | 花瓣粉RotationAnimation.values = new float[]{0.000f, 6.283f}; 490 | 花瓣粉RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 491 | 花瓣粉RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 492 | 花瓣粉RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 493 | addAnimation(findViewsByName("huabanfen"), 花瓣粉RotationAnimation); 494 | 495 | KeyFrameAnimation 花瓣粉OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 496 | 花瓣粉OpacityAnimation.duration = 5.700f; 497 | 花瓣粉OpacityAnimation.values = new float[]{0.000f, 0.000f, 0.000f, 1.000f, 1.000f}; 498 | 花瓣粉OpacityAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.131f, 0.132f, 1.000f}; 499 | 花瓣粉OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming}; 500 | addAnimation(findViewsByName("huabanfen"), 花瓣粉OpacityAnimation); 501 | 502 | KeyFrameAnimation 花瓣粉TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 503 | 花瓣粉TranslationXAnimation.duration = 5.700f; 504 | 花瓣粉TranslationXAnimation.values = new float[]{0.000f, -225.026f, -225.026f, -205.260f, -205.260f}; 505 | 花瓣粉TranslationXAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.131f, 0.132f, 1.000f}; 506 | 花瓣粉TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming}; 507 | addAnimation(findViewsByName("huabanfen"), 花瓣粉TranslationXAnimation); 508 | 509 | KeyFrameAnimation 花瓣粉TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 510 | 花瓣粉TranslationYAnimation.duration = 5.700f; 511 | 花瓣粉TranslationYAnimation.values = new float[]{0.000f, -13.484f, -13.484f, -75.281f, 418.104f, 418.104f}; 512 | 花瓣粉TranslationYAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.131f, 0.132f, 0.789f, 1.000f}; 513 | 花瓣粉TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, easeInOutTiming, linearTiming}; 514 | addAnimation(findViewsByName("huabanfen"), 花瓣粉TranslationYAnimation); 515 | 516 | KeyFrameAnimation 花瓣绿RotationAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.rotation.z"); 517 | 花瓣绿RotationAnimation.duration = 0.750f; 518 | 花瓣绿RotationAnimation.values = new float[]{0.000f, 6.283f}; 519 | 花瓣绿RotationAnimation.keyTimes = new float[]{0.000f, 1.000f}; 520 | 花瓣绿RotationAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming}; 521 | 花瓣绿RotationAnimation.repeatCount = KeyFrameAnimation.HUGE_VALF; 522 | addAnimation(findViewsByName("huabanlv"), 花瓣绿RotationAnimation); 523 | 524 | KeyFrameAnimation 花瓣绿OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 525 | 花瓣绿OpacityAnimation.duration = 5.700f; 526 | 花瓣绿OpacityAnimation.values = new float[]{0.000f, 0.000f, 0.000f, 1.000f, 1.000f}; 527 | 花瓣绿OpacityAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.180f, 0.180f, 1.000f}; 528 | 花瓣绿OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming}; 529 | addAnimation(findViewsByName("huabanlv"), 花瓣绿OpacityAnimation); 530 | 531 | KeyFrameAnimation 花瓣绿TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 532 | 花瓣绿TranslationXAnimation.duration = 5.700f; 533 | 花瓣绿TranslationXAnimation.values = new float[]{0.000f, -120.677f, -120.677f, -205.260f, -279.750f, -279.750f}; 534 | 花瓣绿TranslationXAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.180f, 0.180f, 0.789f, 1.000f}; 535 | 花瓣绿TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 536 | addAnimation(findViewsByName("huabanlv"), 花瓣绿TranslationXAnimation); 537 | 538 | KeyFrameAnimation 花瓣绿TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 539 | 花瓣绿TranslationYAnimation.duration = 5.700f; 540 | 花瓣绿TranslationYAnimation.values = new float[]{0.000f, -27.318f, -27.318f, -75.281f, 419.312f, 419.312f}; 541 | 花瓣绿TranslationYAnimation.keyTimes = new float[]{0.000f, 0.000f, 0.180f, 0.180f, 0.789f, 1.000f}; 542 | 花瓣绿TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, instantTiming, instantTiming, linearTiming, linearTiming}; 543 | addAnimation(findViewsByName("huabanlv"), 花瓣绿TranslationYAnimation); 544 | 545 | KeyFrameAnimation 螺旋桨01OpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 546 | 螺旋桨01OpacityAnimation.duration = 5.700f; 547 | 螺旋桨01OpacityAnimation.values = new float[]{0.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 0.000f, 1.000f, 1.000f}; 548 | 螺旋桨01OpacityAnimation.keyTimes = new float[]{0.000f, 0.044f, 0.088f, 0.132f, 0.175f, 0.219f, 0.263f, 0.307f, 0.351f, 0.395f, 0.439f, 0.482f, 0.526f, 0.570f, 0.614f, 0.658f, 0.702f, 0.746f, 0.789f, 0.833f, 0.877f, 1.000f}; 549 | 螺旋桨01OpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming, linearTiming}; 550 | addAnimation(findViewsByName("luoxuanjiang_1"), 螺旋桨01OpacityAnimation); 551 | 552 | KeyFrameAnimation 螺旋桨01ScaleXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.scale.x"); 553 | 螺旋桨01ScaleXAnimation.duration = 5.700f; 554 | 螺旋桨01ScaleXAnimation.values = new float[]{0.483f, 0.542f, 0.636f, 0.636f}; 555 | 螺旋桨01ScaleXAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 1.000f}; 556 | 螺旋桨01ScaleXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming}; 557 | addAnimation(findViewsByName("luoxuanjiang_1"), 螺旋桨01ScaleXAnimation); 558 | 559 | KeyFrameAnimation 螺旋桨01ScaleYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.scale.y"); 560 | 螺旋桨01ScaleYAnimation.duration = 5.700f; 561 | 螺旋桨01ScaleYAnimation.values = new float[]{0.483f, 0.542f, 0.636f, 0.636f}; 562 | 螺旋桨01ScaleYAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 1.000f}; 563 | 螺旋桨01ScaleYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming}; 564 | addAnimation(findViewsByName("luoxuanjiang_1"), 螺旋桨01ScaleYAnimation); 565 | 566 | KeyFrameAnimation 螺旋桨01TranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 567 | 螺旋桨01TranslationXAnimation.duration = 5.700f; 568 | 螺旋桨01TranslationXAnimation.values = new float[]{0.000f, -435.579f, -654.424f, -1533.303f, -1533.303f}; 569 | 螺旋桨01TranslationXAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 0.877f, 1.000f}; 570 | 螺旋桨01TranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming}; 571 | addAnimation(findViewsByName("luoxuanjiang_1"), 螺旋桨01TranslationXAnimation); 572 | 573 | KeyFrameAnimation 螺旋桨01TranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 574 | 螺旋桨01TranslationYAnimation.duration = 5.700f; 575 | 螺旋桨01TranslationYAnimation.values = new float[]{0.000f, 48.051f, 89.648f, 118.563f, 118.563f}; 576 | 螺旋桨01TranslationYAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 0.877f, 1.000f}; 577 | 螺旋桨01TranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming}; 578 | addAnimation(findViewsByName("luoxuanjiang_1"), 螺旋桨01TranslationYAnimation); 579 | 580 | KeyFrameAnimation afontOpacityAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("opacity"); 581 | afontOpacityAnimation.duration = 5.700f; 582 | afontOpacityAnimation.values = new float[]{1f, 1f, 0f, 0f}; 583 | afontOpacityAnimation.keyTimes = new float[]{0.000f, 0.658f, 0.877f, 1.000f}; 584 | afontOpacityAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming}; 585 | addAnimation(findViewsByName("afont"), afontOpacityAnimation); 586 | 587 | KeyFrameAnimation afontTranslationXAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.x"); 588 | afontTranslationXAnimation.duration = 5.700f; 589 | afontTranslationXAnimation.values = new float[]{1490.000f, 1060.000f, 740.000f, -60.000f, -60.000f}; 590 | afontTranslationXAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 0.877f, 1.000f}; 591 | afontTranslationXAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming}; 592 | addAnimation(findViewsByName("afont"), afontTranslationXAnimation); 593 | 594 | KeyFrameAnimation afontTranslationYAnimation = KeyFrameAnimation.newKeyFrameAnimationWithIOSKeyPath("transform.translation.y"); 595 | afontTranslationYAnimation.duration = 5.700f; 596 | afontTranslationYAnimation.values = new float[]{40.000f, 80f, 100f, 120f, 120f}; 597 | afontTranslationYAnimation.keyTimes = new float[]{0.000f, 0.132f, 0.658f, 0.877f, 1.000f}; 598 | afontTranslationYAnimation.timingFunctions = new TimeInterpolator[]{null, linearTiming, linearTiming, linearTiming, linearTiming}; 599 | addAnimation(findViewsByName("afont"), afontTranslationYAnimation); 600 | return true; 601 | } 602 | 603 | } 604 | -------------------------------------------------------------------------------- /demo/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 |