仿小咖秀倒计时

前言:

2017年的短视频行业,盛况空前,风头无二,市场中不断涌现出各类短视频平台,已多达上百家,小咖秀可以说是短视频中的“元老”,功能齐全,拍摄体验也很棒。我个人觉得小咖秀的拍摄倒计时设计是很人性化的,支持选择时长,有三秒、五秒、十秒等,玩起来还是很舒服的。作为移动端开发者,看到有意思的功能,第一个想到的当然是我能不能也做成这样!所以我简单写了个demo,仅仅模仿了一下倒计时效果。

github:https://github.com/kb18519142009/CountDownDemo

效果图:
这里写图片描述

正文:

一、思路以及准备

1、说到倒计时,我想到了CountDownTimer这个类,它实现了倒计时的基本功能,先看看它的构造方法:

public CountDownTimer(long millisInFuture, long countDownInterval) {
         ......
    }

第一个参数millisInFuture表示倒计时的总时长,第二个参数countDownInterval表示倒计时的间隔时间,比如CountDownTimer(3000, 1000) ,表示倒计时总时长为3s,间隔为1s。

2、接下来就是动画,我选择了缩放动画ScaleAnimation,它有四个构造方法,我用了参数最多的一个:

public ScaleAnimation(float fromX, float toX, float fromY, float toY,
            int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
        ......
    }

fromX:X轴开始动画缩放的比例
toX:X轴结束时动画缩放的比例
fromY:Y轴开始动画缩放的比例
toY:Y轴结束动画缩放的比例
pivotXType:指定pivotXValue的相对位置,取值:Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT
pivotXValue:固定点X轴坐标,取值1%~100%
pivotYType:取值:Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT
pivotYValue:固定点Y轴坐标,取值1%~100%

除了构造函数的这些参数,我们还可以给动画设置时长,重复次数,重复模式等等。

二、具体实现

1、布局文件
在这里倒计时可以是单纯的数字,用TextView实现,也可以直接用图片搞定。
TextView的方式:

<TextView
        android:id="@+id/tv_count_timer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:background="@drawable/bg_video_duration"
        android:paddingBottom="5dp"
        android:paddingEnd="25dp"
        android:paddingStart="25dp"
        android:paddingTop="5dp"
        android:textColor="#fff"
        android:textSize="80sp"/>

其中我们给了TextView一个background,来实现透明阴影的效果,在drawable下创建shape如下:

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="15dip" />
    <solid android:color="#7F000000"/>
</shape>

2、创建倒计时类RecordCountTimer
这个类继承至CountDownTimer,在构造函数中拿到要执行动画的view并且创建了动画,实现了onTick和onFinish方法,onTick在每个间隔时间调用,onFinish在倒计时结束时调用,然后在onTic中执行动画即可,代码比较简单,我就直接贴上来啦:

public class RecordCountTimer extends CountDownTimer {
    private static final int TIME_COUNT = 3100; //倒计时总时间为3.1s,时间防止从2s开始显示(以倒计时3s为例子)
    private static final int TIME_INTERVAL = 1000; //倒计时间隔为1s
    private View view; //要设置动画的view

    private boolean mIsAnimStart;
    private AlphaAnimation alphaAnimation; //渐变动画
    private ScaleAnimation scaleAnimation; //缩放动画

    private OnCountTimerListener mOnCountTimerListener;

    public void setOnCountTimerListener(OnCountTimerListener onFinishListener) {
        this.mOnCountTimerListener = onFinishListener;
    }

    //倒计时开始和结束的监听
    public interface OnCountTimerListener {
        void onStart();

        void onFinish();
    }

    /**
     * @param view 要执行动画的view
     */
    public RecordCountTimer(View view) {
        this(TIME_COUNT, TIME_INTERVAL, view);
    }

