From e45b1a80e3d5e7a82a57c4e003e0cdac7e6ccd15 Mon Sep 17 00:00:00 2001 From: Ozodrukh Date: Thu, 16 Mar 2017 14:53:15 +0500 Subject: [PATCH] Update to show usage of Spring Animation in details --- app/build.gradle | 24 ++- .../circualrevealsample/MainActivity.java | 38 +++- .../RadialTransformationActivity.java | 29 ++- .../SpringSettingsBottomDialog.java | 147 ++++++++++++++ .../res/drawable/ic_looks_one_black_24dp.xml | 9 + .../res/drawable/ic_looks_two_black_24dp.xml | 9 + app/src/main/res/layout/activity_main.xml | 184 ++++++++++-------- app/src/main/res/layout/activity_sample_2.xml | 13 +- app/src/main/res/values/styles.xml | 3 +- 9 files changed, 354 insertions(+), 102 deletions(-) create mode 100644 app/src/main/java/io/codetail/circualrevealsample/SpringSettingsBottomDialog.java create mode 100644 app/src/main/res/drawable/ic_looks_one_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_looks_two_black_24dp.xml diff --git a/app/build.gradle b/app/build.gradle index db86d4d..a06c153 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,15 +2,19 @@ apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion project.compileSDKVersion + buildToolsVersion project.buildToolsVersion defaultConfig { - applicationId "io.codetail.circualrevealsample" - minSdkVersion 15 - targetSdkVersion 23 + minSdkVersion project.minSDKVersion + targetSdkVersion project.targetSDKVersion versionCode 1 versionName "1.0" + applicationId "io.codetail.circualrevealsample" + + vectorDrawables { + useSupportLibrary = true + } } lintOptions { @@ -21,11 +25,13 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':circualreveal') + compile project(':spring-revealmanager') - compile 'com.android.support:appcompat-v7:23.4.0' - compile 'com.android.support:recyclerview-v7:23.4.0' - compile 'com.android.support:cardview-v7:23.4.0' - compile 'com.android.support:design:23.4.0' + compile "com.android.support:appcompat-v7:$support_lib_version" + compile "com.android.support:recyclerview-v7:$support_lib_version" + compile "com.android.support:cardview-v7:$support_lib_version" + compile "com.android.support:design:$support_lib_version" + compile "com.android.support:support-dynamic-animation:$support_lib_version" compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.jakewharton:butterknife:8.0.1' diff --git a/app/src/main/java/io/codetail/circualrevealsample/MainActivity.java b/app/src/main/java/io/codetail/circualrevealsample/MainActivity.java index 062e19e..371b851 100644 --- a/app/src/main/java/io/codetail/circualrevealsample/MainActivity.java +++ b/app/src/main/java/io/codetail/circualrevealsample/MainActivity.java @@ -8,7 +8,9 @@ import android.graphics.Rect; import android.os.Build; import android.os.Bundle; +import android.support.animation.SpringForce; import android.support.annotation.Nullable; +import android.support.design.widget.BottomSheetBehavior; import android.support.v4.view.animation.FastOutLinearInInterpolator; import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.support.v7.app.AppCompatActivity; @@ -16,22 +18,28 @@ import android.util.Property; import android.view.View; import android.view.ViewGroup; +import android.widget.CompoundButton; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; +import io.codetail.animation.RevealViewGroup; +import io.codetail.animation.SpringViewAnimatorManager; import io.codetail.animation.ViewAnimationUtils; +import io.codetail.animation.ViewRevealManager; +import io.codetail.widget.RevealFrameLayout; /** - * Aware section - * https://www.google.com/design/spec/motion/material-motion.html#material-motion-how-does-material-move + * Aware section https://www.google.com/design/spec/motion/material-motion.html#material-motion-how-does-material-move */ public class MainActivity extends AppCompatActivity { final static int SLOW_DURATION = 400; final static int FAST_DURATION = 200; + @BindView(R.id.parent) RevealFrameLayout parent; @BindView(R.id.circlesLine) ViewGroup circlesLine; @BindView(R.id.cardsLine) ViewGroup cardsLine; @BindView(R.id.activator_mask) CardView activatorMask; + @BindView(R.id.springSettings) SpringSettingsBottomDialog settingsView; private float maskElevation; @@ -39,6 +47,25 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); + + final ViewRevealManager revealManager = new ViewRevealManager(); + final SpringViewAnimatorManager springManager = new SpringViewAnimatorManager(); + springManager.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); + springManager.setStiffness(SpringForce.STIFFNESS_LOW); + + parent.setViewRevealManager(revealManager); + + settingsView.addSwitch("Enable Spring", false, new CompoundButton.OnCheckedChangeListener() { + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + parent.setViewRevealManager(isChecked ? springManager : revealManager); + } + }); + settingsView.setAnimatorManager(springManager); + + final BottomSheetBehavior behavior = BottomSheetBehavior.from(settingsView); + behavior.setPeekHeight(getResources().getDimensionPixelSize(R.dimen.bottom_peek_height)); + behavior.setSkipCollapsed(false); + behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } @OnClick(R.id.activator) void activateAwareMotion(View target) { @@ -58,7 +85,7 @@ public class MainActivity extends AppCompatActivity { parent.offsetDescendantRectToMyCoords(target, bounds); parent.offsetDescendantRectToMyCoords(activatorMask, maskBounds); - // Put Mask view at circle initial points + // Put Mask view at circle 8initial points maskElevation = activatorMask.getCardElevation(); activatorMask.setCardElevation(0); activatorMask.setVisibility(View.VISIBLE); @@ -70,10 +97,11 @@ public class MainActivity extends AppCompatActivity { final int cX = maskBounds.centerX(); final int cY = maskBounds.centerY(); + final float endRadius = (float) Math.hypot(maskBounds.width() * .5f, maskBounds.height() * .5f); + Animator circularReveal = ViewAnimationUtils.createCircularReveal(activatorMask, cX, cY, target.getWidth() / 2, - (float) Math.hypot(maskBounds.width() * .5f, maskBounds.height() * .5f), - View.LAYER_TYPE_HARDWARE); + endRadius, View.LAYER_TYPE_HARDWARE); final float c0X = bounds.centerX() - maskBounds.centerX(); final float c0Y = bounds.centerY() - maskBounds.centerY(); diff --git a/app/src/main/java/io/codetail/circualrevealsample/RadialTransformationActivity.java b/app/src/main/java/io/codetail/circualrevealsample/RadialTransformationActivity.java index c8c47b2..9184f1b 100644 --- a/app/src/main/java/io/codetail/circualrevealsample/RadialTransformationActivity.java +++ b/app/src/main/java/io/codetail/circualrevealsample/RadialTransformationActivity.java @@ -5,19 +5,26 @@ import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; +import android.support.animation.SpringForce; import android.support.annotation.Nullable; +import android.support.design.widget.BottomSheetBehavior; import android.support.v4.view.animation.FastOutLinearInInterpolator; import android.support.v7.app.AppCompatActivity; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.widget.CompoundButton; import android.widget.ImageView; import android.widget.VideoView; import butterknife.BindView; import butterknife.ButterKnife; import com.squareup.picasso.Picasso; +import io.codetail.animation.SpringViewAnimatorManager; import io.codetail.animation.ViewAnimationUtils; +import io.codetail.animation.ViewRevealManager; +import io.codetail.widget.RevealFrameLayout; /** * https://www.google.com/design/spec/motion/choreography.html#choreography-radial-reaction @@ -28,9 +35,10 @@ private final static String VIDEO_URL = "https://material-design.storage.googleapis.com/publish/material_v_8/material_ext_publish/0B14F_FSUCc01WUt2SFZkbGVuNVk/RR_Point_of_Contact_001.mp4"; - @BindView(R.id.view_stack) ViewGroup stack; + @BindView(R.id.view_stack) RevealFrameLayout stack; @BindView(R.id.san_francisco) ImageView sanFranciscoView; @BindView(R.id.video) VideoView videoView; + @BindView(R.id.springSettings) SpringSettingsBottomDialog settingsView; private int currentViewIndex = 0; @@ -63,6 +71,25 @@ } }); } + + final ViewRevealManager revealManager = new ViewRevealManager(); + final SpringViewAnimatorManager springManager = new SpringViewAnimatorManager(); + springManager.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY); + springManager.setStiffness(SpringForce.STIFFNESS_LOW); + + stack.setViewRevealManager(revealManager); + + settingsView.addSwitch("Enable Spring", false, new CompoundButton.OnCheckedChangeListener() { + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + stack.setViewRevealManager(isChecked ? springManager : revealManager); + } + }); + settingsView.setAnimatorManager(springManager); + + final BottomSheetBehavior behavior = BottomSheetBehavior.from(settingsView); + behavior.setPeekHeight(getResources().getDimensionPixelSize(R.dimen.bottom_peek_height)); + behavior.setSkipCollapsed(false); + behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } private GestureDetector.OnGestureListener tapDetector = diff --git a/app/src/main/java/io/codetail/circualrevealsample/SpringSettingsBottomDialog.java b/app/src/main/java/io/codetail/circualrevealsample/SpringSettingsBottomDialog.java new file mode 100644 index 0000000..50f67d1 --- /dev/null +++ b/app/src/main/java/io/codetail/circualrevealsample/SpringSettingsBottomDialog.java @@ -0,0 +1,147 @@ +package io.codetail.circualrevealsample; + +import android.content.Context; +import android.support.animation.SpringForce; +import android.support.v7.widget.AppCompatTextView; +import android.support.v7.widget.SwitchCompat; +import android.util.AttributeSet; +import android.widget.CompoundButton; +import android.widget.LinearLayout; +import android.widget.SeekBar; +import android.widget.TextView; +import io.codetail.animation.RevealViewGroup; +import io.codetail.animation.SpringViewAnimatorManager; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; + +/** + * created at 3/16/17 + * + * @author Ozodrukh + * @version 1.0 + */ +public class SpringSettingsBottomDialog extends LinearLayout { + private boolean springManagerAdded = false; + private boolean switchAdded = false; + + private SeekBar stiffnessView; + private SeekBar dampingView; + + public SpringSettingsBottomDialog(Context context, AttributeSet attrs) { + super(context, attrs); + final int padding = dp(16); + + setOrientation(VERTICAL); + setPadding(padding, padding, padding, padding); + } + + public void setAnimatorManager(final SpringViewAnimatorManager animatorManager) { + if (springManagerAdded) { + // already inflated progress bars + return; + } + + springManagerAdded = true; + + final int stiffnessVal = + (int) ((animatorManager.getStiffness() / SpringForce.STIFFNESS_HIGH) * 100f); + + final int dampingVal = + (int) (animatorManager.getDampingRatio() / SpringForce.DAMPING_RATIO_NO_BOUNCY * 100f); + + stiffnessView = + createConfigurationView("Stiffness", stiffnessVal, new OnProgressChangeListener() { + @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + animatorManager.setStiffness(3000 * (progress / 100f)); + } + }); + + dampingView = + createConfigurationView("Damping Ratio", dampingVal, new OnProgressChangeListener() { + @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + animatorManager.setDampingRatio(progress / 100f); + } + }); + } + + public void addSwitch(String label, boolean defaultState, + final CompoundButton.OnCheckedChangeListener listener) { + if (switchAdded) { + return; + } + + switchAdded = true; + + final SwitchCompat switchView = new SwitchCompat(getContext()); + switchView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + listener.onCheckedChanged(buttonView, isChecked); + + if (springManagerAdded) { + stiffnessView.setEnabled(isChecked); + dampingView.setEnabled(isChecked); + } + } + }); + switchView.setChecked(defaultState); + switchView.setText(label); + + addView(switchView, createMarginLayoutParams(MATCH_PARENT, WRAP_CONTENT, 0, 0, 0, dp(16))); + + if (springManagerAdded) { + stiffnessView.setEnabled(defaultState); + dampingView.setEnabled(defaultState); + } + } + + private SeekBar createConfigurationView(CharSequence label, int defaultVal, + SeekBar.OnSeekBarChangeListener changeListener) { + + final TextView labelView = + new AppCompatTextView(getContext(), null, R.style.TextAppearance_AppCompat_Caption); + labelView.setText(label); + labelView.setLayoutParams(createMarginLayoutParams(MATCH_PARENT, WRAP_CONTENT, 0, 0, 0, dp(8))); + + final SeekBar seekBar = new SeekBar(getContext()); + seekBar.setProgress(defaultVal); + seekBar.setMax(100); + seekBar.setOnSeekBarChangeListener(changeListener); + + seekBar.setLayoutParams(createMarginLayoutParams(MATCH_PARENT, WRAP_CONTENT, 0, 0, 0, dp(16))); + + addView(labelView); + addView(seekBar); + return seekBar; + } + + private int dp(float px) { + return (int) (getContext().getResources().getDisplayMetrics().density * px); + } + + private static MarginLayoutParams createMarginLayoutParams(int w, int h, int l, int t, int r, + int b) { + MarginLayoutParams lp = new MarginLayoutParams(w, h); + lp.leftMargin = l; + lp.topMargin = t; + lp.rightMargin = r; + lp.bottomMargin = b; + return lp; + } + + private static abstract class OnProgressChangeListener + implements SeekBar.OnSeekBarChangeListener { + + @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + + } + + @Override public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override public void onStopTrackingTouch(SeekBar seekBar) { + + } + } +} diff --git a/app/src/main/res/drawable/ic_looks_one_black_24dp.xml b/app/src/main/res/drawable/ic_looks_one_black_24dp.xml new file mode 100644 index 0000000..8eb0c29 --- /dev/null +++ b/app/src/main/res/drawable/ic_looks_one_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_looks_two_black_24dp.xml b/app/src/main/res/drawable/ic_looks_two_black_24dp.xml new file mode 100644 index 0000000..5a2a920 --- /dev/null +++ b/app/src/main/res/drawable/ic_looks_two_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2fc365a..8ed898c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,4 +1,4 @@ - - + tools:context=".MainActivity"> - + android:clipChildren="false"> - - - + android:layout_gravity="center" + android:clipChildren="false" + android:clipToPadding="false" + android:gravity="center" + android:orientation="horizontal"> - + - + - - + + app:elevation="2dp" + /> - + - + + + + + + + + + + + - + - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_sample_2.xml b/app/src/main/res/layout/activity_sample_2.xml index e6b14c2..b4ac406 100644 --- a/app/src/main/res/layout/activity_sample_2.xml +++ b/app/src/main/res/layout/activity_sample_2.xml @@ -1,12 +1,11 @@ - - \ No newline at end of file + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d9eee3d..83f5d8a 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -77,11 +77,12 @@ 8dp 24dp + 56dp