Copyright notice: This article is the blogger’s original article, shall not be reproduced without the permission of the blogger

Android Development from Scratch series

Source code: this issue is relatively simple, the source code is directly posted in the article

If you see any mistakes or have any good suggestions, please leave a comment

preface: We usually used MAKA or easy enterprise show these H5 template production tools, DO not know there is a small detail we have not noticed, is this music small control

When we click the control, it will rotate and play background music, and when we click it again, it will reset to its original state. Similar rotation effects are also very common in apps, such as music discs constantly rotating in some music playing interfaces

The effect is a little more complicated. The disc rotates or pauses at a certain rotation Angle as the music plays, and when it resumes from the pause to play, it rotates continuously from the current Angle. This is how to use itProperty animator ObjectAnimatorandRotateAnimationAchieve this effect separately

This article only focuses on the ideas and implementation steps, some knowledge principles used in it will not be very detailed. If there are unclear APIS or methods, you can search the corresponding information on the Internet, there must be a god to explain very clearly, I will not present the ugly. In the spirit of serious and responsible, I will post the relevant knowledge of the blog links (in fact, is lazy do not want to write so much ha ha), you can send their own. For the benefit of those who are reading this series of blogs for the first time, there may be some content that has been covered in the previous series of blogs

International convention, go up effect drawing first


Use ObjectAnimator implementation

It’s easiest to do this using a property animation, because the animation starts, pauses, ends, and replays are all wrapped up in the system (android 3.0 +). We just need to inherit ImageView and call ObjectAnimator. The code is relatively simple, so I’ll just post it here

public class MusicButton extends AppCompatImageView {
    private ObjectAnimator objectAnimator;

    public static final int STATE_PLAYING =1;// It is playing
    public static final int STATE_PAUSE =2;/ / pause
    public static final int STATE_STOP =3;/ / stop
    public int state;

    public MusicButton(Context context) {
        super(context);
        init();
    }

    public MusicButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MusicButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init(a){
        state = STATE_STOP;
        objectAnimator = ObjectAnimator.ofFloat(this."rotation".0f.360f);// Add the rotation animation. The rotation center is the default control midpoint
        objectAnimator.setDuration(3000);// Set the animation time
        objectAnimator.setInterpolator(new LinearInterpolator());// Animation time linear gradient
        objectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
        objectAnimator.setRepeatMode(ObjectAnimator.RESTART);
    }

    public void playMusic(a){
        if(state == STATE_STOP){
            objectAnimator.start();// Start animation
            state = STATE_PLAYING;
        }else if(state == STATE_PAUSE){
            objectAnimator.resume();// Start animation again
            state = STATE_PLAYING;
        }else if(state == STATE_PLAYING){
            objectAnimator.pause();// Animation pausesstate = STATE_PAUSE; }}public void stopMusic(a){
        objectAnimator.end();// End of animationstate = STATE_STOP; }}Copy the code

The effect is shown in figure


Use RotateAnimation implementation

RotateAnimation itself does not encapsulate the method of pause animation, so the implementation will be more complicated than ObjectAnimator. In the attitude of learning and research, it is necessary to create difficulties without difficulties. How can we use the “original” RotateAnimation to achieve the desired effect

Since RotateAnimation only has the start and end methods, when we hit the pause button, we need to record the Angle currently rotated, redraw the View and rotate the canvas as previously recorded. When playing again, since the canvas of the View has been rotated to the paused Angle, we just need to create a new animation to play from the current Angle. The code is as follows

public class MusicButton extends AppCompatImageView {
    public static final int STATE_PLAYING =1;// It is playing
    public static final int STATE_PAUSE =2;/ / pause
    public static final int STATE_STOP =3;/ / stop
    public int state;

    private float angle;// Records the angles affected by the interpolator values in RotateAnimation
    private float angle2;// It is mainly used to record the Angle of the pause, i.e. the initial rotation Angle of the View
    private int viewWidth;
    private int viewHeight;
    private MusicAnim musicAnim;

    public MusicButton(Context context) {
        super(context);
        init();
    }

    public MusicButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MusicButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init(a){
        state = STATE_STOP;
        angle = 0;
        angle2 = 0;
        viewWidth = 0;
        viewHeight = 0;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        viewWidth = getMeasuredWidth();
        viewHeight = getMeasuredHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.rotate(angle2,viewWidth/2,viewHeight/2);
        super.onDraw(canvas);
    }

    public class MusicAnim extends RotateAnimation{
        public MusicAnim(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
            super(fromDegrees, toDegrees, pivotX, pivotY);
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            super.applyTransformation(interpolatedTime, t);
            angle = interpolatedTime * 360; }}public void playMusic(a){
        if(state == STATE_PLAYING){
            angle2 = (angle2 + angle)%360;// Can be mod or not, depending on the actual requirements
            musicAnim.cancel();
            state = STATE_PAUSE;
            invalidate();
        }else {
            musicAnim = new MusicAnim(0.360,viewWidth/2,viewHeight/2);
            musicAnim.setDuration(3000);
            musicAnim.setInterpolator(new LinearInterpolator());// Animation time linear gradientmusicAnim.setRepeatCount(ObjectAnimator.INFINITE); startAnimation(musicAnim); state = STATE_PLAYING; }}public void stopMusic(a){
        angle2 = 0; clearAnimation(); state = STATE_STOP; invalidate(); }}Copy the code

MusicButton code is finished, the following button combined with music playback code posted, interested partners can have a look

mPlayer = MediaPlayer.create(this, r.Raw. name of music); mPlayer.setLooping(true);

btnMusic = (MusicButton) findViewById(R.id.btn_music);
btnMusic.setOnClickListener(new View.OnClickListener() {// Click Play or pause
	@Override
	public void onClick(View v) {
		btnMusic.playMusic();
		try {
			if(mPlayer ! =null) {
				if (mPlayer.isPlaying()) {
					mPlayer.pause();
				} else{ mPlayer.start(); }}}catch(Exception e) { e.printStackTrace(); }}}); btnMusic.setOnLongClickListener(new View.OnLongClickListener() {// Long press to stop
	@Override
	public boolean onLongClick(View v) {
		try {
			if(mPlayer ! =null) { mPlayer.stop(); mPlayer.prepare(); }}catch (Exception e) {
			e.printStackTrace();
		}
		btnMusic.stopMusic();
		return true;// Consume this long press event, no longer passed down}});Copy the code

This is the end of this tutorial. If you enjoy it, please give me a thumbs up. Your support is my biggest motivation