    /**
     * 倒计时的view  可以是TextView、Button或者ImageView
     *
     * @param millisInFuture    表示从计时开始到结束的毫秒数
     * @param countDownInterval 表示onTick(long)回调的间隔时间
     * @param view              要执行动画的view
     */
    public RecordCountTimer(long millisInFuture, long countDownInterval, View view) {
        super(millisInFuture, countDownInterval);
        this.view = view;

        // 设置透明度渐变动画
        alphaAnimation = new AlphaAnimation(0, 1);
        // 设置动画持续时间
        alphaAnimation.setDuration(500);

        // 设置缩放渐变动画
        scaleAnimation = new ScaleAnimation(0.1f, 1f, 0.1f, 1f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        scaleAnimation.setDuration(500); //设置动画时长
        scaleAnimation.setRepeatCount(1); //设置重复次数
        scaleAnimation.setRepeatMode(Animation.REVERSE); //重复模式,reverse表示反向进行,在这里先放大,后缩小
        scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (mOnCountTimerListener != null) {
                    mOnCountTimerListener.onFinish();
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }


    @Override
    public void onTick(long millisUntilFinished) {
        if (!mIsAnimStart) {
            mIsAnimStart = true;
            if (mOnCountTimerListener != null) {
                mOnCountTimerListener.onStart();
            }
        }

        //每隔一秒修改一次UI
        if (view instanceof ImageView) { // 如果是图片,在此判断,每隔一秒,改变一次图片
            if (millisUntilFinished / 1000 == 1) {
                ((ImageView) view).setImageResource(R.drawable.img_show_count_down_1);
            } else if (millisUntilFinished / 1000 == 2) {
                ((ImageView) view).setImageResource(R.drawable.img_show_count_down_2);
            } else if (millisUntilFinished / 1000 == 3) {
                ((ImageView) view).setImageResource(R.drawable.img_show_count_down_3);
            }
        } else if (view instanceof TextView) {
            ((TextView) view).setText(String.valueOf(millisUntilFinished / 1000));
        }

        view.setVisibility(View.VISIBLE);
        view.setEnabled(false);

        view.startAnimation(alphaAnimation);
        view.startAnimation(scaleAnimation);
    }

    @Override
    public void onFinish() {

    }
}

3、再贴上MainActivity的代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

//    private TextView mCountTimerView; // 数字倒计时
        private ImageView mCountTimerView; // 图片倒计时
    private Button mBtnCountDown; //开始按钮

    private RecordCountTimer mCountTimer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        mCountTimerView = findViewById(R.id.tv_count_timer);
        mCountTimerView = findViewById(R.id.iv_count_timer);
        mBtnCountDown = findViewById(R.id.btn_count_down);
        mBtnCountDown.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v == mBtnCountDown) {
            mCountTimer = new RecordCountTimer(mCountTimerView);
            mCountTimer.setOnCountTimerListener(new RecordCountTimer.OnCountTimerListener() {
                @Override
                public void onStart() {
                    //倒计时开始
                    mBtnCountDown.setVisibility(View.GONE);
                }

                @Override
                public void onFinish() {
                    //倒计时结束
                    mCountTimerView.setVisibility(View.GONE);
                    mBtnCountDown.setVisibility(View.VISIBLE);
                }
            });
            mCountTimer.start();
        }
    }
}

这里我加了一个按钮,点击按钮倒计时动画开始,在开始回调onStart()中隐藏按钮;动画结束,在结束回调中隐藏倒计时view,显示按钮。
看看布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.example.countdowndemo.MainActivity">

    <ImageView
        android:id="@+id/iv_count_timer"
        android:layout_width="60dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        android:visibility="gone" />
    <TextView
        android:id="@+id/tv_count_timer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:background="@drawable/bg_video_duration"
        android:paddingBottom="5dp"
        android:paddingEnd="25dp"
        android:paddingStart="25dp"
        android:paddingTop="5dp"
        android:textColor="#fff"
        android:textSize="80sp"
        android:visibility="gone" />

    <Button
        android:id="@+id/btn_count_down"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="3S倒计时开始"/>

</RelativeLayout>

OK!搞定啦!很简单的小Demo,有想看源码的请移步github:
https://github.com/kb18519142009/CountDownDemo
个人水平有限,大家有建议请尽管提,一起学习一起进步!谢谢!

猜你喜欢

转载自blog.csdn.net/k_bb_666/article/details/79416182