Android: как отобразить часы обновления в TextView

есть часы, которые я хочу отобразить в TextView.

Я бы подумал, что есть несколько хороших функций для этого, но я ничего не мог найти. В итоге я реализовал свой собственный способ, использующий обработчик. Однако я спрашиваю, есть ли лучший (более эффективный) способ отображения часов обновления в реальном времени?

private Runnable mUpdateClockTask = new Runnable() {
   public void run() {
       setTime();
       mClockHandler.postDelayed(this, 1000);
   }
};

Это мой обработчик, который запускается каждую секунду, а затем моя установленная функция времени и даты ниже

TextView mClockView;

public void setTime() {
    Calendar cal = Calendar.getInstance();
    int minutes = cal.get(Calendar.MINUTE);

    if (DateFormat.is24HourFormat(this)) {
        int hours = cal.get(Calendar.HOUR_OF_DAY);
        mClockView.setText((hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes));
    }
    else {
        int hours = cal.get(Calendar.HOUR);
        mClockView.setText(hours + ":" + (minutes < 10 ? "0" + minutes : minutes) + " " + new DateFormatSymbols().getAmPmStrings()[cal.get(Calendar.AM_PM)]);
    }
}

Ваше здоровье


person Richard Rout    schedule 09.09.2011    source источник


Ответы (6)


Помните: преждевременная оптимизация — корень всех зол. Так что оптимизируйте только тогда, когда вы уверены (=измерили), что ваша реализация медленная/неэффективная.

Тем не менее, более эффективным методом, вероятно, было бы записывать время начала через System.currentTimeMillis(), а затем периодически проверять его и вычислять разницу в минутах.

person Peter Knego    schedule 09.09.2011
comment
Хм, это хорошая идея. Кроме того, как только я узнаю текущие секунды до следующего обновления, мне нужно вызвать мой обработчик только через столько секунд. - person Richard Rout; 10.09.2011
comment
В целом вы правы в том, что преждевременная оптимизация — это плохо, но реализация в ОП действительно очень плохая, запускает новый поток каждую секунду, а предлагаемая вами оптимизация полностью игнорирует это и предлагает оптимизацию, которая, вероятно, действительно не будет иметь заметного значения. . - person wvdz; 15.02.2017

Обновление системных часов не похоже на обновление хронометра. Мы говорим об изменении времени в минутах (минуты системных часов и 00 секунд).

Использование таймера не является правильным способом сделать это. Это не только излишество, но вы должны прибегнуть к некоторым уловкам, чтобы сделать это правильно.

Правильный способ сделать это (т. е. обновить TextView, показывающий время в формате ЧЧ: мм) — использовать BroadcastReceiver следующим образом:

BroadcastReceiver _broadcastReceiver;
private final SimpleDateFormat _sdfWatchTime = new SimpleDateFormat("HH:mm");
private TextView _tvTime;

@Override
public void onStart() {
    super.onStart();
    _broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context ctx, Intent intent) {
                if (intent.getAction().compareTo(Intent.ACTION_TIME_TICK) == 0)
                    _tvTime.setText(_sdfWatchTime.format(new Date()));
            }
        };

    registerReceiver(_broadcastReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
}

@Override
public void onStop() {
    super.onStop();
    if (_broadcastReceiver != null)
        unregisterReceiver(_broadcastReceiver);
}

Система будет отправлять это широковещательное событие точно в начале каждой минуты на основе системных часов. Однако не забудьте заранее инициализировать TextView (в соответствии с текущим системным временем), поскольку вполне вероятно, что вы откроете свой пользовательский интерфейс в середине минуты, а TextView не будет обновлен до следующей минуты.

person Alex    schedule 24.01.2013
comment
Это сработало для меня. Спасибо! Жаль, что вы не можете иметь такую ​​​​же трансляцию для второго, но я понимаю основную причину. - person Mathieu; 16.02.2013
comment
да. Я предполагаю, что если вам нужно показать секунды, вы можете использовать повторяющийся таймер или что-то подобное. Пока он повторно синхронизируется каждую минуту, чтобы убедиться, что он остается правильным в долгосрочной перспективе, все должно быть в порядке. Но использовать таймер для всего этого просто неправильно. Это тонкий момент, который большинство людей не замечают, поскольку он кажется почти правильным, но это не так (за исключением случаев, когда вы выполняете дополнительные действия, которые в целом тяжелее, чем использование трансляции ACTION_TIME_TICK). - person Alex; 19.02.2013
comment
@Alex Алекс, не могли бы вы сообщить мне, что означает if (intent.getAction().compareTo(Intent.ACTION_TIME_TICK) == 0)? - person krtkush; 06.06.2014
comment
Он проверяет, что полученное событие является предполагаемым. В данном случае это бесполезно, так как получатель может получить только это событие (об этом сообщает IntentFilter при регистрации). Тем не менее, это хорошая привычка и только здесь для полноты картины. - person Alex; 05.08.2014
comment
@Alex Очень хорошее объяснение с фантастическим примером. Большое спасибо за пример и объяснение. Вы экономите мне много времени. - person Smeet; 16.12.2015

