Android动画 播放暂停

作者 : 开心源码 本文共10065个字,预计阅读时间需要26分钟 发布时间: 2022-05-12 共140人阅读

目录

Android 开始暂停动画.png

效果

国际惯例,先放效果

动画开始暂停.gif

前言

之前写了java线程的暂停和继续,Android下载暂停,圆形下载进度条,相信大家看了上面的动画效果就知道我这一个系列是要做什么了,哈哈,没错就是一个简单的网络下载暂停,只是通过一部分一部分的分析,今天把动画给搞定了,过段时间就是可以成功的把这些整合起来,估计效果就是我们手机应用商城中的软件下载的效果,可以暂停,也是圆形进度条;拥有开始和暂停的动画;想想就非常不错;666666666

正文

自己设置View PlayPauseView
  1. 上面的动画就是两个矩形,变成三角形,我们只用设置左边矩形的四个点的坐标,那么右边的坐标,可以通过自己定义的两个矩形之间的宽度,算出相应的坐标,

  2. Path方法就是用画笔画出相应的动画效果,path.moveTo(),就是从起点画到后面的点,

  3. path.lineTo() 画直线,通过两个点确定一个直线,即可以成功的画出动画,

  4. path.close()这可不是关闭方法,而是把线段封闭掉,什么意思呢?我们花了四个点,但是只连接了三个线,那么就会把开始的点和最后的点连接起来,这样就形成了矩形。

