├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── malmstein │ │ └── materialanimations │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── malmstein │ │ └── materialanimations │ │ ├── MainActivity.java │ │ ├── activityscenetransitionbasic │ │ ├── DetailActivity.java │ │ ├── Item.java │ │ ├── SquareFrameLayout.java │ │ └── TransitionActivity.java │ │ ├── elevation │ │ ├── DragFrameLayout.java │ │ ├── ElevationActivity.java │ │ ├── ElevationBasicFragment.java │ │ └── ElevationDragFragment.java │ │ └── interpolator │ │ ├── InterpolatorActivity.java │ │ └── InterpolatorFragment.java │ └── res │ ├── drawable-hdpi │ ├── ic_launcher.png │ └── tile.9.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── drawable │ ├── btn_fab_default.xml │ ├── shape.xml │ └── shape2.xml │ ├── layout │ ├── activity_elevation.xml │ ├── activity_interpolator.xml │ ├── activity_transition.xml │ ├── activity_transition_details.xml │ ├── elevation_basic.xml │ ├── fragment_ztranslation.xml │ ├── grid_item.xml │ └── interpolator_fragment.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── transition │ └── grid_detail_transition.xml │ ├── values-v21 │ └── theme.xml │ └── values │ ├── base-strings.xml │ ├── color.xml │ ├── dimens.xml │ ├── fragmentview_strings.xml │ ├── interpolator_strings.xml │ ├── template-dimens.xml │ ├── theme.xml │ └── transition_strings.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── 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 | out/ 15 | build.log 16 | build-log.xml 17 | 18 | # Local configuration file (sdk path, etc) 19 | local.properties 20 | 21 | .project 22 | .classpath 23 | .settings 24 | target/ 25 | build/ 26 | classes/ 27 | gen-external-apklibs/ 28 | tmp/ 29 | 30 | # IDEA Ignores 31 | *.iml 32 | *.ipr 33 | *.iws 34 | .idea/ 35 | .gradle/ 36 | 37 | # Android 38 | local.properties 39 | 40 | # MAC 41 | *.DS_Store 42 | 43 | # Linux 44 | *~ 45 | 46 | # api scripts 47 | session.key 48 | access.token 49 | response.txt 50 | feed.cookie 51 | login.properties 52 | .pt 53 | *.orig 54 | terminator/ 55 | feed.cookie 56 | login.properties 57 | 58 | ======= 59 | # generated every build 60 | crashlytics.properties 61 | com_crashlytics_export_strings.xml 62 | 63 | app/build 64 | app-test/build 65 | lint-results.xml 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MaterialAnimations 2 | Material Animations examples 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 21 5 | buildToolsVersion "21.1.2" 6 | 7 | defaultConfig { 8 | applicationId "com.malmstein.materialanimations" 9 | minSdkVersion 21 10 | targetSdkVersion 21 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 "com.android.support:support-v4:21.0.3" 24 | compile "com.android.support:support-v13:21.0.3" 25 | compile 'com.android.support:appcompat-v7:21.0.3' 26 | compile 'com.novoda:notils:2.2.8' 27 | compile "com.squareup.picasso:picasso:2.4.0" 28 | } 29 | -------------------------------------------------------------------------------- /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 /Users/malmstein/_dev/android/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 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/malmstein/materialanimations/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.malmstein.materialanimations; 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 | 4 | 5 | 6 | 7 | 12 | 15 | 16 | 17 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.malmstein.materialanimations; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.ActionBarActivity; 5 | 6 | public class MainActivity extends ActionBarActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | setContentView(R.layout.activity_elevation); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/activityscenetransitionbasic/DetailActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.activityscenetransitionbasic; 18 | 19 | import android.app.Activity; 20 | import android.os.Build; 21 | import android.os.Bundle; 22 | import android.support.v4.view.ViewCompat; 23 | import android.transition.Transition; 24 | import android.view.animation.OvershootInterpolator; 25 | import android.widget.ImageButton; 26 | import android.widget.ImageView; 27 | import android.widget.TextView; 28 | 29 | import com.malmstein.materialanimations.R; 30 | import com.squareup.picasso.Picasso; 31 | 32 | /** 33 | * Our secondary Activity which is launched from {@link TransitionActivity}. Has a simple detail UI 34 | * which has a large banner image, title and body text. 35 | */ 36 | public class DetailActivity extends Activity { 37 | 38 | // Extra name for the ID parameter 39 | public static final String EXTRA_PARAM_ID = "detail:_id"; 40 | 41 | // View name of the header image. Used for activity scene transitions 42 | public static final String VIEW_NAME_HEADER_IMAGE = "detail:header:image"; 43 | 44 | // View name of the header title. Used for activity scene transitions 45 | public static final String VIEW_NAME_HEADER_TITLE = "detail:header:title"; 46 | 47 | private ImageView mHeaderImageView; 48 | private TextView mHeaderTitle; 49 | private ImageButton mFab; 50 | 51 | private Item mItem; 52 | 53 | @Override 54 | protected void onCreate(Bundle savedInstanceState) { 55 | super.onCreate(savedInstanceState); 56 | setContentView(R.layout.activity_transition_details); 57 | 58 | // Retrieve the correct Item instance, using the ID provided in the Intent 59 | mItem = Item.getItem(getIntent().getIntExtra(EXTRA_PARAM_ID, 0)); 60 | 61 | mHeaderImageView = (ImageView) findViewById(R.id.imageview_header); 62 | mHeaderTitle = (TextView) findViewById(R.id.textview_title); 63 | mFab = (ImageButton) findViewById(R.id.button_fab); 64 | 65 | // BEGIN_INCLUDE(detail_set_view_name) 66 | /** 67 | * Set the name of the view's which will be transition to, using the static values above. 68 | * This could be done in the layout XML, but exposing it via static variables allows easy 69 | * querying from other Activities 70 | */ 71 | ViewCompat.setTransitionName(mHeaderImageView, VIEW_NAME_HEADER_IMAGE); 72 | ViewCompat.setTransitionName(mHeaderTitle, VIEW_NAME_HEADER_TITLE); 73 | // END_INCLUDE(detail_set_view_name) 74 | 75 | mFab.setTranslationY(2 * getResources().getDimensionPixelOffset(R.dimen.btn_fab_size)); 76 | getWindow().getEnterTransition().addListener(new Transition.TransitionListener() { 77 | @Override 78 | public void onTransitionStart(Transition transition) { 79 | } 80 | 81 | @Override 82 | public void onTransitionEnd(Transition transition) { 83 | mFab.animate() 84 | .translationY(0) 85 | .setInterpolator(new OvershootInterpolator(1.f)) 86 | .setStartDelay(300) 87 | .setDuration(400) 88 | .start(); 89 | } 90 | 91 | @Override 92 | public void onTransitionCancel(Transition transition) { 93 | } 94 | 95 | @Override 96 | public void onTransitionPause(Transition transition) { 97 | } 98 | 99 | @Override 100 | public void onTransitionResume(Transition transition) { 101 | } 102 | }); 103 | 104 | loadItem(); 105 | } 106 | 107 | @Override 108 | public void onBackPressed() { 109 | mFab.animate() 110 | .translationYBy(2 * getResources().getDimensionPixelOffset(R.dimen.btn_fab_size)) 111 | .setInterpolator(new OvershootInterpolator(1.f)) 112 | .setDuration(400) 113 | .withEndAction(new Runnable() { 114 | @Override 115 | public void run() { 116 | finishAfterTransition(); 117 | } 118 | }); 119 | } 120 | 121 | private void loadItem() { 122 | // Set the title TextView to the item's name and author 123 | mHeaderTitle.setText(getString(R.string.image_header, mItem.getName(), mItem.getAuthor())); 124 | 125 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && addTransitionListener()) { 126 | // If we're running on Lollipop and we have added a listener to the shared element 127 | // transition, load the thumbnail. The listener will load the full-size image when 128 | // the transition is complete. 129 | loadThumbnail(); 130 | } else { 131 | // If all other cases we should just load the full-size image now 132 | loadFullSizeImage(); 133 | } 134 | } 135 | 136 | /** 137 | * Load the item's thumbnail image into our {@link android.widget.ImageView}. 138 | */ 139 | private void loadThumbnail() { 140 | Picasso.with(mHeaderImageView.getContext()) 141 | .load(mItem.getThumbnailUrl()) 142 | .noFade() 143 | .into(mHeaderImageView); 144 | } 145 | 146 | /** 147 | * Load the item's full-size image into our {@link android.widget.ImageView}. 148 | */ 149 | private void loadFullSizeImage() { 150 | Picasso.with(mHeaderImageView.getContext()) 151 | .load(mItem.getPhotoUrl()) 152 | .noFade() 153 | .noPlaceholder() 154 | .into(mHeaderImageView); 155 | } 156 | 157 | /** 158 | * Try and add a {@link android.transition.Transition.TransitionListener} to the entering shared element 159 | * {@link android.transition.Transition}. We do this so that we can load the full-size image after the transition 160 | * has completed. 161 | * 162 | * @return true if we were successful in adding a listener to the enter transition 163 | */ 164 | private boolean addTransitionListener() { 165 | final Transition transition = getWindow().getSharedElementEnterTransition(); 166 | 167 | if (transition != null) { 168 | // There is an entering shared element transition so add a listener to it 169 | transition.addListener(new Transition.TransitionListener() { 170 | @Override 171 | public void onTransitionEnd(Transition transition) { 172 | // As the transition has ended, we can now load the full-size image 173 | loadFullSizeImage(); 174 | 175 | // Make sure we remove ourselves as a listener 176 | transition.removeListener(this); 177 | } 178 | 179 | @Override 180 | public void onTransitionStart(Transition transition) { 181 | // No-op 182 | } 183 | 184 | @Override 185 | public void onTransitionCancel(Transition transition) { 186 | // Make sure we remove ourselves as a listener 187 | transition.removeListener(this); 188 | } 189 | 190 | @Override 191 | public void onTransitionPause(Transition transition) { 192 | // No-op 193 | } 194 | 195 | @Override 196 | public void onTransitionResume(Transition transition) { 197 | // No-op 198 | } 199 | }); 200 | return true; 201 | } 202 | 203 | // If we reach here then we have not added a listener 204 | return false; 205 | } 206 | 207 | } 208 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/activityscenetransitionbasic/Item.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.activityscenetransitionbasic; 18 | 19 | /** 20 | * Represents an Item in our application. Each item has a name, id, full size image url and 21 | * thumbnail url. 22 | */ 23 | public class Item { 24 | 25 | private static final String LARGE_BASE_URL = "http://storage.googleapis.com/androiddevelopers/sample_data/activity_transition/large/"; 26 | private static final String THUMB_BASE_URL = "http://storage.googleapis.com/androiddevelopers/sample_data/activity_transition/thumbs/"; 27 | 28 | public static Item[] ITEMS = new Item[] { 29 | new Item("Flying in the Light", "Romain Guy", "flying_in_the_light.jpg"), 30 | new Item("Caterpillar", "Romain Guy", "caterpillar.jpg"), 31 | new Item("Look Me in the Eye", "Romain Guy", "look_me_in_the_eye.jpg"), 32 | new Item("Flamingo", "Romain Guy", "flamingo.jpg"), 33 | new Item("Rainbow", "Romain Guy", "rainbow.jpg"), 34 | new Item("Over there", "Romain Guy", "over_there.jpg"), 35 | new Item("Jelly Fish 2", "Romain Guy", "jelly_fish_2.jpg"), 36 | new Item("Lone Pine Sunset", "Romain Guy", "lone_pine_sunset.jpg"), 37 | }; 38 | 39 | public static Item getItem(int id) { 40 | for (Item item : ITEMS) { 41 | if (item.getId() == id) { 42 | return item; 43 | } 44 | } 45 | return null; 46 | } 47 | 48 | private final String mName; 49 | private final String mAuthor; 50 | private final String mFileName; 51 | 52 | Item (String name, String author, String fileName) { 53 | mName = name; 54 | mAuthor = author; 55 | mFileName = fileName; 56 | } 57 | 58 | public int getId() { 59 | return mName.hashCode() + mFileName.hashCode(); 60 | } 61 | 62 | public String getAuthor() { 63 | return mAuthor; 64 | } 65 | 66 | public String getName() { 67 | return mName; 68 | } 69 | 70 | public String getPhotoUrl() { 71 | return LARGE_BASE_URL + mFileName; 72 | } 73 | 74 | public String getThumbnailUrl() { 75 | return THUMB_BASE_URL + mFileName; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/activityscenetransitionbasic/SquareFrameLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.activityscenetransitionbasic; 18 | 19 | import android.content.Context; 20 | import android.util.AttributeSet; 21 | import android.widget.FrameLayout; 22 | 23 | /** 24 | * {@link android.widget.FrameLayout} which forces itself to be laid out as square. 25 | */ 26 | public class SquareFrameLayout extends FrameLayout { 27 | 28 | public SquareFrameLayout(Context context) { 29 | super(context); 30 | } 31 | 32 | public SquareFrameLayout(Context context, AttributeSet attrs) { 33 | super(context, attrs); 34 | } 35 | 36 | public SquareFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { 37 | super(context, attrs, defStyleAttr); 38 | } 39 | 40 | public SquareFrameLayout(Context context, AttributeSet attrs, 41 | int defStyleAttr, int defStyleRes) { 42 | super(context, attrs, defStyleAttr, defStyleRes); 43 | } 44 | 45 | @Override 46 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 47 | final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 48 | final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 49 | 50 | if (widthSize == 0 && heightSize == 0) { 51 | // If there are no constraints on size, let FrameLayout measure 52 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 53 | 54 | // Now use the smallest of the measured dimensions for both dimensions 55 | final int minSize = Math.min(getMeasuredWidth(), getMeasuredHeight()); 56 | setMeasuredDimension(minSize, minSize); 57 | return; 58 | } 59 | 60 | final int size; 61 | if (widthSize == 0 || heightSize == 0) { 62 | // If one of the dimensions has no restriction on size, set both dimensions to be the 63 | // on that does 64 | size = Math.max(widthSize, heightSize); 65 | } else { 66 | // Both dimensions have restrictions on size, set both dimensions to be the 67 | // smallest of the two 68 | size = Math.min(widthSize, heightSize); 69 | } 70 | 71 | final int newMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 72 | super.onMeasure(newMeasureSpec, newMeasureSpec); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/activityscenetransitionbasic/TransitionActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.activityscenetransitionbasic; 18 | 19 | import android.app.Activity; 20 | import android.content.Intent; 21 | import android.os.Bundle; 22 | import android.support.v4.app.ActivityCompat; 23 | import android.support.v4.app.ActivityOptionsCompat; 24 | import android.support.v4.util.Pair; 25 | import android.view.View; 26 | import android.view.ViewGroup; 27 | import android.widget.AdapterView; 28 | import android.widget.BaseAdapter; 29 | import android.widget.GridView; 30 | import android.widget.ImageView; 31 | import android.widget.TextView; 32 | 33 | import com.malmstein.materialanimations.R; 34 | import com.squareup.picasso.Picasso; 35 | 36 | /** 37 | * Our main Activity in this sample. Displays a grid of items which an image and title. When the 38 | * user clicks on an item, {@link DetailActivity} is launched, using the Activity Scene Transitions 39 | * framework to animatedly do so. 40 | */ 41 | public class TransitionActivity extends Activity implements AdapterView.OnItemClickListener { 42 | 43 | private GridView mGridView; 44 | private GridAdapter mAdapter; 45 | 46 | @Override 47 | public void onCreate(Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | setContentView(R.layout.activity_transition); 50 | 51 | // Setup the GridView and set the adapter 52 | mGridView = (GridView) findViewById(R.id.grid); 53 | mGridView.setOnItemClickListener(this); 54 | mAdapter = new GridAdapter(); 55 | mGridView.setAdapter(mAdapter); 56 | } 57 | 58 | /** 59 | * Called when an item in the {@link android.widget.GridView} is clicked. Here will launch the 60 | * {@link DetailActivity}, using the Scene Transition animation functionality. 61 | */ 62 | @Override 63 | public void onItemClick(AdapterView adapterView, View view, int position, long id) { 64 | Item item = (Item) adapterView.getItemAtPosition(position); 65 | 66 | // Construct an Intent as normal 67 | Intent intent = new Intent(this, DetailActivity.class); 68 | intent.putExtra(DetailActivity.EXTRA_PARAM_ID, item.getId()); 69 | 70 | // BEGIN_INCLUDE(start_activity) 71 | /** 72 | * Now create an {@link android.app.ActivityOptions} instance using the 73 | * {@link android.support.v4.app.ActivityOptionsCompat#makeSceneTransitionAnimation(android.app.Activity, android.support.v4.util.Pair[])} factory 74 | * method. 75 | */ 76 | ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation( 77 | this, 78 | 79 | // Now we provide a list of Pair items which contain the view we can transitioning 80 | // from, and the name of the view it is transitioning to, in the launched activity 81 | new Pair(view.findViewById(R.id.imageview_item), 82 | DetailActivity.VIEW_NAME_HEADER_IMAGE), 83 | new Pair(view.findViewById(R.id.textview_name), 84 | DetailActivity.VIEW_NAME_HEADER_TITLE)); 85 | 86 | // Now we can start the Activity, providing the activity options as a bundle 87 | ActivityCompat.startActivity(this, intent, activityOptions.toBundle()); 88 | // END_INCLUDE(start_activity) 89 | } 90 | 91 | /** 92 | * {@link android.widget.BaseAdapter} which displays items. 93 | */ 94 | private class GridAdapter extends BaseAdapter { 95 | 96 | @Override 97 | public int getCount() { 98 | return Item.ITEMS.length; 99 | } 100 | 101 | @Override 102 | public Item getItem(int position) { 103 | return Item.ITEMS[position]; 104 | } 105 | 106 | @Override 107 | public long getItemId(int position) { 108 | return getItem(position).getId(); 109 | } 110 | 111 | @Override 112 | public View getView(int position, View view, ViewGroup viewGroup) { 113 | if (view == null) { 114 | view = getLayoutInflater().inflate(R.layout.grid_item, viewGroup, false); 115 | } 116 | 117 | final Item item = getItem(position); 118 | 119 | // Load the thumbnail image 120 | ImageView image = (ImageView) view.findViewById(R.id.imageview_item); 121 | Picasso.with(image.getContext()).load(item.getThumbnailUrl()).into(image); 122 | 123 | // Set the TextView's contents 124 | TextView name = (TextView) view.findViewById(R.id.textview_name); 125 | name.setText(item.getName()); 126 | 127 | return view; 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/elevation/DragFrameLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.elevation; 18 | 19 | import android.content.Context; 20 | import android.support.v4.widget.ViewDragHelper; 21 | import android.util.AttributeSet; 22 | import android.view.MotionEvent; 23 | import android.view.View; 24 | import android.widget.FrameLayout; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | /** 30 | * A {@link android.widget.FrameLayout} that allows the user to drag and reposition child views. 31 | */ 32 | public class DragFrameLayout extends FrameLayout { 33 | 34 | /** 35 | * The list of {@link android.view.View}s that will be draggable. 36 | */ 37 | private List mDragViews; 38 | 39 | /** 40 | * The {@link DragFrameLayoutController} that will be notify on drag. 41 | */ 42 | private DragFrameLayoutController mDragFrameLayoutController; 43 | 44 | private ViewDragHelper mDragHelper; 45 | 46 | public DragFrameLayout(Context context) { 47 | this(context, null, 0, 0); 48 | } 49 | 50 | public DragFrameLayout(Context context, AttributeSet attrs) { 51 | this(context, attrs, 0, 0); 52 | } 53 | 54 | public DragFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { 55 | this(context, attrs, defStyleAttr, 0); 56 | } 57 | 58 | public DragFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 59 | super(context, attrs, defStyleAttr, defStyleRes); 60 | mDragViews = new ArrayList(); 61 | 62 | /** 63 | * Create the {@link android.support.v4.widget.ViewDragHelper} and set its callback. 64 | */ 65 | mDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() { 66 | @Override 67 | public boolean tryCaptureView(View child, int pointerId) { 68 | return mDragViews.contains(child); 69 | } 70 | 71 | @Override 72 | public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { 73 | super.onViewPositionChanged(changedView, left, top, dx, dy); 74 | } 75 | 76 | @Override 77 | public int clampViewPositionHorizontal(View child, int left, int dx) { 78 | return left; 79 | } 80 | 81 | @Override 82 | public int clampViewPositionVertical(View child, int top, int dy) { 83 | return top; 84 | } 85 | 86 | @Override 87 | public void onViewCaptured(View capturedChild, int activePointerId) { 88 | super.onViewCaptured(capturedChild, activePointerId); 89 | if (mDragFrameLayoutController != null) { 90 | mDragFrameLayoutController.onDragDrop(true); 91 | } 92 | } 93 | 94 | @Override 95 | public void onViewReleased(View releasedChild, float xvel, float yvel) { 96 | super.onViewReleased(releasedChild, xvel, yvel); 97 | if (mDragFrameLayoutController != null) { 98 | mDragFrameLayoutController.onDragDrop(false); 99 | } 100 | } 101 | }); 102 | } 103 | 104 | @Override 105 | public boolean onInterceptTouchEvent(MotionEvent ev) { 106 | final int action = ev.getActionMasked(); 107 | if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { 108 | mDragHelper.cancel(); 109 | return false; 110 | } 111 | return mDragHelper.shouldInterceptTouchEvent(ev); 112 | } 113 | 114 | @Override 115 | public boolean onTouchEvent(MotionEvent ev) { 116 | mDragHelper.processTouchEvent(ev); 117 | return true; 118 | } 119 | 120 | /** 121 | * Adds a new {@link android.view.View} to the list of views that are draggable within the container. 122 | * @param dragView the {@link android.view.View} to make draggable 123 | */ 124 | public void addDragView(View dragView) { 125 | mDragViews.add(dragView); 126 | } 127 | 128 | /** 129 | * Sets the {@link DragFrameLayoutController} that will receive the drag events. 130 | * @param dragFrameLayoutController a {@link DragFrameLayoutController} 131 | */ 132 | public void setDragFrameController(DragFrameLayoutController dragFrameLayoutController) { 133 | mDragFrameLayoutController = dragFrameLayoutController; 134 | } 135 | 136 | /** 137 | * A controller that will receive the drag events. 138 | */ 139 | public interface DragFrameLayoutController { 140 | 141 | public void onDragDrop(boolean captured); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/elevation/ElevationActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.elevation; 18 | 19 | import android.os.Bundle; 20 | import android.support.v4.app.FragmentActivity; 21 | import android.support.v4.app.FragmentTransaction; 22 | 23 | import com.malmstein.materialanimations.R; 24 | 25 | /** 26 | * A simple launcher activity containing a summary sample description, sample log and a custom 27 | * {@link android.support.v4.app.Fragment} which can display a view. 28 | *

