You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发:获取NumberPicker值传入CountDownTimer实现启停倒计时功能

问题原因分析
  • 空指针隐患+时长无法更新:你把t1、t2定义为全局final变量,类初始化的时候np1、np2还没绑定布局,仍是null,调用getValue()会直接触发空指针崩溃。同时final修饰后值不可修改,后续用户调整NumberPicker的数值,倒计时时长也不会同步更新。
  • 时间单位错误:t2的计算只乘了60,得到的是秒值,而CountDownTimer要求传入毫秒单位,需要额外乘1000,否则实际时长只有预期的千分之一。
  • 倒计时初始化时机错误:你在onCreate里就初始化了CountDownTimer,用的是初始固定值,后续用户调整选择器数值后,倒计时时长还是初始值,不会同步更新。
  • 重复启动冲突:如果当前倒计时已经在运行,再次点击启动按钮会触发多个倒计时同时运行,导致显示混乱。
修复方案

调整逻辑,每次点击启动按钮的时候,再实时获取当前NumberPicker的选中值,动态创建CountDownTimer即可,修复后的完整代码如下:

public class TimeManager extends AppCompatActivity {
    private NumberPicker np1 = null;
    private NumberPicker np2 = null;
    private Button bt1 = null;
    private Button bt2 = null;
    private Button bt3 = null;
    private TextView tv = null;
    private CountDownTimer cdt;


    @RequiresApi(api = Build.VERSION_CODES.Q)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_time_manager);

        np1 = findViewById(R.id.numPicker);
        np2 = findViewById(R.id.numPicker2);
        bt1 = findViewById(R.id.button2);
        bt2 = findViewById(R.id.button4);
        bt3 = findViewById(R.id.button5);
        tv = findViewById(R.id.textView4);

        bt1.setOnClickListener(btlis1);
        bt2.setOnClickListener(btlis2);
        bt3.setOnClickListener(btlis3);

        np1.setMinValue(0); //設定最小值
        np1.setMaxValue(23); //設定最大值
        np1.setValue(1); //設定現值
        np1.setWrapSelectorWheel(true);
        np1.setTextSize(60f);

        np2.setMinValue(0); //設定最小值
        np2.setMaxValue(59); //設定最大值
        np2.setValue(1); //設定現值
        np2.setWrapSelectorWheel(true);
        np2.setTextSize(60f);
    }


    View.OnClickListener btlis1 = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent it = new Intent(TimeManager.this, Home.class);
            startActivity(it);
        }
    };

    View.OnClickListener btlis2 = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 每次启动前先取消之前的倒计时,避免冲突
            if (cdt != null) {
                cdt.cancel();
            }
            // 实时获取当前选中的时长,转成毫秒
            long totalTime = np1.getValue() * 3600 * 1000L + np2.getValue() * 60 * 1000L;
            // 动态创建倒计时
            cdt = new CountDownTimer(totalTime, 1000) {
                @Override
                public void onTick(long millisUntilFinished) {
                    long t3 = millisUntilFinished / 1000;
                    tv.setEnabled(false);
                    tv.setText(t3 + "秒");
                }

                @Override
                public void onFinish() {
                    tv.setEnabled(true);
                    tv.setText("重新发送");
                }
            };
            cdt.start();
        }
    };

    View.OnClickListener btlis3 = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (cdt != null) {
                cdt.cancel();
                // 取消后恢复文字状态,可根据需求调整
                tv.setEnabled(true);
                tv.setText("已取消");
            }
        }
    };
}
补充说明
  • 删掉了无用的NumberPicker监听代码,不需要实时监听数值变化,启动时取一次当前值就足够
  • 新增了非空判断,避免cdt为空的时候调用cancel/start触发空指针
  • 修复了时间单位的计算错误,确保总时长符合预期

内容的提问来源于stack exchange,提问作者Su Mi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:54:02