anumation box

This commit is contained in:
Alexey Kuznetsov 2016-03-26 19:58:03 +03:00
commit 3910aebc5e
4 changed files with 136 additions and 16 deletions

View file

@ -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");

View file

@ -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);

View file

@ -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.
* <p/>
* First:
* <p/>
* If your animation touches some elements, then hide them (GONE), some properties may not be
* recalculated because element is hidden.
* <p/>
* Here is no solution. You have to restore all properties of evey view which may be affected by
* running animation to its initial state.
* <p/>
* 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).
* <p/>
* Second:
* <p/>
* On normal run we have onAnimationEnd() is not final call applyTransformation() called after that.
* <p/>
* applyTransformation()
* onAnimationEnd()
* applyTransformation()
* <p/>
* On animation cancel we have:
* applyTransformation()
* onAnimationEnd()
* <p/>
* 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();
}
}

View file

@ -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) {