29 | * For devices with displays with a width of 720dp or greater, the sample log is always visible, 30 | * on other devices it's visibility is controlled by an item on the Action Bar. 31 | */ 32 | public class ElevationActivity extends FragmentActivity { 33 | 34 | public static final String TAG = "ElevationActivity"; 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_elevation); 40 | 41 | if (savedInstanceState == null) { 42 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 43 | ElevationDragFragment fragment = new ElevationDragFragment(); 44 | transaction.replace(R.id.sample_content_fragment, fragment); 45 | transaction.commit(); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/elevation/ElevationBasicFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.elevation; 18 | 19 | import android.os.Bundle; 20 | import android.support.v4.app.Fragment; 21 | import android.view.LayoutInflater; 22 | import android.view.MotionEvent; 23 | import android.view.View; 24 | import android.view.ViewGroup; 25 | 26 | import com.malmstein.materialanimations.R; 27 | 28 | public class ElevationBasicFragment extends Fragment { 29 | 30 | private final static String TAG = "ElevationBasicFragment"; 31 | 32 | @Override 33 | public void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setHasOptionsMenu(true); 36 | } 37 | 38 | @Override 39 | public View onCreateView( 40 | LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 41 | /** 42 | * Inflates an XML containing two shapes: the first has a fixed elevation 43 | * and the second ones raises when tapped. 44 | */ 45 | View rootView = inflater.inflate(R.layout.elevation_basic, container, false); 46 | 47 | View shape2 = rootView.findViewById(R.id.floating_shape_2); 48 | 49 | /** 50 | * Sets a {@Link View.OnTouchListener} that responds to a touch event on shape2. 51 | */ 52 | shape2.setOnTouchListener(new View.OnTouchListener() { 53 | @Override 54 | public boolean onTouch(View view, MotionEvent motionEvent) { 55 | int action = motionEvent.getActionMasked(); 56 | switch (action) { 57 | case MotionEvent.ACTION_DOWN: 58 | view.animate().setDuration(100).scaleX(1.2f).scaleY(1.3f).translationZ(120); 59 | break; 60 | case MotionEvent.ACTION_UP: 61 | view.animate().setDuration(100).scaleX(1).scaleY(1).translationZ(0); 62 | break; 63 | default: 64 | return false; 65 | } 66 | return true; 67 | } 68 | }); 69 | return rootView; 70 | } 71 | } -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/elevation/ElevationDragFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.elevation; 18 | 19 | import android.graphics.Outline; 20 | import android.os.Bundle; 21 | import android.support.v4.app.Fragment; 22 | import android.view.LayoutInflater; 23 | import android.view.View; 24 | import android.view.ViewGroup; 25 | import android.view.ViewOutlineProvider; 26 | 27 | import com.malmstein.materialanimations.R; 28 | import com.novoda.notils.logger.simple.Log; 29 | 30 | public class ElevationDragFragment extends Fragment { 31 | 32 | public static final String TAG = "ElevationDragFragment"; 33 | 34 | /* The circular outline provider */ 35 | private ViewOutlineProvider mOutlineProviderCircle; 36 | 37 | /* The current elevation of the floating view. */ 38 | private float mElevation = 0; 39 | 40 | /* The step in elevation when changing the Z value */ 41 | private int mElevationStep; 42 | 43 | @Override 44 | public void onCreate(Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | 47 | mOutlineProviderCircle = new CircleOutlineProvider(); 48 | 49 | mElevationStep = getResources().getDimensionPixelSize(R.dimen.elevation_step); 50 | } 51 | 52 | @Override 53 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 54 | Bundle savedInstanceState) { 55 | View rootView = inflater.inflate(R.layout.fragment_ztranslation, container, false); 56 | 57 | /* Find the {@link View} to apply z-translation to. */ 58 | final View floatingShape = rootView.findViewById(R.id.circle); 59 | 60 | /* Define the shape of the {@link View}'s shadow by setting one of the {@link Outline}s. */ 61 | floatingShape.setOutlineProvider(mOutlineProviderCircle); 62 | 63 | /* Clip the {@link View} with its outline. */ 64 | floatingShape.setClipToOutline(true); 65 | 66 | DragFrameLayout dragLayout = ((DragFrameLayout) rootView.findViewById(R.id.main_layout)); 67 | 68 | dragLayout.setDragFrameController(new DragFrameLayout.DragFrameLayoutController() { 69 | 70 | @Override 71 | public void onDragDrop(boolean captured) { 72 | /* Animate the translation of the {@link View}. Note that the translation 73 | is being modified, not the elevation. */ 74 | floatingShape.animate() 75 | .translationZ(captured ? 50 : 0) 76 | .scaleX(1.2f) 77 | .scaleY(1.3f) 78 | .setDuration(100); 79 | Log.d(TAG, captured ? "Drag" : "Drop"); 80 | } 81 | }); 82 | 83 | dragLayout.addDragView(floatingShape); 84 | 85 | /* Raise the circle in z when the "z+" button is clicked. */ 86 | rootView.findViewById(R.id.raise_bt).setOnClickListener(new View.OnClickListener() { 87 | @Override 88 | public void onClick(View v) { 89 | mElevation += mElevationStep; 90 | Log.d(TAG, String.format("Elevation: %.1f", mElevation)); 91 | floatingShape.setElevation(mElevation); 92 | } 93 | }); 94 | 95 | /* Lower the circle in z when the "z-" button is clicked. */ 96 | rootView.findViewById(R.id.lower_bt).setOnClickListener(new View.OnClickListener() { 97 | @Override 98 | public void onClick(View v) { 99 | mElevation -= mElevationStep; 100 | // Don't allow for negative values of Z. 101 | if (mElevation < 0) { 102 | mElevation = 0; 103 | } 104 | Log.d(TAG, String.format("Elevation: %.1f", mElevation)); 105 | } 106 | }); 107 | 108 | return rootView; 109 | } 110 | 111 | /** 112 | * ViewOutlineProvider which sets the outline to be an oval which fits the view bounds. 113 | */ 114 | private class CircleOutlineProvider extends ViewOutlineProvider { 115 | @Override 116 | public void getOutline(View view, Outline outline) { 117 | outline.setOval(0, 0, view.getWidth(), view.getHeight()); 118 | } 119 | } 120 | 121 | } -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/interpolator/InterpolatorActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.interpolator; 18 | 19 | import android.os.Bundle; 20 | import android.support.v4.app.FragmentActivity; 21 | import android.support.v4.app.FragmentTransaction; 22 | 23 | import com.malmstein.materialanimations.R; 24 | 25 | /** 26 | * A simple launcher activity containing a summary sample description, sample log and a custom 27 | * {@link android.support.v4.app.Fragment} which can display a view. 28 | *

29 | * For devices with displays with a width of 720dp or greater, the sample log is always visible, 30 | * on other devices it's visibility is controlled by an item on the Action Bar. 31 | */ 32 | public class InterpolatorActivity extends FragmentActivity { 33 | 34 | public static final String TAG = "InterpolatorActivity"; 35 | 36 | @Override 37 | protected void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_interpolator); 40 | 41 | if (savedInstanceState == null) { 42 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 43 | InterpolatorFragment fragment = new InterpolatorFragment(); 44 | transaction.replace(R.id.sample_content_fragment, fragment); 45 | transaction.commit(); 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/malmstein/materialanimations/interpolator/InterpolatorFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.malmstein.materialanimations.interpolator; 18 | 19 | import android.animation.ObjectAnimator; 20 | import android.graphics.Path; 21 | import android.os.Bundle; 22 | import android.support.v4.app.Fragment; 23 | import android.view.LayoutInflater; 24 | import android.view.View; 25 | import android.view.ViewGroup; 26 | import android.view.animation.AnimationUtils; 27 | import android.view.animation.Interpolator; 28 | import android.widget.ArrayAdapter; 29 | import android.widget.Button; 30 | import android.widget.SeekBar; 31 | import android.widget.Spinner; 32 | import android.widget.TextView; 33 | 34 | import com.malmstein.materialanimations.R; 35 | import com.novoda.notils.logger.simple.Log; 36 | 37 | /** 38 | * This sample demonstrates the use of animation interpolators and path animations for 39 | * Material Design. 40 | * It shows how an {@link android.animation.ObjectAnimator} is used to animate two properties of a 41 | * view (scale X and Y) along a path. 42 | */ 43 | public class InterpolatorFragment extends Fragment { 44 | 45 | /** 46 | * View that is animated. 47 | */ 48 | private View mView; 49 | /** 50 | * Spinner for selection of interpolator. 51 | */ 52 | private Spinner mInterpolatorSpinner; 53 | /** 54 | * SeekBar for selection of duration of animation. 55 | */ 56 | private SeekBar mDurationSeekbar; 57 | /** 58 | * TextView that shows animation selected in SeekBar. 59 | */ 60 | private TextView mDurationLabel; 61 | 62 | /** 63 | * Interpolators used for animation. 64 | */ 65 | private Interpolator mInterpolators[]; 66 | /** 67 | * Path for in (shrinking) animation, from 100% scale to 20%. 68 | */ 69 | private Path mPathIn; 70 | /** 71 | * Path for out (growing) animation, from 20% to 100%. 72 | */ 73 | private Path mPathOut; 74 | 75 | /** 76 | * Set to true if View is animated out (is shrunk). 77 | */ 78 | private boolean mIsOut = false; 79 | 80 | /** 81 | * Default duration of animation in ms. 82 | */ 83 | private static final int INITIAL_DURATION_MS = 750; 84 | 85 | /** 86 | * String used for logging. 87 | */ 88 | public static final String TAG = "InterpolatorplaygroundFragment"; 89 | 90 | public InterpolatorFragment() { 91 | // Required empty public constructor 92 | } 93 | 94 | @Override 95 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 96 | Bundle savedInstanceState) { 97 | 98 | // Inflate the fragment_animation layout 99 | View v = inflater.inflate(R.layout.interpolator_fragment, container, false); 100 | 101 | // Set up the 'animate' button, when it is clicked the view is animated with the options 102 | // selected: the Interpolator, duration and animation path 103 | Button button = (Button) v.findViewById(R.id.animateButton); 104 | button.setOnClickListener(new View.OnClickListener() { 105 | @Override 106 | public void onClick(View view) { 107 | // Interpolator selected in the spinner 108 | Interpolator interpolator = mInterpolators[mInterpolatorSpinner.getSelectedItemPosition()]; 109 | // Duration selected in SeekBar 110 | long duration = mDurationSeekbar.getProgress(); 111 | // Animation path is based on whether animating in or out 112 | Path path = mIsOut ? mPathIn : mPathOut; 113 | 114 | // Log animation details 115 | Log.i(TAG, String.format("Starting animation: [%d ms, %s, %s]", 116 | duration, (String) mInterpolatorSpinner.getSelectedItem(), 117 | ((mIsOut) ? "Out (growing)" : "In (shrinking)"))); 118 | 119 | // Start the animation with the selected options 120 | startAnimation(interpolator, duration, path); 121 | 122 | // Toggle direction of animation (path) 123 | mIsOut = !mIsOut; 124 | } 125 | }); 126 | 127 | // Get the label to display the selected duration 128 | mDurationLabel = (TextView) v.findViewById(R.id.durationLabel); 129 | 130 | // Initialize Interpolators programmatically by loading them from their XML definitions 131 | // provided by the framework. 132 | mInterpolators = new Interpolator[]{ 133 | new AnimationUtils().loadInterpolator(getActivity(), 134 | android.R.interpolator.linear), 135 | new AnimationUtils().loadInterpolator(getActivity(), 136 | android.R.interpolator.fast_out_linear_in), 137 | new AnimationUtils().loadInterpolator(getActivity(), 138 | android.R.interpolator.fast_out_slow_in), 139 | new AnimationUtils().loadInterpolator(getActivity(), 140 | android.R.interpolator.linear_out_slow_in) 141 | }; 142 | 143 | // Load names of interpolators from a resource 144 | String[] interpolatorNames = getResources().getStringArray(R.array.interpolator_names); 145 | 146 | // Set up the Spinner with the names of interpolators 147 | mInterpolatorSpinner = (Spinner) v.findViewById(R.id.interpolatorSpinner); 148 | ArrayAdapter spinnerAdapter = 149 | new ArrayAdapter(getActivity(), 150 | android.R.layout.simple_spinner_dropdown_item, interpolatorNames); 151 | mInterpolatorSpinner.setAdapter(spinnerAdapter); 152 | 153 | // Set up SeekBar that defines the duration of the animation 154 | mDurationSeekbar = (SeekBar) v.findViewById(R.id.durationSeek); 155 | 156 | // Register listener to update the text label when the SeekBar value is updated 157 | mDurationSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 158 | @Override 159 | public void onProgressChanged(SeekBar seekBar, int i, boolean b) { 160 | mDurationLabel.setText(getResources().getString(R.string.animation_duration, i)); 161 | } 162 | 163 | @Override 164 | public void onStartTrackingTouch(SeekBar seekBar) { 165 | } 166 | 167 | @Override 168 | public void onStopTrackingTouch(SeekBar seekBar) { 169 | } 170 | }); 171 | 172 | // Set initial progress to trigger SeekBarChangeListener and update UI 173 | mDurationSeekbar.setProgress(INITIAL_DURATION_MS); 174 | 175 | // Get the view that will be animated 176 | mView = v.findViewById(R.id.square); 177 | 178 | // The following Path definitions are used by the ObjectAnimator to scale the view. 179 | 180 | // Path for 'in' animation: growing from 20% to 100% 181 | mPathIn = new Path(); 182 | mPathIn.moveTo(0.2f, 0.2f); 183 | mPathIn.lineTo(1f, 1f); 184 | 185 | // Path for 'out' animation: shrinking from 100% to 20% 186 | mPathOut = new Path(); 187 | mPathOut.moveTo(1f, 1f); 188 | mPathOut.lineTo(0.2f, 0.2f); 189 | return v; 190 | } 191 | 192 | /** 193 | * Start an animation on the sample view. 194 | * The view is animated using an {@link android.animation.ObjectAnimator} on the 195 | * {@link android.view.View#SCALE_X} and {@link android.view.View#SCALE_Y} properties, with its animation based on a path. 196 | * The only two paths defined here ({@link #mPathIn} and {@link #mPathOut}) scale the view 197 | * uniformly. 198 | * 199 | * @param interpolator The interpolator to use for the animation. 200 | * @param duration Duration of the animation in ms. 201 | * @param path Path of the animation 202 | * @return The ObjectAnimator used for this animation 203 | * @see android.animation.ObjectAnimator#ofFloat(Object, String, String, android.graphics.Path) 204 | */ 205 | public ObjectAnimator startAnimation(Interpolator interpolator, long duration, Path path) { 206 | // This ObjectAnimator uses the path to change the x and y scale of the mView object. 207 | ObjectAnimator animator = ObjectAnimator.ofFloat(mView, View.SCALE_X, View.SCALE_Y, path); 208 | 209 | // Set the duration and interpolator for this animation 210 | animator.setDuration(duration); 211 | animator.setInterpolator(interpolator); 212 | 213 | animator.start(); 214 | 215 | return animator; 216 | } 217 | 218 | /** 219 | * Return the array of loaded Interpolators available in this Fragment. 220 | * 221 | * @return Interpolators 222 | */ 223 | public Interpolator[] getInterpolators() { 224 | return mInterpolators; 225 | } 226 | 227 | /** 228 | * Return the animation path for the 'in' (shrinking) animation. 229 | * 230 | * @return 231 | */ 232 | public Path getPathIn() { 233 | return mPathIn; 234 | } 235 | 236 | /** 237 | * Return the animation path for the 'out' (growing) animation. 238 | * 239 | * @return 240 | */ 241 | public Path getPathOut() { 242 | return mPathOut; 243 | } 244 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malmstein/MaterialAnimations/21576744b6236a9e44dd5834d6993fd585c61e4f/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/tile.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malmstein/MaterialAnimations/21576744b6236a9e44dd5834d6993fd585c61e4f/app/src/main/res/drawable-hdpi/tile.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malmstein/MaterialAnimations/21576744b6236a9e44dd5834d6993fd585c61e4f/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malmstein/MaterialAnimations/21576744b6236a9e44dd5834d6993fd585c61e4f/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malmstein/MaterialAnimations/21576744b6236a9e44dd5834d6993fd585c61e4f/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_fab_default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape2.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_elevation.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_interpolator.xml: -------------------------------------------------------------------------------- 1 | 16 | 22 | 23 | 27 | 28 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_transition.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_transition_details.xml: -------------------------------------------------------------------------------- 1 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 27 | 28 | 32 | 33 | 38 | 39 | 40 | 41 | 51 | 52 | 59 | 60 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/layout/elevation_basic.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | 30 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_ztranslation.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 24 | 25 | 31 | 32 | 37 | 38 |