├── .gitignore ├── LearnAnimation.iml ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── net │ │ └── cattaka │ │ └── learnanimation │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── net │ │ └── cattaka │ │ └── learnanimation │ │ ├── Aa1Activity.java │ │ ├── Aa2Activity.java │ │ ├── At1Activity.java │ │ ├── At2Activity.java │ │ ├── AvActivity.java │ │ ├── Da1Activity.java │ │ ├── Da2Activity.java │ │ ├── FaActivity.java │ │ ├── FtActivity.java │ │ ├── MainActivity.java │ │ ├── Pa1Activity.java │ │ ├── Pa2Activity.java │ │ ├── PaFlex1Activity.java │ │ ├── PaFlex2Activity.java │ │ ├── TaActivity.java │ │ ├── VaActivity.java │ │ ├── VpaActivity.java │ │ ├── fragment │ │ ├── Fa1Fragment.java │ │ ├── Fa2Fragment.java │ │ ├── Ft1Fragment.java │ │ └── Ft2Fragment.java │ │ ├── transition │ │ ├── PathProperty.java │ │ ├── RectEvaluator.java │ │ └── SourceChangeBounds.java │ │ ├── utils │ │ └── RelativeLayoutAnimatorHelper.java │ │ └── view │ │ └── CustomPropertyView.java │ └── res │ ├── anim │ ├── aa_slide_in.xml │ ├── aa_slide_out.xml │ ├── av_path_morph.xml │ ├── av_translation.xml │ ├── va_all.xml │ ├── va_all_share_interpolator.xml │ ├── va_alpha.xml │ ├── va_move.xml │ ├── va_rotate.xml │ └── va_scale.xml │ ├── animator │ ├── pa_all.xml │ ├── pa_all_share_interpolator.xml │ ├── pa_alpha.xml │ ├── pa_custom_property.xml │ ├── pa_move.xml │ ├── pa_rotate.xml │ └── pa_scale.xml │ ├── drawable-hdpi │ ├── ctklabo_logo256.png │ ├── ctklabo_rb256.png │ ├── roll_cat_1.png │ ├── roll_cat_2.png │ └── roll_cat_3.png │ ├── drawable-xhdpi │ └── logo.png │ ├── drawable │ ├── avd.xml │ ├── roll_cat.xml │ └── vector_drawable.xml │ ├── layout │ ├── activity_aa_1.xml │ ├── activity_aa_2.xml │ ├── activity_at_1.xml │ ├── activity_at_2.xml │ ├── activity_av.xml │ ├── activity_da_1.xml │ ├── activity_da_2.xml │ ├── activity_fa.xml │ ├── activity_ft.xml │ ├── activity_main.xml │ ├── activity_pa.xml │ ├── activity_pa_2.xml │ ├── activity_pa_flex_1.xml │ ├── activity_pa_flex_2.xml │ ├── activity_ta.xml │ ├── activity_ta_child_logo.xml │ ├── activity_ta_child_rb.xml │ ├── activity_va.xml │ ├── activity_vpa.xml │ ├── fragment_fa_1.xml │ ├── fragment_fa_2.xml │ ├── fragment_ft_1.xml │ └── fragment_ft_2.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── transition │ ├── ta.xml │ ├── ta_logo.xml │ └── ta_rb.xml │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ ├── styles.xml │ └── values.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── misc └── cat.svg └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | #built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Windows thumbnail db 19 | Thumbs.db 20 | 21 | # OSX files 22 | .DS_Store 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | 28 | # Android Studio 29 | .idea 30 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 31 | .gradle 32 | build/ 33 | 34 | -------------------------------------------------------------------------------- /LearnAnimation.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | buildToolsVersion "28.0.3" 6 | 7 | defaultConfig { 8 | applicationId "net.cattaka.learnanimation" 9 | minSdkVersion 22 10 | targetSdkVersion 28 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 | implementation fileTree(dir: 'libs', include: ['*.jar']) 24 | implementation 'com.android.support:appcompat-v7:28.0.0' 25 | implementation 'com.android.support:transition:28.0.0' 26 | } 27 | -------------------------------------------------------------------------------- /app/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 /home/cattaka/opt/android-sdk-linux/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 | -------------------------------------------------------------------------------- /app/src/androidTest/java/net/cattaka/learnanimation/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 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 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/Aa1Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.app.ActivityOptions; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.transition.Explode; 8 | import android.transition.Fade; 9 | import android.util.Pair; 10 | import android.view.View; 11 | import android.view.Window; 12 | 13 | /** 14 | * Created by takao on 2015/10/28. 15 | */ 16 | public class Aa1Activity extends Activity implements View.OnClickListener { 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 21 | setContentView(R.layout.activity_aa_1); 22 | 23 | findViewById(R.id.image_logo).setOnClickListener(this); 24 | } 25 | 26 | @Override 27 | public void onClick(View view) { 28 | if (view.getId() == R.id.image_logo) { 29 | if (true) { 30 | Intent intent = new Intent(this, At2Activity.class); 31 | startActivity(intent); 32 | overridePendingTransition(R.anim.aa_slide_in, R.anim.aa_slide_out); 33 | } else { 34 | Intent intent = new Intent(this, At2Activity.class); 35 | ActivityOptions options = ActivityOptions.makeCustomAnimation(this, R.anim.aa_slide_in, R.anim.aa_slide_out); 36 | startActivity(intent, options.toBundle()); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/Aa2Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.Window; 6 | 7 | /** 8 | * Created by takao on 2015/10/28. 9 | */ 10 | public class Aa2Activity extends Activity { 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 15 | setContentView(R.layout.activity_aa_2); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/At1Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.app.ActivityOptions; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.transition.Explode; 8 | import android.transition.Fade; 9 | import android.util.Pair; 10 | import android.view.View; 11 | import android.view.Window; 12 | 13 | /** 14 | * Created by takao on 2015/10/28. 15 | */ 16 | public class At1Activity extends Activity implements View.OnClickListener { 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 21 | setContentView(R.layout.activity_at_1); 22 | 23 | findViewById(R.id.image_logo).setOnClickListener(this); 24 | } 25 | 26 | @Override 27 | public void onClick(View view) { 28 | if (view.getId() == R.id.image_logo) { 29 | // ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation( 30 | // this, 31 | // view.findViewById(R.id.image_logo), getString(R.string.transition_name_image_logo) 32 | // ); 33 | ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation( 34 | this, 35 | new Pair<>(view.findViewById(R.id.image_logo), getString(R.string.transition_name_image_logo)) 36 | ); 37 | 38 | getWindow().setEnterTransition(new Fade()); 39 | getWindow().setExitTransition(new Explode()); 40 | 41 | Intent intent = new Intent(this, At2Activity.class); 42 | startActivity(intent, options.toBundle()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/At2Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.Window; 6 | 7 | /** 8 | * Created by takao on 2015/10/28. 9 | */ 10 | public class At2Activity extends Activity { 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 15 | setContentView(R.layout.activity_at_2); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/AvActivity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.graphics.drawable.AnimatedVectorDrawable; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.ImageView; 8 | 9 | /** 10 | * Created by takao on 2015/10/28. 11 | */ 12 | public class AvActivity extends Activity implements View.OnClickListener { 13 | ImageView mLogoImage; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_av); 19 | 20 | mLogoImage = (ImageView) findViewById(R.id.image_logo); 21 | mLogoImage.setOnClickListener(this); 22 | } 23 | 24 | @Override 25 | public void onClick(View v) { 26 | if (v.getId() == R.id.image_logo) { 27 | AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable(R.drawable.avd); 28 | mLogoImage.setImageDrawable(drawable); 29 | drawable.start(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/Da1Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.graphics.drawable.AnimationDrawable; 5 | import android.os.Bundle; 6 | import android.widget.ImageView; 7 | 8 | /** 9 | * Created by takao on 2015/10/28. 10 | */ 11 | public class Da1Activity extends Activity { 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_da_1); 17 | } 18 | 19 | @Override 20 | public void onWindowFocusChanged(boolean hasFocus) { 21 | super.onWindowFocusChanged(hasFocus); 22 | if (hasFocus) { 23 | ImageView logoImage = (ImageView) findViewById(R.id.image_logo); 24 | AnimationDrawable rollCatDrawable = (AnimationDrawable) logoImage.getDrawable(); 25 | rollCatDrawable.start(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/Da2Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.graphics.drawable.AnimationDrawable; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.ImageView; 8 | 9 | /** 10 | * Created by takao on 2015/10/28. 11 | */ 12 | public class Da2Activity extends Activity implements View.OnClickListener { 13 | ImageView mLogoImage; 14 | AnimationDrawable mRollCatDrawable; 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_da_2); 20 | 21 | mLogoImage = (ImageView) findViewById(R.id.image_logo); 22 | mLogoImage.setOnClickListener(this); 23 | 24 | mRollCatDrawable = (AnimationDrawable) mLogoImage.getDrawable(); 25 | } 26 | 27 | @Override 28 | public void onClick(View view) { 29 | if (view.getId() == R.id.image_logo) { 30 | if (mRollCatDrawable.isRunning()) { 31 | mRollCatDrawable.stop(); 32 | } else { 33 | mRollCatDrawable.start(); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/FaActivity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.app.FragmentTransaction; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import net.cattaka.learnanimation.fragment.Fa1Fragment; 12 | import net.cattaka.learnanimation.fragment.Fa2Fragment; 13 | 14 | /** 15 | * Created by takao on 2015/10/28. 16 | */ 17 | public class FaActivity extends AppCompatActivity implements View.OnClickListener { 18 | ViewGroup mContainerLayout; 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_fa); 24 | 25 | mContainerLayout = (ViewGroup) findViewById(R.id.layout_container); 26 | 27 | findViewById(R.id.button_item_1).setOnClickListener(this); 28 | findViewById(R.id.button_item_2).setOnClickListener(this); 29 | } 30 | 31 | @Override 32 | public void onClick(View view) { 33 | if (view.getId() == R.id.button_item_1) { 34 | Fragment fragment = Fa1Fragment.newInstance(); 35 | FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 36 | ft.setCustomAnimations(R.anim.aa_slide_in, R.anim.aa_slide_out); 37 | ft.replace(R.id.layout_fragment, fragment); 38 | ft.addToBackStack(null); 39 | ft.commit(); 40 | } else if (view.getId() == R.id.button_item_2) { 41 | Fragment fragment = Fa2Fragment.newInstance(); 42 | FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 43 | ft.setCustomAnimations(R.anim.aa_slide_in, R.anim.aa_slide_out); 44 | ft.replace(R.id.layout_fragment, fragment); 45 | ft.addToBackStack(null); 46 | ft.commit(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/FtActivity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.os.Bundle; 4 | import android.support.transition.Fade; 5 | import android.support.transition.TransitionSet; 6 | import android.support.v4.app.Fragment; 7 | import android.support.v4.app.FragmentTransaction; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import net.cattaka.learnanimation.fragment.Ft1Fragment; 13 | import net.cattaka.learnanimation.fragment.Ft2Fragment; 14 | import net.cattaka.learnanimation.transition.SourceChangeBounds; 15 | 16 | /** 17 | * Created by takao on 2015/10/28. 18 | */ 19 | public class FtActivity extends AppCompatActivity implements View.OnClickListener { 20 | ViewGroup mContainerLayout; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_ft); 26 | 27 | mContainerLayout = (ViewGroup) findViewById(R.id.layout_container); 28 | 29 | findViewById(R.id.button_item_1).setOnClickListener(this); 30 | findViewById(R.id.button_item_2).setOnClickListener(this); 31 | } 32 | 33 | @Override 34 | public void onClick(View view) { 35 | if (view.getId() == R.id.button_item_1) { 36 | Fragment fragment = Ft1Fragment.newInstance(); 37 | fragment.setEnterTransition(new Fade(Fade.IN)); 38 | fragment.setExitTransition(new Fade(Fade.OUT)); 39 | fragment.setSharedElementEnterTransition(new TransitionSet().addTransition(new SourceChangeBounds())); 40 | fragment.setSharedElementReturnTransition(new TransitionSet().addTransition(new SourceChangeBounds())); 41 | 42 | FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 43 | 44 | Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.layout_fragment); 45 | if (currentFragment != null && currentFragment.getView() != null) { 46 | View image = currentFragment.getView().findViewById(R.id.image_logo); 47 | ft.addSharedElement(image, image.getTransitionName()); 48 | View aButton = currentFragment.getView().findViewById(R.id.button_a); 49 | ft.addSharedElement(aButton, aButton.getTransitionName()); 50 | } 51 | ft.replace(R.id.layout_fragment, fragment); 52 | ft.addToBackStack(null); 53 | ft.commit(); 54 | } else if (view.getId() == R.id.button_item_2) { 55 | Fragment fragment = Ft2Fragment.newInstance(); 56 | fragment.setEnterTransition(new Fade(Fade.IN)); 57 | fragment.setExitTransition(new Fade(Fade.OUT)); 58 | fragment.setSharedElementEnterTransition(new TransitionSet().addTransition(new SourceChangeBounds())); 59 | fragment.setSharedElementReturnTransition(new TransitionSet().addTransition(new SourceChangeBounds())); 60 | 61 | FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 62 | 63 | Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.layout_fragment); 64 | if (currentFragment != null && currentFragment.getView() != null) { 65 | View image = currentFragment.getView().findViewById(R.id.image_logo); 66 | ft.addSharedElement(image, image.getTransitionName()); 67 | View aButton = currentFragment.getView().findViewById(R.id.button_a); 68 | ft.addSharedElement(aButton, aButton.getTransitionName()); 69 | } 70 | ft.replace(R.id.layout_fragment, fragment); 71 | ft.addToBackStack(null); 72 | ft.commit(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/MainActivity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.AdapterView; 8 | import android.widget.ArrayAdapter; 9 | import android.widget.ListView; 10 | 11 | import java.util.Arrays; 12 | 13 | public class MainActivity extends Activity implements AdapterView.OnItemClickListener { 14 | 15 | ListView mListView; 16 | 17 | @Override 18 | protected void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_main); 21 | 22 | mListView = (ListView) findViewById(R.id.list); 23 | mListView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Arrays.asList(ActivityItem.values()))); 24 | mListView.setOnItemClickListener(this); 25 | 26 | } 27 | 28 | @Override 29 | public void onItemClick(AdapterView adapterView, View view, int position, long id) { 30 | if (adapterView.getId() == R.id.list) { 31 | ActivityItem item = (ActivityItem) adapterView.getItemAtPosition(position); 32 | startActivity(new Intent(this, item.mActivityClass)); 33 | } 34 | } 35 | 36 | public enum ActivityItem { 37 | ACTIVITY_ANIMATION("Activity Animation", Aa1Activity.class), 38 | ACTIVITY_TRANSITION("Activity Transition", At1Activity.class), 39 | FRAGMENT_ANIMATION("Fragment Animation", FaActivity.class), 40 | FRAGMENT_TRANSITION("Fragment Transition", FtActivity.class), 41 | DRAWABLE_ANIMATION_1("Drawable Animation 1", Da1Activity.class), 42 | DRAWABLE_ANIMATION_2("Drawable Animation 2", Da2Activity.class), 43 | VIEW_ANIMATION("View Animation", VaActivity.class), 44 | PROPERTY_ANIMATION_1("Property Animation 1", Pa1Activity.class), 45 | PROPERTY_ANIMATION_2("Property Animation 2", Pa2Activity.class), 46 | VIEW_PROPERTY_ANIMATOR("View Property Animator", VpaActivity.class), 47 | TRANSITION_ANIMATION("Transition Animation", TaActivity.class), 48 | PROPERTY_ANIMATION_SAMPLE_FLEX_1("Property Animation - Sample Flex 1", PaFlex1Activity.class), 49 | PROPERTY_ANIMATION_SAMPLE_FLEX_2("Property Animation - Sample Flex 2", PaFlex2Activity.class), 50 | ANIMATION_VECTOR("Animation Vector", AvActivity.class), 51 | // 52 | ; 53 | final String mLabel; 54 | final Class mActivityClass; 55 | 56 | ActivityItem(String label, Class activityClass) { 57 | mLabel = label; 58 | mActivityClass = activityClass; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return mLabel; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/Pa1Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorInflater; 5 | import android.animation.AnimatorSet; 6 | import android.animation.ObjectAnimator; 7 | import android.app.Activity; 8 | import android.graphics.drawable.AnimationDrawable; 9 | import android.os.Bundle; 10 | import android.view.View; 11 | import android.view.animation.BounceInterpolator; 12 | 13 | import java.util.ArrayList; 14 | 15 | /** 16 | * Created by takao on 2015/10/28. 17 | */ 18 | public class Pa1Activity extends Activity implements View.OnClickListener { 19 | View mTargetButton; 20 | AnimationDrawable mRollCatDrawable; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_pa); 26 | 27 | mTargetButton = findViewById(R.id.button_target); 28 | 29 | findViewById(R.id.button_move_code).setOnClickListener(this); 30 | findViewById(R.id.button_rotate_code).setOnClickListener(this); 31 | findViewById(R.id.button_scale_code).setOnClickListener(this); 32 | findViewById(R.id.button_alpha_code).setOnClickListener(this); 33 | findViewById(R.id.button_all_code).setOnClickListener(this); 34 | findViewById(R.id.button_all_share_interpolator_code).setOnClickListener(this); 35 | findViewById(R.id.button_move_xml).setOnClickListener(this); 36 | findViewById(R.id.button_rotate_xml).setOnClickListener(this); 37 | findViewById(R.id.button_scale_xml).setOnClickListener(this); 38 | findViewById(R.id.button_alpha_xml).setOnClickListener(this); 39 | findViewById(R.id.button_all_xml).setOnClickListener(this); 40 | } 41 | 42 | @Override 43 | public void onClick(View view) { 44 | if (view.getId() == R.id.button_move_code) { 45 | ObjectAnimator animator = ObjectAnimator.ofFloat(mTargetButton, "translationX", 0f, mTargetButton.getWidth()); 46 | animator.setInterpolator(new BounceInterpolator()); 47 | animator.setDuration(3000); 48 | animator.start(); 49 | } else if (view.getId() == R.id.button_rotate_code) { 50 | ObjectAnimator animator = ObjectAnimator.ofFloat(mTargetButton, "rotation", 0f, 360f); 51 | animator.setInterpolator(new BounceInterpolator()); 52 | animator.setDuration(3000); 53 | animator.start(); 54 | } else if (view.getId() == R.id.button_scale_code) { 55 | ObjectAnimator animator = ObjectAnimator.ofFloat(mTargetButton, "scaleX", 1f, 0f, 1f); 56 | animator.setInterpolator(new BounceInterpolator()); 57 | animator.setDuration(3000); 58 | animator.start(); 59 | } else if (view.getId() == R.id.button_alpha_code) { 60 | ObjectAnimator animator = ObjectAnimator.ofFloat(mTargetButton, "alpha", 1f, 0f, 1f); 61 | animator.setInterpolator(new BounceInterpolator()); 62 | animator.setDuration(3000); 63 | animator.start(); 64 | } else if (view.getId() == R.id.button_all_code) { 65 | ObjectAnimator translationX = ObjectAnimator.ofFloat(mTargetButton, "translationX", 0f, mTargetButton.getWidth()); 66 | translationX.setInterpolator(new BounceInterpolator()); 67 | translationX.setDuration(3000); 68 | 69 | ObjectAnimator rotation = ObjectAnimator.ofFloat(mTargetButton, "rotation", 0f, 360f); 70 | rotation.setInterpolator(new BounceInterpolator()); 71 | rotation.setDuration(3000); 72 | 73 | ObjectAnimator scaleX = ObjectAnimator.ofFloat(mTargetButton, "scaleX", 1f, 0f, 1f); 74 | scaleX.setInterpolator(new BounceInterpolator()); 75 | scaleX.setDuration(3000); 76 | 77 | ObjectAnimator alpha = ObjectAnimator.ofFloat(mTargetButton, "alpha", 1f, 0f, 1f); 78 | alpha.setInterpolator(new BounceInterpolator()); 79 | alpha.setDuration(3000); 80 | 81 | ArrayList animators = new ArrayList<>(); 82 | animators.add(translationX); 83 | animators.add(rotation); 84 | animators.add(scaleX); 85 | animators.add(alpha); 86 | 87 | AnimatorSet as = new AnimatorSet(); 88 | as.playTogether(animators); 89 | as.start(); 90 | } else if (view.getId() == R.id.button_all_share_interpolator_code) { 91 | ArrayList animators = new ArrayList<>(); 92 | 93 | ObjectAnimator translationX = ObjectAnimator.ofFloat(mTargetButton, "translationX", 0f, mTargetButton.getWidth()); 94 | animators.add(translationX); 95 | 96 | ObjectAnimator rotation = ObjectAnimator.ofFloat(mTargetButton, "rotation", 0f, 360f); 97 | animators.add(rotation); 98 | 99 | ObjectAnimator scaleX = ObjectAnimator.ofFloat(mTargetButton, "scaleX", 1f, 0f, 1f); 100 | animators.add(scaleX); 101 | 102 | ObjectAnimator alpha = ObjectAnimator.ofFloat(mTargetButton, "alpha", 1f, 0f, 1f); 103 | animators.add(alpha); 104 | 105 | AnimatorSet as = new AnimatorSet(); 106 | as.setInterpolator(new BounceInterpolator()); 107 | as.setDuration(3000); 108 | as.playTogether(animators); 109 | as.start(); 110 | } else if (view.getId() == R.id.button_move_xml) { 111 | Animator anim = AnimatorInflater.loadAnimator(this, R.animator.pa_move); 112 | anim.setTarget(mTargetButton); 113 | anim.start(); 114 | } else if (view.getId() == R.id.button_rotate_xml) { 115 | Animator anim = AnimatorInflater.loadAnimator(this, R.animator.pa_rotate); 116 | anim.setTarget(mTargetButton); 117 | anim.start(); 118 | } else if (view.getId() == R.id.button_scale_xml) { 119 | Animator anim = AnimatorInflater.loadAnimator(this, R.animator.pa_scale); 120 | anim.setTarget(mTargetButton); 121 | anim.start(); 122 | } else if (view.getId() == R.id.button_alpha_xml) { 123 | Animator anim = AnimatorInflater.loadAnimator(this, R.animator.pa_alpha); 124 | anim.setTarget(mTargetButton); 125 | anim.start(); 126 | } else if (view.getId() == R.id.button_all_xml) { 127 | Animator anim = AnimatorInflater.loadAnimator(this, R.animator.pa_all); 128 | anim.setTarget(mTargetButton); 129 | anim.start(); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/Pa2Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorInflater; 5 | import android.animation.ObjectAnimator; 6 | import android.app.Activity; 7 | import android.graphics.drawable.AnimationDrawable; 8 | import android.os.Bundle; 9 | import android.view.View; 10 | import android.view.animation.BounceInterpolator; 11 | 12 | import net.cattaka.learnanimation.view.CustomPropertyView; 13 | 14 | /** 15 | * Created by takao on 2015/10/28. 16 | */ 17 | public class Pa2Activity extends Activity implements View.OnClickListener { 18 | CustomPropertyView mTargetView; 19 | AnimationDrawable mRollCatDrawable; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_pa_2); 25 | 26 | mTargetView = (CustomPropertyView) findViewById(R.id.text_target); 27 | 28 | findViewById(R.id.button_custom_property_code).setOnClickListener(this); 29 | findViewById(R.id.button_custom_property_xml).setOnClickListener(this); 30 | } 31 | 32 | @Override 33 | public void onClick(View view) { 34 | if (view.getId() == R.id.button_custom_property_code) { 35 | ObjectAnimator animator = ObjectAnimator.ofInt(mTargetView, "customProperty", 0, 1000); 36 | animator.setInterpolator(new BounceInterpolator()); 37 | animator.setDuration(1000); 38 | animator.start(); 39 | } else if (view.getId() == R.id.button_custom_property_xml) { 40 | Animator anim = AnimatorInflater.loadAnimator(this, R.animator.pa_custom_property); 41 | anim.setTarget(mTargetView); 42 | anim.start(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/PaFlex1Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.animation.ObjectAnimator; 4 | import android.app.Activity; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | /** 11 | * Created by takao on 2015/11/11. 12 | */ 13 | public class PaFlex1Activity extends Activity implements View.OnClickListener { 14 | TextView mLabelText; 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_pa_flex_1); 20 | 21 | // Find views 22 | mLabelText = (TextView) findViewById(R.id.text_label); 23 | 24 | // Bind event handlers 25 | findViewById(R.id.button_hide).setOnClickListener(this); 26 | findViewById(R.id.button_show).setOnClickListener(this); 27 | } 28 | 29 | @Override 30 | public void onClick(View view) { 31 | if (view.getId() == R.id.button_hide) { 32 | int from = mLabelText.getWidth(); 33 | int to = 0; 34 | ObjectAnimator.ofInt(mLabelText, "width", from, to).start(); 35 | } else if (view.getId() == R.id.button_show) { 36 | int from = mLabelText.getWidth(); 37 | mLabelText.setMaxWidth(Integer.MAX_VALUE); 38 | mLabelText.setMaxHeight(Integer.MAX_VALUE); 39 | mLabelText.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 40 | int to = mLabelText.getMeasuredWidth(); 41 | ObjectAnimator.ofInt(mLabelText, "width", from, to).start(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/PaFlex2Activity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.animation.ObjectAnimator; 4 | import android.app.Activity; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.TextView; 8 | 9 | import net.cattaka.learnanimation.utils.RelativeLayoutAnimatorHelper; 10 | 11 | /** 12 | * Created by takao on 2015/11/11. 13 | */ 14 | public class PaFlex2Activity extends Activity implements View.OnClickListener { 15 | TextView mLabelText; 16 | RelativeLayoutAnimatorHelper mLabelTextHelper; 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_pa_flex_2); 22 | 23 | // Find views 24 | mLabelText = (TextView) findViewById(R.id.text_label); 25 | 26 | // Bind event handlers 27 | findViewById(R.id.button_hide).setOnClickListener(this); 28 | findViewById(R.id.button_show).setOnClickListener(this); 29 | 30 | mLabelTextHelper = new RelativeLayoutAnimatorHelper(mLabelText); 31 | } 32 | 33 | @Override 34 | public void onClick(View view) { 35 | if (view.getId() == R.id.button_hide) { 36 | int from = 0; 37 | int to = -mLabelText.getWidth(); 38 | ObjectAnimator.ofInt(mLabelTextHelper, "rightMargin", from, to).start(); 39 | } else if (view.getId() == R.id.button_show) { 40 | int from = mLabelTextHelper.getRightMargin(); 41 | int to = 0; 42 | ObjectAnimator.ofInt(mLabelTextHelper, "rightMargin", from, to).start(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/TaActivity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.transition.Scene; 6 | import android.transition.Transition; 7 | import android.transition.TransitionInflater; 8 | import android.transition.TransitionManager; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.Toast; 12 | 13 | /** 14 | * Created by takao on 2015/10/28. 15 | */ 16 | public class TaActivity extends Activity implements View.OnClickListener { 17 | ViewGroup mContainerLayout; 18 | 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | setContentView(R.layout.activity_ta); 23 | 24 | mContainerLayout = (ViewGroup) findViewById(R.id.layout_container); 25 | 26 | findViewById(R.id.button_item_1).setOnClickListener(this); 27 | findViewById(R.id.button_item_2).setOnClickListener(this); 28 | } 29 | 30 | @Override 31 | public void onClick(View view) { 32 | if (view.getId() == R.id.button_item_1) { 33 | Scene scene = Scene.getSceneForLayout(mContainerLayout, R.layout.activity_ta_child_logo, this); 34 | scene.setEnterAction(new Runnable() { 35 | @Override 36 | public void run() { 37 | Toast.makeText(TaActivity.this, "Enter action", Toast.LENGTH_SHORT).show(); 38 | } 39 | }); 40 | scene.setExitAction(new Runnable() { 41 | @Override 42 | public void run() { 43 | Toast.makeText(TaActivity.this, "Exit action", Toast.LENGTH_SHORT).show(); 44 | } 45 | }); 46 | Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.ta); 47 | TransitionManager.go(scene, transition); 48 | } else if (view.getId() == R.id.button_item_2) { 49 | Scene scene = Scene.getSceneForLayout(mContainerLayout, R.layout.activity_ta_child_rb, this); 50 | Transition transition = TransitionInflater.from(this).inflateTransition(R.transition.ta); 51 | TransitionManager.go(scene, transition); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/VaActivity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.graphics.drawable.AnimationDrawable; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.view.animation.AlphaAnimation; 8 | import android.view.animation.Animation; 9 | import android.view.animation.AnimationSet; 10 | import android.view.animation.AnimationUtils; 11 | import android.view.animation.BounceInterpolator; 12 | import android.view.animation.RotateAnimation; 13 | import android.view.animation.ScaleAnimation; 14 | import android.view.animation.TranslateAnimation; 15 | 16 | /** 17 | * Created by takao on 2015/10/28. 18 | */ 19 | public class VaActivity extends Activity implements View.OnClickListener { 20 | View mTargetButton; 21 | AnimationDrawable mRollCatDrawable; 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_va); 27 | 28 | mTargetButton = findViewById(R.id.button_target); 29 | 30 | findViewById(R.id.button_move_code).setOnClickListener(this); 31 | findViewById(R.id.button_rotate_code).setOnClickListener(this); 32 | findViewById(R.id.button_scale_code).setOnClickListener(this); 33 | findViewById(R.id.button_alpha_code).setOnClickListener(this); 34 | findViewById(R.id.button_all_code).setOnClickListener(this); 35 | findViewById(R.id.button_all_share_interpolator_code).setOnClickListener(this); 36 | findViewById(R.id.button_move_xml).setOnClickListener(this); 37 | findViewById(R.id.button_rotate_xml).setOnClickListener(this); 38 | findViewById(R.id.button_scale_xml).setOnClickListener(this); 39 | findViewById(R.id.button_alpha_xml).setOnClickListener(this); 40 | findViewById(R.id.button_all_xml).setOnClickListener(this); 41 | findViewById(R.id.button_all_share_interpolator_xml).setOnClickListener(this); 42 | } 43 | 44 | @Override 45 | public void onClick(View view) { 46 | if (view.getId() == R.id.button_move_code) { 47 | TranslateAnimation anim = new TranslateAnimation(0, mTargetButton.getWidth(), 0, mTargetButton.getHeight()); 48 | anim.setInterpolator(new BounceInterpolator()); 49 | anim.setDuration(3000); 50 | mTargetButton.startAnimation(anim); 51 | } else if (view.getId() == R.id.button_rotate_code) { 52 | RotateAnimation anim = new RotateAnimation(0, 360, mTargetButton.getWidth() / 2, mTargetButton.getHeight() / 2); 53 | anim.setInterpolator(new BounceInterpolator()); 54 | anim.setDuration(3000); 55 | mTargetButton.startAnimation(anim); 56 | } else if (view.getId() == R.id.button_scale_code) { 57 | ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, mTargetButton.getWidth() / 2, mTargetButton.getHeight() / 2); 58 | anim.setInterpolator(new BounceInterpolator()); 59 | anim.setDuration(3000); 60 | mTargetButton.startAnimation(anim); 61 | } else if (view.getId() == R.id.button_alpha_code) { 62 | AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f); 63 | anim.setInterpolator(new BounceInterpolator()); 64 | anim.setDuration(3000); 65 | mTargetButton.startAnimation(anim); 66 | } else if (view.getId() == R.id.button_all_code) { 67 | TranslateAnimation translate = new TranslateAnimation(0, mTargetButton.getWidth(), 0, mTargetButton.getHeight()); 68 | translate.setInterpolator(new BounceInterpolator()); 69 | translate.setDuration(3000); 70 | 71 | RotateAnimation rotate = new RotateAnimation(0, 360, mTargetButton.getWidth() / 2, mTargetButton.getHeight() / 2); 72 | rotate.setInterpolator(new BounceInterpolator()); 73 | rotate.setDuration(3000); 74 | 75 | ScaleAnimation scale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, mTargetButton.getWidth() / 2, mTargetButton.getHeight() / 2); 76 | scale.setInterpolator(new BounceInterpolator()); 77 | scale.setDuration(3000); 78 | 79 | AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f); 80 | alpha.setInterpolator(new BounceInterpolator()); 81 | alpha.setDuration(3000); 82 | 83 | boolean shareInterpolator = false; 84 | AnimationSet as = new AnimationSet(shareInterpolator); 85 | as.addAnimation(translate); 86 | as.addAnimation(rotate); 87 | as.addAnimation(scale); 88 | as.addAnimation(alpha); 89 | mTargetButton.startAnimation(as); 90 | } else if (view.getId() == R.id.button_all_share_interpolator_code) { 91 | TranslateAnimation translate = new TranslateAnimation(0, mTargetButton.getWidth(), 0, mTargetButton.getHeight()); 92 | RotateAnimation rotate = new RotateAnimation(0, 360, mTargetButton.getWidth() / 2, mTargetButton.getHeight() / 2); 93 | ScaleAnimation scale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, mTargetButton.getWidth() / 2, mTargetButton.getHeight() / 2); 94 | AlphaAnimation alpha = new AlphaAnimation(1.0f, 0.0f); 95 | 96 | boolean shareInterpolator = true; 97 | AnimationSet as = new AnimationSet(shareInterpolator); 98 | as.addAnimation(translate); 99 | as.addAnimation(rotate); 100 | as.addAnimation(scale); 101 | as.addAnimation(alpha); 102 | as.setInterpolator(new BounceInterpolator()); 103 | as.setDuration(3000); 104 | mTargetButton.startAnimation(as); 105 | } else if (view.getId() == R.id.button_move_xml) { 106 | Animation anim = AnimationUtils.loadAnimation(this, R.anim.va_move); 107 | mTargetButton.startAnimation(anim); 108 | } else if (view.getId() == R.id.button_rotate_xml) { 109 | Animation anim = AnimationUtils.loadAnimation(this, R.anim.va_rotate); 110 | mTargetButton.startAnimation(anim); 111 | } else if (view.getId() == R.id.button_scale_xml) { 112 | Animation anim = AnimationUtils.loadAnimation(this, R.anim.va_scale); 113 | mTargetButton.startAnimation(anim); 114 | } else if (view.getId() == R.id.button_alpha_xml) { 115 | Animation anim = AnimationUtils.loadAnimation(this, R.anim.va_alpha); 116 | mTargetButton.startAnimation(anim); 117 | } else if (view.getId() == R.id.button_all_xml) { 118 | Animation anim = AnimationUtils.loadAnimation(this, R.anim.va_all); 119 | mTargetButton.startAnimation(anim); 120 | } else if (view.getId() == R.id.button_all_share_interpolator_xml) { 121 | Animation anim = AnimationUtils.loadAnimation(this, R.anim.va_all_share_interpolator); 122 | mTargetButton.startAnimation(anim); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/VpaActivity.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | 7 | /** 8 | * Created by takao on 2015/10/28. 9 | */ 10 | public class VpaActivity extends Activity implements View.OnClickListener { 11 | View mTargetButton; 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_vpa); 17 | 18 | mTargetButton = findViewById(R.id.button_target); 19 | 20 | findViewById(R.id.button_move_code).setOnClickListener(this); 21 | findViewById(R.id.button_rotate_code).setOnClickListener(this); 22 | findViewById(R.id.button_scale_code).setOnClickListener(this); 23 | findViewById(R.id.button_alpha_code).setOnClickListener(this); 24 | findViewById(R.id.button_move_back).setOnClickListener(this); 25 | findViewById(R.id.button_rotate_back).setOnClickListener(this); 26 | findViewById(R.id.button_scale_back).setOnClickListener(this); 27 | findViewById(R.id.button_alpha_back).setOnClickListener(this); 28 | } 29 | 30 | @Override 31 | public void onClick(View view) { 32 | if (view.getId() == R.id.button_move_code) { 33 | mTargetButton.animate() 34 | .translationX(mTargetButton.getWidth()) 35 | .setDuration(3000) 36 | .start(); 37 | } else if (view.getId() == R.id.button_rotate_code) { 38 | mTargetButton.animate() 39 | .rotation(360f) 40 | .setDuration(3000) 41 | .start(); 42 | } else if (view.getId() == R.id.button_scale_code) { 43 | mTargetButton.animate() 44 | .scaleX(0.5f) 45 | .scaleY(0.5f) 46 | .setDuration(3000) 47 | .start(); 48 | } else if (view.getId() == R.id.button_alpha_code) { 49 | mTargetButton.animate() 50 | .alpha(0f) 51 | .setDuration(3000) 52 | .start(); 53 | } else if (view.getId() == R.id.button_move_back) { 54 | mTargetButton.animate() 55 | .translationX(0) 56 | .setDuration(3000) 57 | .start(); 58 | } else if (view.getId() == R.id.button_rotate_back) { 59 | mTargetButton.animate() 60 | .rotation(0f) 61 | .setDuration(3000) 62 | .start(); 63 | } else if (view.getId() == R.id.button_scale_back) { 64 | mTargetButton.animate() 65 | .scaleX(1f) 66 | .scaleY(1f) 67 | .setDuration(3000) 68 | .start(); 69 | } else if (view.getId() == R.id.button_alpha_back) { 70 | mTargetButton.animate() 71 | .alpha(1f) 72 | .setDuration(3000) 73 | .start(); 74 | 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/fragment/Fa1Fragment.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import net.cattaka.learnanimation.R; 10 | 11 | /** 12 | * Created by takao on 2015/11/18. 13 | */ 14 | public class Fa1Fragment extends Fragment { 15 | public static Fa1Fragment newInstance() { 16 | Bundle args = new Bundle(); 17 | 18 | Fa1Fragment fragment = new Fa1Fragment(); 19 | fragment.setArguments(args); 20 | return fragment; 21 | } 22 | 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 25 | return inflater.inflate(R.layout.fragment_fa_1, container, false); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/fragment/Fa2Fragment.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import net.cattaka.learnanimation.R; 10 | 11 | /** 12 | * Created by takao on 2015/11/18. 13 | */ 14 | public class Fa2Fragment extends Fragment { 15 | public static Fa2Fragment newInstance() { 16 | Bundle args = new Bundle(); 17 | 18 | Fa2Fragment fragment = new Fa2Fragment(); 19 | fragment.setArguments(args); 20 | return fragment; 21 | } 22 | 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 25 | return inflater.inflate(R.layout.fragment_fa_2, container, false); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/fragment/Ft1Fragment.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import net.cattaka.learnanimation.R; 10 | 11 | /** 12 | * Created by takao on 2015/11/18. 13 | */ 14 | public class Ft1Fragment extends Fragment { 15 | public static Ft1Fragment newInstance() { 16 | Bundle args = new Bundle(); 17 | 18 | Ft1Fragment fragment = new Ft1Fragment(); 19 | fragment.setArguments(args); 20 | return fragment; 21 | } 22 | 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 25 | return inflater.inflate(R.layout.fragment_ft_1, container, false); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/fragment/Ft2Fragment.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.fragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import net.cattaka.learnanimation.R; 10 | 11 | /** 12 | * Created by takao on 2015/11/18. 13 | */ 14 | public class Ft2Fragment extends Fragment { 15 | public static Ft2Fragment newInstance() { 16 | Bundle args = new Bundle(); 17 | 18 | Ft2Fragment fragment = new Ft2Fragment(); 19 | fragment.setArguments(args); 20 | return fragment; 21 | } 22 | 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 25 | return inflater.inflate(R.layout.fragment_ft_2, container, false); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/transition/PathProperty.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.transition; 2 | 3 | 4 | import android.graphics.Path; 5 | import android.graphics.PathMeasure; 6 | import android.graphics.PointF; 7 | import android.util.Property; 8 | 9 | class PathProperty extends Property { 10 | private final Property mProperty; 11 | private final PathMeasure mPathMeasure; 12 | private final float mPathLength; 13 | private final float[] mPosition = new float[2]; 14 | private final PointF mPointF = new PointF(); 15 | private float mCurrentFraction; 16 | 17 | PathProperty(Property property, Path path) { 18 | super(Float.class, property.getName()); 19 | this.mProperty = property; 20 | this.mPathMeasure = new PathMeasure(path, false); 21 | this.mPathLength = this.mPathMeasure.getLength(); 22 | } 23 | 24 | public Float get(T object) { 25 | return this.mCurrentFraction; 26 | } 27 | 28 | public void set(T target, Float fraction) { 29 | this.mCurrentFraction = fraction; 30 | this.mPathMeasure.getPosTan(this.mPathLength * fraction, this.mPosition, (float[]) null); 31 | this.mPointF.x = this.mPosition[0]; 32 | this.mPointF.y = this.mPosition[1]; 33 | this.mProperty.set(target, this.mPointF); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/transition/RectEvaluator.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.transition; 2 | 3 | import android.animation.TypeEvaluator; 4 | import android.graphics.Rect; 5 | 6 | class RectEvaluator implements TypeEvaluator { 7 | private Rect mRect; 8 | 9 | RectEvaluator() { 10 | } 11 | 12 | RectEvaluator(Rect reuseRect) { 13 | this.mRect = reuseRect; 14 | } 15 | 16 | public Rect evaluate(float fraction, Rect startValue, Rect endValue) { 17 | int left = startValue.left + (int) ((float) (endValue.left - startValue.left) * fraction); 18 | int top = startValue.top + (int) ((float) (endValue.top - startValue.top) * fraction); 19 | int right = startValue.right + (int) ((float) (endValue.right - startValue.right) * fraction); 20 | int bottom = startValue.bottom + (int) ((float) (endValue.bottom - startValue.bottom) * fraction); 21 | if (this.mRect == null) { 22 | return new Rect(left, top, right, bottom); 23 | } else { 24 | this.mRect.set(left, top, right, bottom); 25 | return this.mRect; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/transition/SourceChangeBounds.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.transition; 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.TypeConverter; 9 | import android.content.Context; 10 | import android.graphics.Path; 11 | import android.graphics.PointF; 12 | import android.graphics.Rect; 13 | import android.graphics.drawable.Drawable; 14 | import android.support.annotation.NonNull; 15 | import android.support.annotation.Nullable; 16 | import android.support.transition.ChangeBounds; 17 | import android.support.transition.Transition; 18 | import android.support.transition.TransitionListenerAdapter; 19 | import android.support.transition.TransitionValues; 20 | import android.support.v4.view.ViewCompat; 21 | import android.util.AttributeSet; 22 | import android.util.Log; 23 | import android.util.Property; 24 | import android.view.View; 25 | import android.view.ViewGroup; 26 | 27 | import net.cattaka.learnanimation.R; 28 | 29 | import java.lang.reflect.InvocationTargetException; 30 | import java.lang.reflect.Method; 31 | 32 | public class SourceChangeBounds extends ChangeBounds { 33 | 34 | private static final Property DRAWABLE_ORIGIN_PROPERTY = new Property(PointF.class, "boundsOrigin") { 35 | private Rect mBounds = new Rect(); 36 | 37 | public void set(Drawable object, PointF value) { 38 | object.copyBounds(this.mBounds); 39 | this.mBounds.offsetTo(Math.round(value.x), Math.round(value.y)); 40 | object.setBounds(this.mBounds); 41 | } 42 | 43 | public PointF get(Drawable object) { 44 | object.copyBounds(this.mBounds); 45 | return new PointF((float) this.mBounds.left, (float) this.mBounds.top); 46 | } 47 | }; 48 | private static final Property TOP_LEFT_PROPERTY = new Property(PointF.class, "topLeft") { 49 | public void set(ViewBounds viewBounds, PointF topLeft) { 50 | viewBounds.setTopLeft(topLeft); 51 | } 52 | 53 | public PointF get(ViewBounds viewBounds) { 54 | return null; 55 | } 56 | }; 57 | private static final Property BOTTOM_RIGHT_PROPERTY = new Property(PointF.class, "bottomRight") { 58 | public void set(ViewBounds viewBounds, PointF bottomRight) { 59 | viewBounds.setBottomRight(bottomRight); 60 | } 61 | 62 | public PointF get(ViewBounds viewBounds) { 63 | return null; 64 | } 65 | }; 66 | private static final Property BOTTOM_RIGHT_ONLY_PROPERTY = new Property(PointF.class, "bottomRight") { 67 | public void set(View view, PointF bottomRight) { 68 | int left = view.getLeft(); 69 | int top = view.getTop(); 70 | int right = Math.round(bottomRight.x); 71 | int bottom = Math.round(bottomRight.y); 72 | setLeftTopRightBottom(view, left, top, right, bottom); 73 | } 74 | 75 | public PointF get(View view) { 76 | return null; 77 | } 78 | }; 79 | private static final Property TOP_LEFT_ONLY_PROPERTY = new Property(PointF.class, "topLeft") { 80 | public void set(View view, PointF topLeft) { 81 | int left = Math.round(topLeft.x); 82 | int top = Math.round(topLeft.y); 83 | int right = view.getRight(); 84 | int bottom = view.getBottom(); 85 | setLeftTopRightBottom(view, left, top, right, bottom); 86 | } 87 | 88 | public PointF get(View view) { 89 | return null; 90 | } 91 | }; 92 | private static final Property POSITION_PROPERTY = new Property(PointF.class, "position") { 93 | public void set(View view, PointF topLeft) { 94 | int left = Math.round(topLeft.x); 95 | int top = Math.round(topLeft.y); 96 | int right = left + view.getWidth(); 97 | int bottom = top + view.getHeight(); 98 | setLeftTopRightBottom(view, left, top, right, bottom); 99 | } 100 | 101 | public PointF get(View view) { 102 | return null; 103 | } 104 | }; 105 | 106 | private int[] mTempLocation = new int[2]; 107 | private boolean mResizeClip = false; 108 | private boolean mReparent = false; 109 | private static RectEvaluator sRectEvaluator = new RectEvaluator(); 110 | 111 | public SourceChangeBounds() { 112 | } 113 | 114 | public SourceChangeBounds(Context context, AttributeSet attrs) { 115 | super(context, attrs); 116 | } 117 | 118 | public void captureStartValues(@NonNull TransitionValues transitionValues) { 119 | this.captureValues(transitionValues); 120 | } 121 | 122 | public void captureEndValues(@NonNull TransitionValues transitionValues) { 123 | this.captureValues(transitionValues); 124 | } 125 | 126 | private void captureValues(TransitionValues values) { 127 | View view = values.view; 128 | if (ViewCompat.isLaidOut(view) || view.getWidth() != 0 || view.getHeight() != 0) { 129 | values.values.put("android:changeBounds:bounds", new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); 130 | values.values.put("android:changeBounds:parent", values.view.getParent()); 131 | if (this.mReparent) { 132 | values.view.getLocationInWindow(this.mTempLocation); 133 | values.values.put("android:changeBounds:windowX", this.mTempLocation[0]); 134 | values.values.put("android:changeBounds:windowY", this.mTempLocation[1]); 135 | } 136 | 137 | if (this.mResizeClip) { 138 | values.values.put("android:changeBounds:clip", ViewCompat.getClipBounds(view)); 139 | } 140 | } 141 | 142 | } 143 | 144 | @Nullable 145 | @Override 146 | public Animator createAnimator(@NonNull final ViewGroup sceneRoot, @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) { 147 | if (startValues != null && endValues != null) { 148 | final View view = endValues.view; 149 | Rect startBounds = (Rect) startValues.values.get("android:changeBounds:bounds"); 150 | Rect endBounds = (Rect) endValues.values.get("android:changeBounds:bounds"); 151 | int startLeft = startBounds.left; 152 | final int endLeft = endBounds.left; 153 | int startTop = startBounds.top; 154 | final int endTop = endBounds.top; 155 | int startRight = startBounds.right; 156 | final int endRight = endBounds.right; 157 | int startBottom = startBounds.bottom; 158 | final int endBottom = endBounds.bottom; 159 | int startWidth = startRight - startLeft; 160 | int startHeight = startBottom - startTop; 161 | int endWidth = endRight - endLeft; 162 | int endHeight = endBottom - endTop; 163 | Rect startClip = (Rect) startValues.values.get("android:changeBounds:clip"); 164 | Rect endClip = (Rect) endValues.values.get("android:changeBounds:clip"); 165 | int numChanges = 0; 166 | if (startWidth != 0 && startHeight != 0 || endWidth != 0 && endHeight != 0) { 167 | if (startLeft != endLeft || startTop != endTop) { 168 | ++numChanges; 169 | } 170 | 171 | if (startRight != endRight || startBottom != endBottom) { 172 | ++numChanges; 173 | } 174 | } 175 | 176 | if (startClip != null && !startClip.equals(endClip) || startClip == null && endClip != null) { 177 | ++numChanges; 178 | } 179 | 180 | if (numChanges > 0) { 181 | Object anim; 182 | ObjectAnimator positionAnimator; 183 | Path bottomRightPath; 184 | ObjectAnimator clipAnimator; 185 | if (!this.mResizeClip) { 186 | setLeftTopRightBottom(view, startLeft, startTop, startRight, startBottom); 187 | Path topLeftPath; 188 | if (numChanges == 2) { 189 | if (startWidth == endWidth && startHeight == endHeight) { 190 | topLeftPath = this.getPathMotion().getPath((float) startLeft, (float) startTop, (float) endLeft, (float) endTop); 191 | anim = ofPointF(view, POSITION_PROPERTY, topLeftPath); 192 | } else { 193 | final ViewBounds viewBounds = new ViewBounds(view); 194 | topLeftPath = this.getPathMotion().getPath((float) startLeft, (float) startTop, (float) endLeft, (float) endTop); 195 | positionAnimator = ofPointF(viewBounds, TOP_LEFT_PROPERTY, topLeftPath); 196 | bottomRightPath = this.getPathMotion().getPath((float) startRight, (float) startBottom, (float) endRight, (float) endBottom); 197 | clipAnimator = ofPointF(viewBounds, BOTTOM_RIGHT_PROPERTY, bottomRightPath); 198 | AnimatorSet set = new AnimatorSet(); 199 | set.playTogether(new Animator[]{positionAnimator, clipAnimator}); 200 | anim = set; 201 | set.addListener(new AnimatorListenerAdapter() { 202 | private ViewBounds mViewBounds = viewBounds; 203 | }); 204 | } 205 | } else if (startLeft == endLeft && startTop == endTop) { 206 | topLeftPath = this.getPathMotion().getPath((float) startRight, (float) startBottom, (float) endRight, (float) endBottom); 207 | anim = ofPointF(view, BOTTOM_RIGHT_ONLY_PROPERTY, topLeftPath); 208 | } else { 209 | topLeftPath = this.getPathMotion().getPath((float) startLeft, (float) startTop, (float) endLeft, (float) endTop); 210 | anim = ofPointF(view, TOP_LEFT_ONLY_PROPERTY, topLeftPath); 211 | } 212 | } else { 213 | int maxWidth = Math.max(startWidth, endWidth); 214 | int maxHeight = Math.max(startHeight, endHeight); 215 | setLeftTopRightBottom(view, startLeft, startTop, startLeft + maxWidth, startTop + maxHeight); 216 | positionAnimator = null; 217 | if (startLeft != endLeft || startTop != endTop) { 218 | bottomRightPath = this.getPathMotion().getPath((float) startLeft, (float) startTop, (float) endLeft, (float) endTop); 219 | positionAnimator = ofPointF(view, POSITION_PROPERTY, bottomRightPath); 220 | } 221 | 222 | final Rect finalClip = endClip; 223 | if (startClip == null) { 224 | startClip = new Rect(0, 0, startWidth, startHeight); 225 | } 226 | 227 | if (endClip == null) { 228 | endClip = new Rect(0, 0, endWidth, endHeight); 229 | } 230 | 231 | clipAnimator = null; 232 | if (!startClip.equals(endClip)) { 233 | ViewCompat.setClipBounds(view, startClip); 234 | clipAnimator = ObjectAnimator.ofObject(view, "clipBounds", sRectEvaluator, new Object[]{startClip, endClip}); 235 | clipAnimator.addListener(new AnimatorListenerAdapter() { 236 | private boolean mIsCanceled; 237 | 238 | public void onAnimationCancel(Animator animation) { 239 | this.mIsCanceled = true; 240 | } 241 | 242 | public void onAnimationEnd(Animator animation) { 243 | if (!this.mIsCanceled) { 244 | ViewCompat.setClipBounds(view, finalClip); 245 | setLeftTopRightBottom(view, endLeft, endTop, endRight, endBottom); 246 | } 247 | 248 | } 249 | }); 250 | } 251 | 252 | anim = mergeAnimators(positionAnimator, clipAnimator); 253 | } 254 | 255 | if (view.getParent() instanceof ViewGroup) { 256 | final ViewGroup parent = (ViewGroup) view.getParent(); 257 | suppressLayout(parent, true); 258 | TransitionListener transitionListener = new TransitionListenerAdapter() { 259 | boolean mCanceled = false; 260 | 261 | public void onTransitionCancel(@NonNull Transition transition) { 262 | suppressLayout(parent, false); 263 | this.mCanceled = true; 264 | } 265 | 266 | public void onTransitionEnd(@NonNull Transition transition) { 267 | if (!this.mCanceled) { 268 | suppressLayout(parent, false); 269 | } 270 | 271 | transition.removeListener(this); 272 | } 273 | 274 | public void onTransitionPause(@NonNull Transition transition) { 275 | suppressLayout(parent, false); 276 | } 277 | 278 | public void onTransitionResume(@NonNull Transition transition) { 279 | suppressLayout(parent, true); 280 | } 281 | }; 282 | this.addListener(transitionListener); 283 | } 284 | 285 | return (Animator) anim; 286 | } 287 | } 288 | return super.createAnimator(sceneRoot, startValues, endValues); 289 | } 290 | 291 | public float getTransitionAlpha(@NonNull View view) { 292 | Float savedAlpha = (Float) view.getTag(R.id.save_non_transition_alpha); 293 | return savedAlpha != null ? view.getAlpha() / savedAlpha : view.getAlpha(); 294 | } 295 | 296 | public void setTransitionAlpha(@NonNull View view, float alpha) { 297 | Float savedAlpha = (Float) view.getTag(R.id.save_non_transition_alpha); 298 | if (savedAlpha != null) { 299 | view.setAlpha(savedAlpha * alpha); 300 | } else { 301 | view.setAlpha(alpha); 302 | } 303 | } 304 | 305 | public static void setLeftTopRightBottom(View v, int left, int top, int right, int bottom) { 306 | v.setLeft(left); 307 | v.setTop(top); 308 | v.setRight(right); 309 | v.setBottom(bottom); 310 | } 311 | 312 | static PropertyValuesHolder ofPointF(Property property, Path path) { 313 | return PropertyValuesHolder.ofObject(property, (TypeConverter) null, path); 314 | } 315 | 316 | static ObjectAnimator ofPointF(T target, Property property, Path path) { 317 | return ObjectAnimator.ofObject(target, property, (TypeConverter) null, path); 318 | } 319 | 320 | static Animator mergeAnimators(Animator animator1, Animator animator2) { 321 | if (animator1 == null) { 322 | return animator2; 323 | } else if (animator2 == null) { 324 | return animator1; 325 | } else { 326 | AnimatorSet animatorSet = new AnimatorSet(); 327 | animatorSet.playTogether(new Animator[]{animator1, animator2}); 328 | return animatorSet; 329 | } 330 | } 331 | 332 | 333 | private static Method sSuppressLayoutMethod; 334 | private static boolean sSuppressLayoutMethodFetched; 335 | 336 | static void suppressLayout(@NonNull ViewGroup group, boolean suppress) { 337 | fetchSuppressLayoutMethod(); 338 | if (sSuppressLayoutMethod != null) { 339 | try { 340 | sSuppressLayoutMethod.invoke(group, suppress); 341 | } catch (IllegalAccessException var3) { 342 | Log.i("ViewUtilsApi18", "Failed to invoke suppressLayout method", var3); 343 | } catch (InvocationTargetException var4) { 344 | Log.i("ViewUtilsApi18", "Error invoking suppressLayout method", var4); 345 | } 346 | } 347 | 348 | } 349 | 350 | private static void fetchSuppressLayoutMethod() { 351 | if (!sSuppressLayoutMethodFetched) { 352 | try { 353 | sSuppressLayoutMethod = ViewGroup.class.getDeclaredMethod("suppressLayout", Boolean.TYPE); 354 | sSuppressLayoutMethod.setAccessible(true); 355 | } catch (NoSuchMethodException var1) { 356 | Log.i("ViewUtilsApi18", "Failed to retrieve suppressLayout method", var1); 357 | } 358 | 359 | sSuppressLayoutMethodFetched = true; 360 | } 361 | 362 | } 363 | 364 | private static class ViewBounds { 365 | private int mLeft; 366 | private int mTop; 367 | private int mRight; 368 | private int mBottom; 369 | private View mView; 370 | private int mTopLeftCalls; 371 | private int mBottomRightCalls; 372 | 373 | ViewBounds(View view) { 374 | this.mView = view; 375 | } 376 | 377 | void setTopLeft(PointF topLeft) { 378 | this.mLeft = Math.round(topLeft.x); 379 | this.mTop = Math.round(topLeft.y); 380 | ++this.mTopLeftCalls; 381 | if (this.mTopLeftCalls == this.mBottomRightCalls) { 382 | this.setLeftTopRightBottom(); 383 | } 384 | 385 | } 386 | 387 | void setBottomRight(PointF bottomRight) { 388 | this.mRight = Math.round(bottomRight.x); 389 | this.mBottom = Math.round(bottomRight.y); 390 | ++this.mBottomRightCalls; 391 | if (this.mTopLeftCalls == this.mBottomRightCalls) { 392 | this.setLeftTopRightBottom(); 393 | } 394 | 395 | } 396 | 397 | private void setLeftTopRightBottom() { 398 | SourceChangeBounds.setLeftTopRightBottom(this.mView, this.mLeft, this.mTop, this.mRight, this.mBottom); 399 | this.mTopLeftCalls = 0; 400 | this.mBottomRightCalls = 0; 401 | } 402 | } 403 | } 404 | 405 | -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/utils/RelativeLayoutAnimatorHelper.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.utils; 2 | 3 | import android.view.View; 4 | import android.widget.RelativeLayout; 5 | 6 | /** 7 | * Save all methods from proguard!! 8 | *

