Android怎么自定义View实现计时文字

其他教程   发布日期:2025年04月19日   浏览次数:147

这篇文章主要介绍了Android怎么自定义View实现计时文字的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android怎么自定义View实现计时文字文章都会有所收获,下面我们一起来看看吧。

一、XML样式

首先来确定XML中的属性样式,在attrs.xml中增加如下代码:

  1. <!--计时文字-->
  2. <declare-styleable name="TimingTextView">
  3. <!--倒计时-->
  4. <attr name="countdown" format="boolean" />
  5. <!--时间最大值-->
  6. <attr name="max" format="integer" />
  7. <!--时间单位,时:h,分:m,秒:s-->
  8. <attr name="unit">
  9. <enum name="h" value="1" />
  10. <enum name="m" value="2" />
  11. <enum name="s" value="3" />
  12. </attr>
  13. </declare-styleable>

这里的计时文字目前有3个属性,第一个boolean用来确定是计时还是倒计时,第二个是最大时间,第三个是时间单位:时分秒。

二、构造方法

之前我说自定义View有三种方式,一种是继承View,一种是继承现有的View,还有一种是继承ViewGroup,那么今天的这个计时文字,我们就可以继承现有的View,这样做的目的就是可以让我们减少一定的工作量,专注于功能上,下面我们在

  1. com.llw.easyview
包下新建一个
  1. TimingTextView
类,里面的代码如下所示:
  1. public class TimingTextView extends MaterialTextView {
  2. /**
  3. * 时间单位
  4. */
  5. private int mUnit;
  6. /**
  7. * 计时最大值
  8. */
  9. private int mMax;
  10. /**
  11. * 是否倒计时
  12. */
  13. private boolean mCountDown;
  14. private int mTotal;
  15. /**
  16. * 是否计时中
  17. */
  18. private boolean mTiming;
  19. public TimingTextView(Context context) {
  20. this(context, null);
  21. }
  22. public TimingTextView(Context context, @Nullable AttributeSet attrs) {
  23. this(context, attrs, 0);
  24. }
  25. public TimingTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  26. super(context, attrs, defStyleAttr);
  27. @SuppressLint("CustomViewStyleable")
  28. TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TimingTextView);
  29. mCountDown = typedArray.getBoolean(R.styleable.TimingTextView_countdown, false);
  30. mMax = typedArray.getInteger(R.styleable.TimingTextView_max, 60);
  31. mUnit = typedArray.getInt(R.styleable.TimingTextView_unit, 3);
  32. typedArray.recycle();
  33. }
  34. }

因为有计时的缘故,所以我们需要一个计时监听,主要用于结束的时候进行调用,可以在

  1. com.llw.easyview
下新建一个
  1. TimingListener
接口,代码如下:
  1. public interface TimingListener {
  2. void onEnd();
  3. }

三、API方法

下面在TimingTextView中新增一些API方法和变量,首先增加变量:

  1. private TimingListener listener;
  2. private CountDownTimer countDownTimer;

然后增加API方法:

  1. /**
  2. * 设置时间单位
  3. *
  4. * @param unit 1,2,3
  5. */
  6. public void setUnit(int unit) {
  7. if (unit <= 0 || unit > 3) {
  8. throw new IllegalArgumentException("unit value can only be between 1 and 3");
  9. }
  10. mUnit = unit;
  11. }
  12. /**
  13. * 设置最大时间值
  14. *
  15. * @param max 最大值
  16. */
  17. public void setMax(int max) {
  18. mMax = max;
  19. }
  20. /**
  21. * 设置是否为倒计时
  22. *
  23. * @param isCountDown true or false
  24. */
  25. public void setCountDown(boolean isCountDown) {
  26. mCountDown = isCountDown;
  27. }
  28. public void setListener(TimingListener listener) {
  29. this.listener = listener;
  30. }
  31. public boolean isTiming() {
  32. return mTiming;
  33. }
  34. /**
  35. * 开始
  36. */
  37. public void start() {
  38. switch (mUnit) {
  39. case 1:
  40. mTotal = mMax * 60 * 60 * 1000;
  41. break;
  42. case 2:
  43. mTotal = mMax * 60 * 1000;
  44. break;
  45. case 3:
  46. mTotal = mMax * 1000;
  47. break;
  48. }
  49. if (countDownTimer == null) {
  50. countDownTimer = new CountDownTimer(mTotal, 1000) {
  51. @Override
  52. public void onTick(long millisUntilFinished) {
  53. int time = 0;
  54. if (mCountDown) {
  55. time = (int) (millisUntilFinished / 1000);
  56. setText(String.valueOf(time));
  57. } else {
  58. time = (int) (mTotal / 1000 - millisUntilFinished / 1000);
  59. }
  60. setText(String.valueOf(time));
  61. }
  62. @Override
  63. public void onFinish() {
  64. //倒计时结束
  65. end();
  66. }
  67. };
  68. mTiming = true;
  69. countDownTimer.start();
  70. }
  71. }
  72. /**
  73. * 计时结束
  74. */
  75. public void end() {
  76. mTotal = 0;
  77. mTiming = false;
  78. countDownTimer.cancel();
  79. countDownTimer = null;
  80. if (listener != null) {
  81. listener.onEnd();
  82. }
  83. }

