blob: 7bce3c5cb63f8477a7b3efb6db291355ddaaf113 [file] [log] [blame]
Robert Snoebergerce8c2042019-01-17 10:36:02 -05001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.keyguard.clock;
17
18import android.content.Context;
19import android.content.res.Resources;
Robert Snoeberger326d0c12019-02-05 11:09:48 -050020import android.text.Annotation;
21import android.text.Spannable;
22import android.text.SpannableString;
23import android.text.SpannedString;
24import android.text.TextUtils;
Robert Snoebergerce8c2042019-01-17 10:36:02 -050025import android.text.format.DateFormat;
Robert Snoeberger326d0c12019-02-05 11:09:48 -050026import android.text.style.ForegroundColorSpan;
Robert Snoebergerce8c2042019-01-17 10:36:02 -050027import android.util.AttributeSet;
Robert Snoebergerce8c2042019-01-17 10:36:02 -050028import android.widget.TextView;
29
30import com.android.keyguard.R;
31
32import java.text.SimpleDateFormat;
33import java.util.Calendar;
34import java.util.TimeZone;
35
36/**
37 * Clock that presents the time in words.
38 */
Robert Snoeberger326d0c12019-02-05 11:09:48 -050039public class TypographicClock extends TextView {
Robert Snoebergerce8c2042019-01-17 10:36:02 -050040
Robert Snoeberger326d0c12019-02-05 11:09:48 -050041 private static final String ANNOTATION_COLOR = "color";
42
43 private final Resources mResources;
Robert Snoebergerce8c2042019-01-17 10:36:02 -050044 private final String[] mHours;
45 private final String[] mMinutes;
Robert Snoeberger0397c842019-02-07 14:25:46 -050046 private int mAccentColor;
Robert Snoeberger71e50792019-02-15 15:48:01 -050047 private final Calendar mTime = Calendar.getInstance(TimeZone.getDefault());
Robert Snoebergerce8c2042019-01-17 10:36:02 -050048 private String mDescFormat;
49 private TimeZone mTimeZone;
50
51 public TypographicClock(Context context) {
52 this(context, null);
53 }
54
55 public TypographicClock(Context context, AttributeSet attrs) {
56 this(context, attrs, 0);
57 }
58
59 public TypographicClock(Context context, AttributeSet attrs, int defStyleAttr) {
60 super(context, attrs, defStyleAttr);
Robert Snoebergerce8c2042019-01-17 10:36:02 -050061 mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern();
Robert Snoeberger326d0c12019-02-05 11:09:48 -050062 mResources = context.getResources();
63 mHours = mResources.getStringArray(R.array.type_clock_hours);
64 mMinutes = mResources.getStringArray(R.array.type_clock_minutes);
65 mAccentColor = mResources.getColor(R.color.typeClockAccentColor, null);
Robert Snoebergerce8c2042019-01-17 10:36:02 -050066 }
67
68 /**
69 * Call when the time changes to update the text of the time.
70 */
71 public void onTimeChanged() {
72 mTime.setTimeInMillis(System.currentTimeMillis());
73 setContentDescription(DateFormat.format(mDescFormat, mTime));
Robert Snoeberger326d0c12019-02-05 11:09:48 -050074 final int hour = mTime.get(Calendar.HOUR) % 12;
75 final int minute = mTime.get(Calendar.MINUTE) % 60;
76
77 // Get the quantity based on the hour for languages like Portuguese and Czech.
78 SpannedString typeTemplate = (SpannedString) mResources.getQuantityText(
79 R.plurals.type_clock_header, hour);
80
81 // Find the "color" annotation and set the foreground color to the accent color.
82 Annotation[] annotations = typeTemplate.getSpans(0, typeTemplate.length(),
83 Annotation.class);
84 SpannableString spanType = new SpannableString(typeTemplate);
85 for (int i = 0; i < annotations.length; i++) {
86 Annotation annotation = annotations[i];
87 String key = annotation.getValue();
88 if (ANNOTATION_COLOR.equals(key)) {
89 spanType.setSpan(new ForegroundColorSpan(mAccentColor),
90 spanType.getSpanStart(annotation), spanType.getSpanEnd(annotation),
91 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
92 }
93 }
94
95 setText(TextUtils.expandTemplate(spanType, mHours[hour], mMinutes[minute]));
Robert Snoebergerce8c2042019-01-17 10:36:02 -050096 }
97
98 /**
99 * Call when the time zone has changed to update clock time.
100 *
101 * @param timeZone The updated time zone that will be used.
102 */
103 public void onTimeZoneChanged(TimeZone timeZone) {
104 mTimeZone = timeZone;
105 mTime.setTimeZone(timeZone);
106 }
107
Robert Snoeberger0397c842019-02-07 14:25:46 -0500108 /**
109 * Sets the accent color used on the clock face.
110 */
111 public void setClockColor(int color) {
112 mAccentColor = color;
Robert Snoeberger71e50792019-02-15 15:48:01 -0500113 onTimeChanged();
Robert Snoeberger0397c842019-02-07 14:25:46 -0500114 }
115
Robert Snoebergerce8c2042019-01-17 10:36:02 -0500116 @Override
117 protected void onAttachedToWindow() {
118 super.onAttachedToWindow();
Robert Snoeberger71e50792019-02-15 15:48:01 -0500119 mTime.setTimeZone(mTimeZone != null ? mTimeZone : TimeZone.getDefault());
Robert Snoebergerce8c2042019-01-17 10:36:02 -0500120 onTimeChanged();
121 }
122}