public class PlayPauseView extends View {    private int mWidth; //View宽度    private int mHeight; //View高度    private Paint mPaint;    private Path mLeftPath; //暂停时左侧竖条Path    private Path mRightPath; //暂停时右侧竖条Path    private float mGapWidth; //两个暂停竖条中间的空隙,默认为两侧竖条的宽度    private float mProgress; //动画Progress    private Rect mRect;    private boolean isPlaying;    private float mRectWidth;  //圆内矩形宽度    private float mRectHeight; //圆内矩形高度    private float mRectLT;  //矩形左侧上侧坐标    private float mRadius;  //圆的半径    private int mBgColor = Color.WHITE;    private int mBtnColor = Color.BLACK;    private int mDirection = Direction.POSITIVE.value;    private float mPadding;    private int mAnimDuration = 200;//动画时间    public PlayPauseView(Context context) {        super(context);    }    public PlayPauseView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init(context, attrs);    }    public PlayPauseView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context, attrs);    }    private void init(Context context, AttributeSet attrs) {        mPaint = new Paint();        mPaint.setAntiAlias(true);        mLeftPath = new Path();        mRightPath = new Path();        mRect = new Rect();        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PlayPauseView);        mBgColor = ta.getColor(R.styleable.PlayPauseView_bg_color, Color.WHITE);        mBtnColor = ta.getColor(R.styleable.PlayPauseView_btn_color, Color.BLACK);        mGapWidth = ta.getDimensionPixelSize(R.styleable.PlayPauseView_gap_width, dp2px(context, 0));        mPadding = ta.getDimensionPixelSize(R.styleable.PlayPauseView_space_padding, dp2px(context, 0));        mDirection = ta.getInt(R.styleable.PlayPauseView_anim_direction, Direction.POSITIVE.value);        mAnimDuration = ta.getInt(R.styleable.PlayPauseView_anim_duration, 200);        ta.recycle();        setLayerType(View.LAYER_TYPE_SOFTWARE, null);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWidth = MeasureSpec.getSize(widthMeasureSpec);        mHeight = MeasureSpec.getSize(heightMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        if (widthMode == MeasureSpec.EXACTLY) {            mWidth = Math.min(mWidth, mHeight);        } else {            mWidth = dp2px(getContext(), 50);        }        if (heightMode == MeasureSpec.EXACTLY) {            mHeight = Math.min(mWidth, mHeight);        } else {            mHeight = dp2px(getContext(), 50);        }        mWidth = mHeight = Math.min(mWidth, mHeight);        setMeasuredDimension(mWidth, mHeight);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mWidth = mHeight = w;        initValue();    }    private void initValue() {        mRadius = mWidth / 2;              mPadding = getSpacePadding() == 0 ? mRadius / 3f : getSpacePadding();        if (getSpacePadding() > mRadius / Math.sqrt(2) || mPadding < 0) {            mPadding = mRadius / 3f; //默认值        }        float space = (float) (mRadius / Math.sqrt(2) - mPadding); //矩形宽高的一半        mRectLT = mRadius - space;        float rectRB = mRadius + space;        mRectWidth = 2 * space;        mRectHeight = 2 * space;        mGapWidth = getGapWidth() != 0 ? getGapWidth() : mRectWidth / 3;        mProgress = isPlaying ? 0 : 1;        mAnimDuration = getAnimDuration() < 0 ? 200 : getAnimDuration();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mLeftPath.rewind();        mRightPath.rewind();        mPaint.setColor(mBgColor);        canvas.drawCircle(mWidth / 2, mHeight / 2, mRadius, mPaint);        float distance = mGapWidth * (1 - mProgress);  //暂停时左右两边矩形距离        float barWidth = mRectWidth / 2 - distance / 2;     //一个矩形的宽度        float leftLeftTop = barWidth * mProgress;       //左边矩形左上角        float rightLeftTop = barWidth + distance;       //右边矩形左上角        float rightRightTop = 2 * barWidth + distance;  //右边矩形右上角        float rightRightBottom = rightRightTop - barWidth * mProgress; //右边矩形右下角        mPaint.setColor(mBtnColor);        mPaint.setStyle(Paint.Style.FILL);        if (mDirection == Direction.NEGATIVE.value) {            mLeftPath.moveTo(mRectLT, mRectLT);            mLeftPath.lineTo(leftLeftTop + mRectLT, mRectHeight + mRectLT);            mLeftPath.lineTo(barWidth + mRectLT, mRectHeight + mRectLT);            mLeftPath.lineTo(barWidth + mRectLT, mRectLT);            mLeftPath.close();            mRightPath.moveTo(rightLeftTop + mRectLT, mRectLT);            mRightPath.lineTo(rightLeftTop + mRectLT, mRectHeight + mRectLT);            mRightPath.lineTo(rightRightBottom + mRectLT, mRectHeight + mRectLT);            mRightPath.lineTo(rightRightTop + mRectLT, mRectLT);            mRightPath.close();        } else {            mLeftPath.moveTo(leftLeftTop + mRectLT, mRectLT);            mLeftPath.lineTo(mRectLT, mRectHeight + mRectLT);            mLeftPath.lineTo(barWidth + mRectLT, mRectHeight + mRectLT);            mLeftPath.lineTo(barWidth + mRectLT, mRectLT);            mLeftPath.close();            mRightPath.moveTo(rightLeftTop + mRectLT, mRectLT);            mRightPath.lineTo(rightLeftTop + mRectLT, mRectHeight + mRectLT);            mRightPath.lineTo(rightLeftTop + mRectLT + barWidth, mRectHeight + mRectLT);            mRightPath.lineTo(rightRightBottom + mRectLT, mRectLT);            mRightPath.close();        }        canvas.save();        canvas.translate(mRectHeight / 8f * mProgress, 0);        float progress = isPlaying ? (1 - mProgress) : mProgress;        int corner = mDirection == Direction.NEGATIVE.value ? -90 : 90;        float rotation = isPlaying ? corner * (1 + progress) : corner * progress;        canvas.rotate(rotation, mWidth / 2f, mHeight / 2f);        canvas.drawPath(mLeftPath, mPaint);        canvas.drawPath(mRightPath, mPaint);        canvas.restore();    }    public ValueAnimator getPlayPauseAnim() {        ValueAnimator valueAnimator = ValueAnimator.ofFloat(isPlaying ? 1 : 0, isPlaying ? 0 : 1);        valueAnimator.setDuration(mAnimDuration);        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mProgress = (float) animation.getAnimatedValue();                invalidate();            }        });        return valueAnimator;    }    public void play() {        if (getPlayPauseAnim() != null) {            getPlayPauseAnim().cancel();        }        setPlaying(true);        getPlayPauseAnim().start();    }    public void pause() {        if (getPlayPauseAnim() != null) {            getPlayPauseAnim().cancel();        }        setPlaying(false);        getPlayPauseAnim().start();    }    private PlayPauseListener mPlayPauseListener;    public void setPlayPauseListener(PlayPauseListener playPauseListener) {        mPlayPauseListener = playPauseListener;        setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                if (isPlaying()) {                    pause();                    if (null != mPlayPauseListener) {                        mPlayPauseListener.pause();                    }                } else {                    play();                    if (null != mPlayPauseListener) {                        mPlayPauseListener.play();                    }                }            }        });    }    public interface PlayPauseListener {        void play();        void pause();    }    public int dp2px(Context context, float dpVal) {        float density = context.getResources().getDisplayMetrics().density;        return (int) (density * dpVal + 0.5f);    }    /* ------------下方是参数------------- */    public boolean isPlaying() {        return isPlaying;    }    public void setPlaying(boolean playing) {        isPlaying = playing;    }    public void setGapWidth(float gapWidth) {        mGapWidth = gapWidth;    }    public float getGapWidth() {        return mGapWidth;    }    public int getBgColor() {        return mBgColor;    }    public int getBtnColor() {        return mBtnColor;    }    public int getDirection() {        return mDirection;    }    public void setBgColor(int bgColor) {        mBgColor = bgColor;    }    public void setBtnColor(int btnColor) {        mBtnColor = btnColor;    }    public void setDirection(Direction direction) {        mDirection = direction.value;    }    public float getSpacePadding() {        return mPadding;    }    public void setSpacePadding(float padding) {        mPadding = padding;    }    public int getAnimDuration() {        return mAnimDuration;    }    public void setAnimDuration(int animDuration) {        mAnimDuration = animDuration;    }    public enum Direction {        POSITIVE(1),//顺时针        NEGATIVE(2);//逆时针        int value;        Direction(int value) {            this.value = value;        }    }}
  mBgColor = ta.getColor(R.styleable.PlayPauseView_bg_color, Color.WHITE);        mBtnColor = ta.getColor(R.styleable.PlayPauseView_btn_color, Color.BLACK);        mGapWidth = ta.getDimensionPixelSize(R.styleable.PlayPauseView_gap_width, dp2px(context, 0));        mPadding = ta.getDimensionPixelSize(R.styleable.PlayPauseView_space_padding, dp2px(context, 0));        mDirection = ta.getInt(R.styleable.PlayPauseView_anim_direction, Direction.POSITIVE.value);        mAnimDuration = ta.getInt(R.styleable.PlayPauseView_anim_duration, 200);

大家可能不太清楚这些是什么,其实这个就是我们在xml中声名的属性,也就是自己设置View的属性;

自己设置xml attrs.xml
<resources>    <declare-styleable name="PlayPauseView">        <attr name="bg_color" format="color"/>        <attr name="btn_color" format="color"/>        <attr name="gap_width" format="dimension|reference"/>        <attr name="space_padding" format="dimension|reference"/>        <attr name="anim_duration" format="integer"/>        <attr name="anim_direction">            <enum name="positive" value="1"/>            <enum name="negative" value="2"/>        </attr>    </declare-styleable></resources>

大家看到上面的name,就是我们在自己设置View 中的属性方法;

通过相应的设置,大家即可以看出来了;

界面 activity_main.xml
<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.freedom.lauzy.playpauseview.MainActivity">    <com.freedom.lauzy.playpauseviewlib.PlayPauseView        android:id="@+id/play_pause_view1"        android:layout_width="80dp"        android:layout_height="80dp"        android:layout_gravity="center"        android:layout_marginTop="40dp"        app:anim_direction="positive"        app:anim_duration="300"        app:bg_color="#E0E0E0"        app:btn_color="#000000"/></LinearLayout>

看见上面的app:后下面跟的属性名称了吗?就是我们自己设置View 的那些属性,我们是在自己设置的时候通过get()``set()方法,设置属性的;

主方法 MainActivity()
package com.freedom.lauzy.playpauseview;import android.graphics.Color;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Toast;import com.freedom.lauzy.playpauseviewlib.PlayPauseView;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        final PlayPauseView playPauseView1 = (PlayPauseView) findViewById(R.id.play_pause_view1);        playPauseView1.setPlayPauseListener(new PlayPauseView.PlayPauseListener() {            @Override            public void play() {                Toast.makeText(MainActivity.this, "Play", Toast.LENGTH_SHORT).show();            }            @Override            public void pause() {                Toast.makeText(MainActivity.this, "Pause", Toast.LENGTH_SHORT).show();            }        });    }}

这个就还是蛮简单的,设置一下点击事件即可以了,我们自己设置的时候,自己设置了点击事件(可以看看上面的代码)。

总结

自己设置View时,要想一想我们自己设置需要什么功能,他有动画吗,需要什么样的参数,能设置的属性有需要多少,需要动画吗?需要什么要的动画,等等

  1. 首先就是两个矩形,先考虑假如画出两个矩形,先画出一个圆,配置该视图的宽高,就像画出个圆形,在圆形里面画出矩形,左边矩形的坐标,假如画,两个矩形的宽度设置出来,就知道相应的右边的坐标,这样子两个矩形就出来了
  2. 其次就是个三角形,也就是三个点的坐标,通过宽度换算成适合的大小,画出就可;
  3. 最后就是动画,设置动画时间,动画效果
  4. 最后就是可配置的参数和属性;
感谢

感谢大家!!! 加油!!! 努力!! 日更!!

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Android动画 播放暂停

发表回复