代码还是很简单的,你敢信,这个自定义View就写完了,不过可能存在一些问题,我将自定义View的代码都放到了一个library下面里,然后将这个library进行构建成aar,然后上传到

  1. mavenCentral()
中。

四、使用

&emsp;&emsp;然后我们修改一下activity_main.xml,代码如下所示:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:gravity="center"
  8. android:orientation="vertical"
  9. android:padding="16dp"
  10. tools:context=".MainActivity">
  11. <com.easy.view.MacAddressEditText
  12. android:id="@+id/mac_et"
  13. android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"
  15. app:boxBackgroundColor="@color/white"
  16. app:boxStrokeColor="@color/black"
  17. app:boxStrokeWidth="2dp"
  18. app:boxWidth="48dp"
  19. app:separator=":"
  20. app:textColor="@color/black"
  21. app:textSize="16sp" />
  22. <Button
  23. android:id="@+id/btn_mac"
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:layout_marginTop="30dp"
  27. android:text="获取地址" />
  28. <com.easy.view.CircularProgressBar
  29. android:id="@+id/cpb_test"
  30. android:layout_width="wrap_content"
  31. android:layout_height="wrap_content"
  32. android:layout_marginTop="30dp"
  33. app:maxProgress="100"
  34. app:progress="10"
  35. app:progressbarBackgroundColor="@color/purple_500"
  36. app:progressbarColor="@color/purple_200"
  37. app:radius="80dp"
  38. app:strokeWidth="16dp"
  39. app:text="10%"
  40. app:textColor="@color/teal_200"
  41. app:textSize="28sp" />
  42. <Button
  43. android:id="@+id/btn_set_progress"
  44. android:layout_width="wrap_content"
  45. android:layout_height="wrap_content"
  46. android:layout_marginTop="30dp"
  47. android:text="随机设置进度" />
  48. <com.easy.view.TimingTextView
  49. android:id="@+id/tv_timing"
  50. android:layout_width="wrap_content"
  51. android:layout_height="wrap_content"
  52. android:layout_marginTop="30dp"
  53. android:text="计时文字"
  54. android:textColor="@color/black"
  55. android:textSize="32sp"
  56. app:countdown="false"
  57. app:max="60"
  58. app:unit="s" />
  59. <LinearLayout
  60. android:layout_width="wrap_content"
  61. android:layout_height="wrap_content"
  62. android:layout_marginTop="12dp"
  63. android:gravity="center"
  64. android:orientation="vertical">
  65. <CheckBox
  66. android:id="@+id/cb_flag"
  67. android:layout_width="wrap_content"
  68. android:layout_height="wrap_content"
  69. android:text="计时" />
  70. <Button
  71. android:id="@+id/btn_start"
  72. android:layout_width="wrap_content"
  73. android:layout_height="wrap_content"
  74. android:text="开始" />
  75. </LinearLayout>
  76. </LinearLayout>

下面我们回到MainActivity中,在

  1. onCreate()
方法中添加如下代码:
  1. //计时文本操作
  2. TimingTextView tvTiming = findViewById(R.id.tv_timing);
  3. CheckBox cbFlag = findViewById(R.id.cb_flag);
  4. Button btnStart = findViewById(R.id.btn_start);
  5. tvTiming.setListener(new TimingListener() {
  6. @Override
  7. public void onEnd() {
  8. tvTiming.setText("计时文字");
  9. btnStart.setText("开始");
  10. }
  11. });
  12. cbFlag.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  13. @Override
  14. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  15. cbFlag.setText(isChecked ? "倒计时" : "计时");
  16. }
  17. });
  18. //计时按钮点击
  19. btnStart.setOnClickListener(v -> {
  20. if (tvTiming.isTiming()) {
  21. //停止计时
  22. tvTiming.end();
  23. btnStart.setText("开始");
  24. } else {
  25. tvTiming.setMax(6);
  26. tvTiming.setCountDown(cbFlag.isChecked());
  27. tvTiming.setUnit(3);//单位 秒
  28. //开始计时
  29. tvTiming.start();
  30. btnStart.setText("停止");
  31. }
  32. });

以上就是Android怎么自定义View实现计时文字的详细内容,更多关于Android怎么自定义View实现计时文字的资料请关注九品源码其它相关文章!