java - 在 Android 操作栏中创建倒数计时器

标签 java android timer android-actionbar

我在创建可从操作栏查看的倒数计时器时遇到问题。现在这是我的 menu_main.xml 和我的 MainActivity.java 代码的一部分:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    undoValuesA.add(scoreTeamA);
    undoValuesB.add(scoreTeamB);
    if (savedInstanceState != null) {
        scoreTeamA = savedInstanceState.getInt(SCORE_TEAM_A_KEY);
        scoreTeamB = savedInstanceState.getInt(SCORE_TEAM_B_KEY);
        undoValuesA = savedInstanceState.getIntegerArrayList(UNDO_A_KEY);
        undoValuesB = savedInstanceState.getIntegerArrayList(UNDO_B_KEY);
    }
    displayForTeamA(scoreTeamA);
    displayForTeamB(scoreTeamB);

    swish = MediaPlayer.create(this, R.raw.swish);

    textViewTime = (TextView) findViewById(R.id.timer);
    textViewTime.setText("3:00");



}



<menu 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"
tools:context=".MainActivity">
<item
    android:title = "0:00"
    android:id = "@+id/timer"
    app:showAsAction = "always"

    />
<item android:id="@+id/action_plus"
    android:title="Plus"
    android:icon="@drawable/ic_action_plus"
    android:orderInCategory="100"
    app:showAsAction="always"/>

<item android:id="@+id/action_minus"
    android:title="minus"
    android:icon="@drawable/ic_action_minus"
    android:orderInCategory="100"
    app:showAsAction="always"/>

我的应用程序崩溃是因为操作栏中的计时器不是 TextView ,而只是一个项目。所以,当我尝试使用 textViewTime.setText("3:00");它在启动时崩溃。 我将如何实现?

最佳答案

第 1 步:将“倒数计时器”实现为自定义 View 类,例如这个 ReverseChronometer 实现:

/***
  Copyright (c) 2013 CommonsWare, LLC
  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain a copy
  of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  From _The Busy Coder's Guide to Android Development_
    http://commonsware.com/Android
 */

package com.commonsware.android.preso.slides;

import android.content.Context;
import android.graphics.Color;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.widget.TextView;

public class ReverseChronometer extends TextView implements Runnable {
  long startTime=0L;
  long overallDuration=0L;
  long warningDuration=0L;
  boolean isRunning=false;

  public ReverseChronometer(Context context) {
    super(context);

    reset();
  }

  public ReverseChronometer(Context context, AttributeSet attrs) {
    super(context, attrs);

    reset();
  }

  @Override
  public void run() {
    isRunning=true;

    long elapsedSeconds=
        (SystemClock.elapsedRealtime() - startTime) / 1000;

    if (elapsedSeconds < overallDuration) {
      long remainingSeconds=overallDuration - elapsedSeconds;
      long minutes=remainingSeconds / 60;
      long seconds=remainingSeconds - (60 * minutes);

      setText(String.format("%d:%02d", minutes, seconds));

      if (warningDuration > 0 && remainingSeconds < warningDuration) {
        setTextColor(0xFFFF6600); // orange
      }
      else {
        setTextColor(Color.WHITE);
      }

      postDelayed(this, 1000);
    }
    else {
      setText("0:00");
      setTextColor(Color.RED);
      isRunning=false;
    }
  }

  public void reset() {
    startTime=SystemClock.elapsedRealtime();
    setText("--:--");
    setTextColor(Color.WHITE);
  }

  public void stop() {
    removeCallbacks(this);
    isRunning=false;
  }

  public boolean isRunning() {
    return(isRunning);
  }

  public void setOverallDuration(long overallDuration) {
    this.overallDuration=overallDuration;
  }

  public void setWarningDuration(long warningDuration) {
    this.warningDuration=warningDuration;
  }
}

第 2 步:使用 android:actionViewClass(或者,在您的情况下,app:actionViewClass)指向菜单资源中第 1 步中的类,例如 native 操作栏:

<item
    android:id="@+id/countdown"
    android:actionViewClass="com.commonsware.android.preso.slides.ReverseChronometer"
    android:showAsAction="always"
    android:title="This Should Not Be Needed">
</item>

第 3 步:检索该操作项并从您的 Java 代码对其进行配置,例如 native 操作栏:

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_actions, menu);

    ReverseChronometer rc=(ReverseChronometer)menu
                                                .findItem(R.id.countdown)
                                                .getActionView();

    rc.setOverallDuration(40*60);
    rc.setWarningDuration(5*60);
    rc.setOnClickListener(this);
    rc.setOnLongClickListener(this);
    rc.setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
    rc.setTextColor(Color.WHITE);

    return(super.onCreateOptionsMenu(menu));
  }

您需要对步骤 #2 和步骤 #3 进行适当的调整,因为您正在使用 appcompat-v7 操作栏向后移植。

关于java - 在 Android 操作栏中创建倒数计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31120802/

相关文章:

java - BeanPropertySqlParameterSource 和 double

java - 在android中为移动对象制作矩形

java - Android HttpUrlConnection 传递 header 参数

android - 无法从数据库中获取数据

c - 下面的c程序有什么错误?

java - 定时器任务中的run方法执行了两次

java - Spring MVC @ResponseBody 返回一个列表

java - Android Emulator 插件在 Jenkins 中不起作用

Android:为什么 android.permission.ACCESS_WIFI_STATE 会自动添加到我签名的 apk 版本中?

c# - 如何在 C# 中每隔几秒调用一个特定的方法?