9 | * Created by cattaka on 2015/11/10. 10 | */ 11 | public class RelativeLayoutAnimatorHelper { 12 | View mView; 13 | 14 | public RelativeLayoutAnimatorHelper(View view) { 15 | mView = view; 16 | } 17 | 18 | public int getTopMargin() { 19 | return ((RelativeLayout.LayoutParams) mView.getLayoutParams()).topMargin; 20 | } 21 | 22 | public void setTopMargin(int v) { 23 | RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mView.getLayoutParams(); 24 | params.topMargin = v; 25 | mView.setLayoutParams(params); 26 | } 27 | 28 | public int getLeftMargin() { 29 | return ((RelativeLayout.LayoutParams) mView.getLayoutParams()).leftMargin; 30 | } 31 | 32 | public void setLeftMargin(int v) { 33 | RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mView.getLayoutParams(); 34 | params.leftMargin = v; 35 | mView.setLayoutParams(params); 36 | } 37 | 38 | public int getRightMargin() { 39 | return ((RelativeLayout.LayoutParams) mView.getLayoutParams()).rightMargin; 40 | } 41 | 42 | public void setRightMargin(int v) { 43 | RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mView.getLayoutParams(); 44 | params.rightMargin = v; 45 | mView.setLayoutParams(params); 46 | } 47 | 48 | public int getBottomMargin() { 49 | return ((RelativeLayout.LayoutParams) mView.getLayoutParams()).bottomMargin; 50 | } 51 | 52 | public void setBottomMargin(int v) { 53 | RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mView.getLayoutParams(); 54 | params.bottomMargin = v; 55 | mView.setLayoutParams(params); 56 | } 57 | } -------------------------------------------------------------------------------- /app/src/main/java/net/cattaka/learnanimation/view/CustomPropertyView.java: -------------------------------------------------------------------------------- 1 | package net.cattaka.learnanimation.view; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.TextView; 6 | 7 | /** 8 | * Created by cattaka on 15/11/07. 9 | */ 10 | public class CustomPropertyView extends TextView { 11 | public CustomPropertyView(Context context) { 12 | super(context); 13 | } 14 | 15 | public CustomPropertyView(Context context, AttributeSet attrs) { 16 | super(context, attrs); 17 | } 18 | 19 | public CustomPropertyView(Context context, AttributeSet attrs, int defStyleAttr) { 20 | super(context, attrs, defStyleAttr); 21 | } 22 | 23 | public CustomPropertyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 24 | super(context, attrs, defStyleAttr, defStyleRes); 25 | } 26 | 27 | public void setCustomProperty(int number) { 28 | setText(String.valueOf(number)); 29 | } 30 | 31 | public int getCustomProperty() { 32 | try { 33 | return Integer.valueOf(String.valueOf(getText())); 34 | } catch (NumberFormatException e) { 35 | return 0; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/res/anim/aa_slide_in.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/aa_slide_out.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/av_path_morph.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/anim/av_translation.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/va_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 11 | 19 | 27 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/anim/va_all_share_interpolator.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 17 | 23 | 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/anim/va_alpha.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/va_move.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/va_rotate.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/anim/va_scale.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pa_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | 20 | 27 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pa_all_share_interpolator.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 16 | 21 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pa_alpha.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pa_custom_property.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pa_move.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pa_rotate.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/animator/pa_scale.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ctklabo_logo256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cattaka/LearnAnimation/3cbc32ca316ce762c30848d93c1676ec0daf1196/app/src/main/res/drawable-hdpi/ctklabo_logo256.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ctklabo_rb256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cattaka/LearnAnimation/3cbc32ca316ce762c30848d93c1676ec0daf1196/app/src/main/res/drawable-hdpi/ctklabo_rb256.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/roll_cat_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cattaka/LearnAnimation/3cbc32ca316ce762c30848d93c1676ec0daf1196/app/src/main/res/drawable-hdpi/roll_cat_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/roll_cat_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cattaka/LearnAnimation/3cbc32ca316ce762c30848d93c1676ec0daf1196/app/src/main/res/drawable-hdpi/roll_cat_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/roll_cat_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cattaka/LearnAnimation/3cbc32ca316ce762c30848d93c1676ec0daf1196/app/src/main/res/drawable-hdpi/roll_cat_3.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cattaka/LearnAnimation/3cbc32ca316ce762c30848d93c1676ec0daf1196/app/src/main/res/drawable-xhdpi/logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/avd.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/roll_cat.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 10 | 13 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/vector_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 13 | 14 | 16 | 19 | /> 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_aa_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 |