Ознакомьтесь с хронометром и DigitalClock, которые являются расширениями класса TextView. Они должны автоматически делать то, что вы ищете. Если вам нужна дополнительная функциональность, просто взгляните на исходный код для них и внесите необходимые изменения.

ОБНОВИТЬ:

Поскольку цифровые часы не рекомендуются в API 17, я бы рекомендовал вместо них использовать текстовые часы .

person Joe Krill    schedule 09.09.2011
comment
DigitalClock не дает возможности указать формат. Который не делает то, что мне нужно. Также я попробовал Хронометр, но он, похоже, не хотел хорошо играть. Спасибо хоть! - person Richard Rout; 10.09.2011
comment
Я понимаю, что существуют ограничения, поэтому я предложил использовать исходный код и внесение необходимых изменений. У меня также были ограничения при использовании хронометра, и я смог просто скопировать код и внести необходимые изменения. - person Joe Krill; 12.09.2011
comment
DigitalClock кажется устаревшим. Вместо этого используйте TextClock (исходный код). - person Levente Dobson; 30.04.2014

Я рекомендую TextClock (из API 17), также не используйте DigitalClock (Устарело из API 17), так как это вызовет MEMORY LEAK и приведет к исключению Out of Memory Exception. Добавьте следующий фрагмент кода в соответствующий файл layout.xml.

 <TextClock
   android:id="@+id/textClock1"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:gravity="center_horizontal"
   android:textColor="#17d409" />

Это поможет, также обратите внимание, что вы можете отформатировать время отображения по мере необходимости, например, для получения 12-часового формата с секундами вы можете использовать android:format12Hour=hh:mm:ss a.

person Sreerag S Kumar    schedule 10.03.2017
comment
Пожалуйста, уточните свои ответы с помощью примера кода. Иначе это будет бесполезно для читателей. - person Muhammad Haseeb Khan; 10.03.2017
comment
@MuhammadHaseebKhan короткий поиск в Google для Android TextClock приведет любого к странице примера, которая в основном говорит: просто поместите представление TextClock в ваш файл layout.xml. Я проголосовал за этот ответ. - person Royz; 16.04.2018

Вы можете использовать виджет TextClock, предоставленный Android

<TextClock
    android:id="@+id/textClock"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:format12Hour="hh:mm:ss a"
    android:gravity="center_horizontal"
    android:textColor="#d41709"
    android:textSize="20sp"
    android:textStyle="bold" />

требуется минимальный уровень API 17

https://developer.android.com/reference/android/widget/TextClock

если вы хотите текущее время в другом текстовом представлении

вы можете использовать приведенный ниже фрагмент кода

 tClock = (TextClock) findViewById(R.id.textClock1);
        tView = (TextView) findViewById(R.id.textview1);
        btn = (Button)findViewById(R.id.btnGet);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tView.setText("Time: "+tClock.getText());
            }
        });
    }
person MarGin    schedule 29.01.2019

Виджет DigitalClock доступен в Android API 1 или используйте виджет TextClock в API 17.

сначала создайте макет для часов, подобный этому:

<LinearLayout 
         android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:id="@+id/clocktext"
        android:textStyle="bold"
        android:textColor="#ffffff"
        android:layout_marginTop="30dp"
        android:textSize="50sp"
        android:text="2:46"/>
    <DigitalClock android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:id="@+id/clock"
        android:textStyle="bold"
        android:textSize="50sp"
        android:visibility="gone"
        android:textColor="#ffffff"
        />  
    </LinearLayout>       

в Activity добавьте прослушиватель textchage в DigitalClock, это подкласс textview, поэтому мы можем добавить textchangedkistener, чтобы получить обновленное время и установить время для вашего textview, как вы хотите

chagre = (TextView) mTopView.findViewById(R.id.clocktext);// TextView to display Time
    clock = (DigitalClock) mTopView.findViewById(R.id.clock);// DigitalClock With visibility=gone

    clock.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {}

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {}
        @Override
        public void afterTextChanged(Editable s) {

            chagre.setText(s.toString());//will be called when system clock updataes

        }
    });
person Jitty Aandyan    schedule 04.06.2014
comment
DigitalClock устарел, начиная с API 17. - person Monica Aspiras Labbao; 03.10.2018