diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java index 3cd4477..040c766 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java +++ b/app/src/main/java/com/github/axet/audiorecorder/activities/RecordingActivity.java @@ -32,6 +32,7 @@ import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; +import android.view.animation.Animation; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.RemoteViews; @@ -39,6 +40,7 @@ import android.widget.TextView; import android.widget.Toast; import com.github.axet.audiorecorder.R; +import com.github.axet.audiorecorder.animations.MarginBottomAnimation; import com.github.axet.audiorecorder.app.MainApplication; import com.github.axet.audiorecorder.app.RawSamples; import com.github.axet.audiorecorder.app.Sound; @@ -159,7 +161,7 @@ public class RecordingActivity extends AppCompatActivity { state = (TextView) findViewById(R.id.recording_state); title = (TextView) findViewById(R.id.recording_title); - edit(false); + edit(false, false); storage = new Storage(this); sound = new Sound(this); @@ -332,7 +334,7 @@ public class RecordingActivity extends AppCompatActivity { super.onPause(); Log.d(TAG, "onPause"); updateBufferSize(true); - edit(false); + edit(false, true); pitch.stop(); } @@ -347,7 +349,10 @@ public class RecordingActivity extends AppCompatActivity { pitch.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { - edit(true); + View box = findViewById(R.id.recording_edit_box); + Animation a = box.getAnimation(); + boolean animate = box.getVisibility() == View.GONE || (a != null && !a.hasEnded()); + edit(true, animate); editSample = pitch.edit(event.getX()) * samplesUpdate; return true; } @@ -363,13 +368,13 @@ public class RecordingActivity extends AppCompatActivity { sound.unsilent(); } - void edit(boolean b) { + void edit(boolean b, boolean animate) { if (b) { state.setText("edit"); editPlay(false); View box = findViewById(R.id.recording_edit_box); - box.setVisibility(View.VISIBLE); + MarginBottomAnimation.apply(box, true, animate); View cut = box.findViewById(R.id.recording_cut); cut.setOnClickListener(new View.OnClickListener() { @@ -395,7 +400,7 @@ public class RecordingActivity extends AppCompatActivity { done.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - edit(false); + edit(false, true); } }); } else { @@ -403,8 +408,9 @@ public class RecordingActivity extends AppCompatActivity { state.setText("pause"); editPlay(false); pitch.stop(); + View box = findViewById(R.id.recording_edit_box); - box.setVisibility(View.GONE); + MarginBottomAnimation.apply(box, false, animate); } } @@ -463,7 +469,7 @@ public class RecordingActivity extends AppCompatActivity { RawSamples rs = new RawSamples(storage.getTempRecording()); rs.trunk(editSample + 1); rs.close(); - edit(false); + edit(false, true); loadSamples(); pitch.drawCalc(); } @@ -519,7 +525,7 @@ public class RecordingActivity extends AppCompatActivity { } void startRecording() { - edit(false); + edit(false, true); pitch.setOnTouchListener(null); state.setText("recording"); diff --git a/app/src/main/java/com/github/axet/audiorecorder/animations/MarginAnimation.java b/app/src/main/java/com/github/axet/audiorecorder/animations/MarginAnimation.java index 07ba42f..9b43e67 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/animations/MarginAnimation.java +++ b/app/src/main/java/com/github/axet/audiorecorder/animations/MarginAnimation.java @@ -41,7 +41,6 @@ public class MarginAnimation extends StepAnimation { ViewGroup.MarginLayoutParams viewLp; ViewGroup.MarginLayoutParams viewLpOrig; int marginSlide; - boolean expand; public static void apply(final View v, final boolean expand, boolean animate) { apply(new LateCreator() { @@ -53,8 +52,7 @@ public class MarginAnimation extends StepAnimation { } public MarginAnimation(View v, boolean expand) { - super(v); - this.expand = expand; + super(v, expand); setDuration(500); diff --git a/app/src/main/java/com/github/axet/audiorecorder/animations/MarginBottomAnimation.java b/app/src/main/java/com/github/axet/audiorecorder/animations/MarginBottomAnimation.java new file mode 100644 index 0000000..1bd2314 --- /dev/null +++ b/app/src/main/java/com/github/axet/audiorecorder/animations/MarginBottomAnimation.java @@ -0,0 +1,115 @@ +package com.github.axet.audiorecorder.animations; + +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Transformation; + +/** + * Animation Tranformation.getMatrix() has no issues. But animation properies does. Here are few + * issues about animations properties. + *

+ * First: + *

+ * If your animation touches some elements, then hide them (GONE), some properties may not be + * recalculated because element is hidden. + *

+ * Here is no solution. You have to restore all properties of evey view which may be affected by + * running animation to its initial state. + *

+ * If you dont you may see routated (setRotate) or hidded (setAlpha) elements even if endAnimation() + * restore thier initial states (do setRotate(0) or setApha(1) do not make them not rotated or + * visible). + *

+ * Second: + *

+ * On normal run we have onAnimationEnd() is not final call applyTransformation() called after that. + *

+ * applyTransformation() + * onAnimationEnd() + * applyTransformation() + *

+ * On animation cancel we have: + * applyTransformation() + * onAnimationEnd() + *

+ * Which makes unpredictable where do we have to finish animation with initial values on top of first + * statement. + */ +public class MarginBottomAnimation extends StepAnimation { + + ViewGroup.MarginLayoutParams viewLp; + ViewGroup.MarginLayoutParams viewLpOrig; + + int vh; + + public static void apply(final View v, final boolean expand, boolean animate) { + apply(new LateCreator() { + @Override + public MarginBottomAnimation create() { + return new MarginBottomAnimation(v, expand); + } + }, v, expand, animate); + } + + public MarginBottomAnimation(View v, boolean expand) { + super(v, expand); + + setDuration(500); + + viewLp = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); + viewLpOrig = new ViewGroup.MarginLayoutParams(viewLp); + } + + @Override + public void init() { + super.init(); + + ViewGroup parent = (ViewGroup) view.getParent(); + int parentWidth = parent.getWidth(); + int parentHeight = parent.getHeight(); + + int width = view.getWidth(); + int height = view.getHeight(); + + int h; + int w; + + if (height == 0 && parentHeight == 0) + h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + else + h = View.MeasureSpec.makeMeasureSpec(Math.max(height, parentHeight), View.MeasureSpec.AT_MOST); + + w = View.MeasureSpec.makeMeasureSpec(Math.max(width, parentWidth), View.MeasureSpec.AT_MOST); + + view.measure(w, h); + vh = view.getMeasuredHeight(); + + view.measure(w, h); + } + + @Override + public void calc(float i, Transformation t) { + super.calc(i, t); + + i = expand ? 1 - i : i; + + viewLp.bottomMargin = (int) (-vh * i); + view.requestLayout(); + } + + @Override + public void restore() { + super.restore(); + + viewLp.bottomMargin = viewLpOrig.bottomMargin; + } + + @Override + public void end() { + super.end(); + + view.setVisibility(expand ? View.VISIBLE : View.GONE); + view.requestLayout(); + } + +} diff --git a/app/src/main/java/com/github/axet/audiorecorder/animations/StepAnimation.java b/app/src/main/java/com/github/axet/audiorecorder/animations/StepAnimation.java index bae62ca..665fbd7 100644 --- a/app/src/main/java/com/github/axet/audiorecorder/animations/StepAnimation.java +++ b/app/src/main/java/com/github/axet/audiorecorder/animations/StepAnimation.java @@ -9,8 +9,8 @@ import android.view.animation.AnimationUtils; import android.view.animation.Transformation; public class StepAnimation extends Animation { - View view; + boolean expand; public interface LateCreator { StepAnimation create(); @@ -18,8 +18,8 @@ public class StepAnimation extends Animation { public static void apply(LateCreator c, View v, boolean expand, boolean animate) { Animation old = v.getAnimation(); - if (old != null && old instanceof MarginAnimation) { - MarginAnimation m = (MarginAnimation) old; + if (old != null && old instanceof StepAnimation) { + StepAnimation m = (StepAnimation) old; long cur = AnimationUtils.currentAnimationTimeMillis(); long past = cur - m.getStartTime() - m.getStartOffset(); @@ -58,8 +58,9 @@ public class StepAnimation extends Animation { } } - public StepAnimation(View view) { + public StepAnimation(View view, boolean expand) { this.view = view; + this.expand = expand; } public void startAnimation(View v) {