blob: 417c0692f92938c1ddf41c9ea623f7ec62a37b8a [file] [log] [blame]
Jason Monk8a452e92017-10-31 19:21:47 -04001/*
2 * Copyright 2017 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 */
16
17package androidx.app.slice.widget;
18
Jason Monkdcb5e2f2017-11-15 20:19:43 -050019import static android.app.slice.Slice.HINT_NO_TINT;
20import static android.app.slice.Slice.HINT_SELECTED;
Jason Monk0c76d302017-11-21 14:02:27 -050021import static android.app.slice.SliceItem.FORMAT_ACTION;
Jason Monk0c76d302017-11-21 14:02:27 -050022import static android.app.slice.SliceItem.FORMAT_IMAGE;
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -050023import static android.app.slice.SliceItem.FORMAT_INT;
Jason Monk0c76d302017-11-21 14:02:27 -050024import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;
25
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -050026import static androidx.app.slice.core.SliceHints.EXTRA_SLIDER_VALUE;
Mady Mellorc1334182017-11-10 15:50:35 -080027import static androidx.app.slice.core.SliceHints.EXTRA_TOGGLE_STATE;
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -050028import static androidx.app.slice.core.SliceHints.SUBTYPE_MAX;
29import static androidx.app.slice.core.SliceHints.SUBTYPE_PROGRESS;
Amin Shaikhbfeddba2018-01-10 14:51:13 -050030import static androidx.app.slice.core.SliceHints.SUBTYPE_TOGGLE;
Mady Mellor238b9b62018-01-09 16:15:40 -080031import static androidx.app.slice.widget.SliceView.MODE_LARGE;
32import static androidx.app.slice.widget.SliceView.MODE_SMALL;
Mady Mellorc1334182017-11-10 15:50:35 -080033
Jason Monk2a7d0fc2017-11-15 10:10:24 -050034import android.annotation.TargetApi;
Mady Mellordb8aa8c2017-11-08 14:26:17 -080035import android.app.PendingIntent;
Jason Monk8a452e92017-10-31 19:21:47 -040036import android.app.PendingIntent.CanceledException;
Jason Monk8a452e92017-10-31 19:21:47 -040037import android.content.Context;
Mady Mellordb8aa8c2017-11-08 14:26:17 -080038import android.content.Intent;
Mady Mellorc1334182017-11-10 15:50:35 -080039import android.graphics.drawable.Icon;
Mady Mellordc052042018-01-04 17:11:07 -080040import android.support.annotation.ColorInt;
Jason Monk8a452e92017-10-31 19:21:47 -040041import android.support.annotation.RestrictTo;
Mady Mellordb8aa8c2017-11-08 14:26:17 -080042import android.util.Log;
Jason Monk8a452e92017-10-31 19:21:47 -040043import android.view.View;
Mady Mellor238b9b62018-01-09 16:15:40 -080044import android.view.ViewGroup;
Jason Monk2a7d0fc2017-11-15 10:10:24 -050045import android.widget.CompoundButton;
Jason Monk8a452e92017-10-31 19:21:47 -040046import android.widget.ImageView;
47import android.widget.LinearLayout;
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -050048import android.widget.ProgressBar;
49import android.widget.SeekBar;
Mady Mellordb8aa8c2017-11-08 14:26:17 -080050import android.widget.Switch;
Jason Monk8a452e92017-10-31 19:21:47 -040051import android.widget.TextView;
Mady Mellorc1334182017-11-10 15:50:35 -080052import android.widget.ToggleButton;
Jason Monk8a452e92017-10-31 19:21:47 -040053
Jason Monk8a452e92017-10-31 19:21:47 -040054import java.util.ArrayList;
Jason Monk8a452e92017-10-31 19:21:47 -040055import java.util.List;
56
Jason Monkdcb5e2f2017-11-15 20:19:43 -050057import androidx.app.slice.Slice;
58import androidx.app.slice.SliceItem;
Jason Monk8a452e92017-10-31 19:21:47 -040059import androidx.app.slice.core.SliceQuery;
60import androidx.app.slice.view.R;
61
62/**
Mady Mellorc1334182017-11-10 15:50:35 -080063 * Row item is in small template format and can be used to construct list items for use
64 * with {@link LargeTemplateView}.
Jason Monk8a452e92017-10-31 19:21:47 -040065 *
66 * @hide
67 */
68@RestrictTo(RestrictTo.Scope.LIBRARY)
Jason Monk2a7d0fc2017-11-15 10:10:24 -050069@TargetApi(23)
Mady Mellordc052042018-01-04 17:11:07 -080070public class RowView extends SliceChildView implements View.OnClickListener {
Jason Monk8a452e92017-10-31 19:21:47 -040071
Mady Mellorc1334182017-11-10 15:50:35 -080072 private static final String TAG = "RowView";
Jason Monk8a452e92017-10-31 19:21:47 -040073
Mady Mellordb8aa8c2017-11-08 14:26:17 -080074 // The number of items that fit on the right hand side of a small slice
75 private static final int MAX_END_ITEMS = 3;
76
Jason Monk8a452e92017-10-31 19:21:47 -040077 private LinearLayout mStartContainer;
Mady Mellordb8aa8c2017-11-08 14:26:17 -080078 private LinearLayout mContent;
79 private TextView mPrimaryText;
Jason Monk8a452e92017-10-31 19:21:47 -040080 private TextView mSecondaryText;
Mady Mellorc1334182017-11-10 15:50:35 -080081 private View mDivider;
Amin Shaikhbfeddba2018-01-10 14:51:13 -050082 private ArrayList<CompoundButton> mToggles = new ArrayList<>();
Jason Monk8a452e92017-10-31 19:21:47 -040083 private LinearLayout mEndContainer;
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -050084 private SeekBar mSeekBar;
85 private ProgressBar mProgressBar;
Jason Monk8a452e92017-10-31 19:21:47 -040086
Mady Mellordc052042018-01-04 17:11:07 -080087 private boolean mInSmallMode;
Mady Mellor238b9b62018-01-09 16:15:40 -080088 private int mRowIndex;
89 private RowContent mRowContent;
Mady Mellordb8aa8c2017-11-08 14:26:17 -080090 private SliceItem mRowAction;
Mady Mellordc052042018-01-04 17:11:07 -080091 private boolean mIsHeader;
Mady Mellordb8aa8c2017-11-08 14:26:17 -080092
Mady Mellordc052042018-01-04 17:11:07 -080093 private int mIconSize;
94 private int mPadding;
Mady Mellor238b9b62018-01-09 16:15:40 -080095
Mady Mellorc1334182017-11-10 15:50:35 -080096 public RowView(Context context) {
Jason Monk8a452e92017-10-31 19:21:47 -040097 super(context);
Jason Monk8a452e92017-10-31 19:21:47 -040098 mIconSize = getContext().getResources().getDimensionPixelSize(R.dimen.abc_slice_icon_size);
99 mPadding = getContext().getResources().getDimensionPixelSize(R.dimen.abc_slice_padding);
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800100 inflate(context, R.layout.abc_slice_small_template, this);
Jason Monk8a452e92017-10-31 19:21:47 -0400101
Jason Monk2a7d0fc2017-11-15 10:10:24 -0500102 mStartContainer = (LinearLayout) findViewById(R.id.icon_frame);
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800103 mContent = (LinearLayout) findViewById(android.R.id.content);
104 mPrimaryText = (TextView) findViewById(android.R.id.title);
Jason Monk8a452e92017-10-31 19:21:47 -0400105 mSecondaryText = (TextView) findViewById(android.R.id.summary);
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800106 mDivider = findViewById(R.id.divider);
Jason Monk8a452e92017-10-31 19:21:47 -0400107 mEndContainer = (LinearLayout) findViewById(android.R.id.widget_frame);
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -0500108 mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
109 mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
Jason Monk8a452e92017-10-31 19:21:47 -0400110 }
111
112 @Override
113 public @SliceView.SliceMode int getMode() {
Mady Mellor238b9b62018-01-09 16:15:40 -0800114 return mInSmallMode ? MODE_SMALL : MODE_LARGE;
Jason Monk8a452e92017-10-31 19:21:47 -0400115 }
116
117 @Override
Mady Mellordc052042018-01-04 17:11:07 -0800118 public void setTint(@ColorInt int tintColor) {
119 super.setTint(tintColor);
120 if (mRowContent != null) {
121 // TODO -- can be smarter about this
122 resetView();
123 populateViews();
124 }
Mady Mellor238b9b62018-01-09 16:15:40 -0800125 }
126
Mady Mellorc1334182017-11-10 15:50:35 -0800127 /**
128 * This is called when RowView is being used as a component in a large template.
129 */
Jason Monk8a452e92017-10-31 19:21:47 -0400130 @Override
Mady Mellor238b9b62018-01-09 16:15:40 -0800131 public void setSliceItem(SliceItem slice, boolean isHeader, int index,
132 SliceView.SliceObserver observer) {
Mady Mellordc052042018-01-04 17:11:07 -0800133 mInSmallMode = false;
Mady Mellor238b9b62018-01-09 16:15:40 -0800134 setSliceObserver(observer);
135 mRowIndex = index;
Mady Mellor71ef84d2017-12-11 13:33:36 -0800136 mIsHeader = isHeader;
Mady Mellordc052042018-01-04 17:11:07 -0800137 mRowContent = new RowContent(slice, !mIsHeader /* showStartItem */);
138 populateViews();
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800139 }
Jason Monk2a7d0fc2017-11-15 10:10:24 -0500140
Mady Mellorc1334182017-11-10 15:50:35 -0800141 /**
142 * This is called when RowView is being used as a small template.
143 */
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800144 @Override
Jason Monk8a452e92017-10-31 19:21:47 -0400145 public void setSlice(Slice slice) {
Mady Mellor71ef84d2017-12-11 13:33:36 -0800146 mInSmallMode = true;
Mady Mellordc052042018-01-04 17:11:07 -0800147 mRowIndex = 0;
148 mIsHeader = true;
Mady Mellor6b5cd612017-12-14 11:36:59 -0800149 ListContent lc = new ListContent(slice);
Mady Mellordc052042018-01-04 17:11:07 -0800150 mRowContent = new RowContent(lc.getSummaryItem(), false /* showStartItem */);
151 populateViews();
Jason Monk8a452e92017-10-31 19:21:47 -0400152 }
153
Mady Mellordc052042018-01-04 17:11:07 -0800154 private void populateViews() {
Mady Mellordf269702017-12-20 15:40:00 -0800155 resetView();
Mady Mellor6b5cd612017-12-14 11:36:59 -0800156 boolean showStart = false;
157 final SliceItem startItem = mRowContent.getStartItem();
158 if (startItem != null) {
Mady Mellor238b9b62018-01-09 16:15:40 -0800159 final EventInfo info = new EventInfo(getMode(),
160 EventInfo.ACTION_TYPE_BUTTON,
161 EventInfo.ROW_TYPE_LIST, mRowIndex);
162 info.setPosition(EventInfo.POSITION_START, 0, 1);
Mady Mellordc052042018-01-04 17:11:07 -0800163 showStart = addItem(startItem, mTintColor, true /* isStart */, 0 /* padding */, info);
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800164 }
Mady Mellor6b5cd612017-12-14 11:36:59 -0800165 mStartContainer.setVisibility(showStart ? View.VISIBLE : View.GONE);
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800166
Mady Mellor6b5cd612017-12-14 11:36:59 -0800167 final SliceItem titleItem = mRowContent.getTitleItem();
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800168 if (titleItem != null) {
169 mPrimaryText.setText(titleItem.getText());
170 }
171 mPrimaryText.setVisibility(titleItem != null ? View.VISIBLE : View.GONE);
Mady Mellor6b5cd612017-12-14 11:36:59 -0800172
173 final SliceItem subTitle = mRowContent.getSubtitleItem();
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800174 if (subTitle != null) {
175 mSecondaryText.setText(subTitle.getText());
176 }
177 mSecondaryText.setVisibility(subTitle != null ? View.VISIBLE : View.GONE);
178
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -0500179 final SliceItem slider = mRowContent.getSlider();
180 if (slider != null) {
181 addSlider(slider);
182 return;
183 }
184
Mady Mellor6b5cd612017-12-14 11:36:59 -0800185 mRowAction = mRowContent.getContentIntent();
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500186 ArrayList<SliceItem> endItems = mRowContent.getEndItems();
187 if (endItems.isEmpty()) {
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800188 return;
189 }
Mady Mellor6b5cd612017-12-14 11:36:59 -0800190
191 // If we're here we might be able to show end items
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500192 int itemCount = 0;
193 // Prefer to show actions as end items if possible; fall back to the first format type.
194 String desiredFormat = mRowContent.endItemsContainAction()
195 ? FORMAT_ACTION : endItems.get(0).getFormat();
196 boolean firstItemIsADefaultToggle = false;
197 for (int i = 0; i < endItems.size(); i++) {
198 final SliceItem endItem = endItems.get(i);
199 final String endFormat = endItem.getFormat();
200 // Only show one type of format at the end of the slice, use whatever is first
201 if (itemCount <= MAX_END_ITEMS
202 && (desiredFormat.equals(endFormat)
203 || FORMAT_TIMESTAMP.equals(endFormat))) {
204 final EventInfo info = new EventInfo(getMode(),
205 EventInfo.ACTION_TYPE_BUTTON,
206 EventInfo.ROW_TYPE_LIST, mRowIndex);
207 info.setPosition(EventInfo.POSITION_END, i,
208 Math.min(endItems.size(), MAX_END_ITEMS));
Mady Mellordc052042018-01-04 17:11:07 -0800209 if (addItem(endItem, mTintColor, false /* isStart */, mPadding, info)) {
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500210 itemCount++;
211 if (itemCount == 1) {
212 firstItemIsADefaultToggle = !mToggles.isEmpty()
213 && SliceQuery.find(endItem.getSlice(), FORMAT_IMAGE) == null;
Jason Monk2a7d0fc2017-11-15 10:10:24 -0500214 }
Jason Monk8a452e92017-10-31 19:21:47 -0400215 }
216 }
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500217 }
218
219 boolean hasRowAction = mRowAction != null;
220 boolean hasEndItemAction = FORMAT_ACTION.contentEquals(desiredFormat);
221 // If there is a row action and the first end item is a default toggle, show the divider.
222 mDivider.setVisibility(hasRowAction && firstItemIsADefaultToggle
223 ? View.VISIBLE : View.GONE);
224 if (hasRowAction) {
225 if (itemCount > 0 && hasEndItemAction) {
226 setViewClickable(mContent, true);
227 } else {
228 setViewClickable(this, true);
229 }
230 } else {
231 // If the only end item is an action, make the whole row clickable.
232 if (mRowContent.endItemsContainAction() && itemCount == 1) {
233 setViewClickable(this, true);
Mady Mellor6b5cd612017-12-14 11:36:59 -0800234 }
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800235 }
Jason Monk8a452e92017-10-31 19:21:47 -0400236 }
237
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -0500238 private void addSlider(final SliceItem slider) {
239 final ProgressBar progressBar;
240 if (FORMAT_ACTION.equals(slider.getFormat())) {
241 // Seek bar
242 progressBar = mSeekBar;
243 mSeekBar.setVisibility(View.VISIBLE);
244 SliceItem thumb = SliceQuery.find(slider, FORMAT_IMAGE);
245 if (thumb != null) {
246 mSeekBar.setThumb(thumb.getIcon().loadDrawable(getContext()));
247 }
248 mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
249 @Override
250 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
251 try {
252 PendingIntent pi = slider.getAction();
253 Intent i = new Intent().putExtra(EXTRA_SLIDER_VALUE, progress);
254 // TODO: sending this PendingIntent should be rate limited.
255 pi.send(getContext(), 0, i, null, null);
256 } catch (CanceledException e) { }
257 }
258
259 @Override
260 public void onStartTrackingTouch(SeekBar seekBar) { }
261
262 @Override
263 public void onStopTrackingTouch(SeekBar seekBar) { }
264 });
265 } else {
266 // Progress bar
267 progressBar = mProgressBar;
268 mProgressBar.setVisibility(View.VISIBLE);
269 }
270 SliceItem max = SliceQuery.findSubtype(slider, FORMAT_INT, SUBTYPE_MAX);
271 if (max != null) {
272 progressBar.setMax(max.getInt());
273 }
274 SliceItem progress = SliceQuery.findSubtype(slider, FORMAT_INT, SUBTYPE_PROGRESS);
275 if (progress != null) {
276 progressBar.setProgress(progress.getInt());
277 }
278 }
279
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800280 /**
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500281 * Add a toggle view to container.
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800282 */
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500283 private void addToggle(final SliceItem toggleItem, int color, ViewGroup container) {
Mady Mellorc1334182017-11-10 15:50:35 -0800284 // Check if this is a custom toggle
285 Icon checkedIcon = null;
286 List<SliceItem> sliceItems = toggleItem.getSlice().getItems();
287 if (sliceItems.size() > 0) {
288 checkedIcon = FORMAT_IMAGE.equals(sliceItems.get(0).getFormat())
289 ? sliceItems.get(0).getIcon()
290 : null;
291 }
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500292 final CompoundButton toggle;
Mady Mellorc1334182017-11-10 15:50:35 -0800293 if (checkedIcon != null) {
294 if (color != -1) {
Mady Mellordc052042018-01-04 17:11:07 -0800295 // TODO - Should custom toggle buttons be tinted? What if the app wants diff
296 // colors per state?
Mady Mellorc1334182017-11-10 15:50:35 -0800297 checkedIcon.setTint(color);
298 }
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500299 toggle = new ToggleButton(getContext());
300 ((ToggleButton) toggle).setTextOff("");
301 ((ToggleButton) toggle).setTextOn("");
302 toggle.setBackground(checkedIcon.loadDrawable(getContext()));
303 container.addView(toggle);
304 LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) toggle.getLayoutParams();
Mady Mellorc1334182017-11-10 15:50:35 -0800305 lp.width = mIconSize;
306 lp.height = mIconSize;
307 } else {
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500308 toggle = new Switch(getContext());
309 container.addView(toggle);
Mady Mellorc1334182017-11-10 15:50:35 -0800310 }
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500311 toggle.setChecked(SliceQuery.hasHints(toggleItem.getSlice(), HINT_SELECTED));
312 toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
Jason Monk2a7d0fc2017-11-15 10:10:24 -0500313 @Override
314 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
315 try {
316 PendingIntent pi = toggleItem.getAction();
Mady Mellorc1334182017-11-10 15:50:35 -0800317 Intent i = new Intent().putExtra(EXTRA_TOGGLE_STATE, isChecked);
Jason Monk2a7d0fc2017-11-15 10:10:24 -0500318 pi.send(getContext(), 0, i, null, null);
Mady Mellor238b9b62018-01-09 16:15:40 -0800319 if (mObserver != null) {
320 final EventInfo info = new EventInfo(getMode(),
321 EventInfo.ACTION_TYPE_TOGGLE,
322 EventInfo.ROW_TYPE_LIST, mRowIndex);
323 info.state = isChecked ? EventInfo.STATE_ON : EventInfo.STATE_OFF;
324 mObserver.onSliceAction(info, toggleItem);
325 }
Jason Monk2a7d0fc2017-11-15 10:10:24 -0500326 } catch (CanceledException e) {
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500327 toggle.setSelected(!isChecked);
Jason Monk2a7d0fc2017-11-15 10:10:24 -0500328 }
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800329 }
330 });
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500331 mToggles.add(toggle);
Jason Monk8a452e92017-10-31 19:21:47 -0400332 }
333
334 /**
Mady Mellorc1334182017-11-10 15:50:35 -0800335 * Adds simple items to a container. Simple items include actions with icons, images, or
336 * timestamps.
Jason Monk8a452e92017-10-31 19:21:47 -0400337 */
Mady Mellor238b9b62018-01-09 16:15:40 -0800338 private boolean addItem(SliceItem sliceItem, int color, boolean isStart, int padding,
339 final EventInfo info) {
Jason Monk8a452e92017-10-31 19:21:47 -0400340 SliceItem image = null;
341 SliceItem action = null;
Mady Mellorc1334182017-11-10 15:50:35 -0800342 SliceItem timeStamp = null;
Mady Mellor238b9b62018-01-09 16:15:40 -0800343 ViewGroup container = isStart ? mStartContainer : mEndContainer;
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500344 if (FORMAT_ACTION.equals(sliceItem.getFormat())) {
345 if (SliceQuery.hasHints(sliceItem.getSlice(), SUBTYPE_TOGGLE)) {
346 addToggle(sliceItem, color, container);
347 return true;
348 }
Jason Monk0c76d302017-11-21 14:02:27 -0500349 image = SliceQuery.find(sliceItem.getSlice(), FORMAT_IMAGE);
Mady Mellorc1334182017-11-10 15:50:35 -0800350 timeStamp = SliceQuery.find(sliceItem.getSlice(), FORMAT_TIMESTAMP);
Jason Monk8a452e92017-10-31 19:21:47 -0400351 action = sliceItem;
Jason Monk0c76d302017-11-21 14:02:27 -0500352 } else if (FORMAT_IMAGE.equals(sliceItem.getFormat())) {
Jason Monk8a452e92017-10-31 19:21:47 -0400353 image = sliceItem;
Mady Mellorc1334182017-11-10 15:50:35 -0800354 } else if (FORMAT_TIMESTAMP.equals(sliceItem.getFormat())) {
355 timeStamp = sliceItem;
Jason Monk8a452e92017-10-31 19:21:47 -0400356 }
Mady Mellorc1334182017-11-10 15:50:35 -0800357 View addedView = null;
Jason Monk8a452e92017-10-31 19:21:47 -0400358 if (image != null) {
359 ImageView iv = new ImageView(getContext());
360 iv.setImageIcon(image.getIcon());
Jason Monkdcb5e2f2017-11-15 20:19:43 -0500361 if (color != -1 && !sliceItem.hasHint(HINT_NO_TINT)) {
Jason Monk8a452e92017-10-31 19:21:47 -0400362 iv.setColorFilter(color);
363 }
364 container.addView(iv);
365 LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) iv.getLayoutParams();
366 lp.width = mIconSize;
367 lp.height = mIconSize;
Mady Mellorc1334182017-11-10 15:50:35 -0800368 lp.setMarginStart(padding);
369 addedView = iv;
370 } else if (timeStamp != null) {
371 TextView tv = new TextView(getContext());
372 tv.setText(SliceViewUtil.getRelativeTimeString(sliceItem.getTimestamp()));
373 container.addView(tv);
374 addedView = tv;
Jason Monk8a452e92017-10-31 19:21:47 -0400375 }
Mady Mellorc1334182017-11-10 15:50:35 -0800376 if (action != null && addedView != null) {
377 final SliceItem sliceAction = action;
378 addedView.setOnClickListener(new View.OnClickListener() {
379 @Override
380 public void onClick(View v) {
Mady Mellor238b9b62018-01-09 16:15:40 -0800381 try {
382 sliceAction.getAction().send();
383 if (mObserver != null) {
384 mObserver.onSliceAction(info, sliceAction);
Mady Mellorc1334182017-11-10 15:50:35 -0800385 }
Mady Mellor238b9b62018-01-09 16:15:40 -0800386 } catch (CanceledException e) {
387 e.printStackTrace();
388 }
Mady Mellorc1334182017-11-10 15:50:35 -0800389 }
390 });
391 addedView.setBackground(SliceViewUtil.getDrawable(getContext(),
392 android.R.attr.selectableItemBackground));
393 }
394 return addedView != null;
Jason Monk8a452e92017-10-31 19:21:47 -0400395 }
396
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800397 @Override
398 public void onClick(View view) {
Jason Monk0c76d302017-11-21 14:02:27 -0500399 if (mRowAction != null && FORMAT_ACTION.equals(mRowAction.getFormat())) {
Mady Mellorc1334182017-11-10 15:50:35 -0800400 // Check for a row action
Mady Mellor238b9b62018-01-09 16:15:40 -0800401 try {
402 mRowAction.getAction().send();
403 if (mObserver != null) {
404 EventInfo info = new EventInfo(getMode(), EventInfo.ACTION_TYPE_CONTENT,
405 EventInfo.ROW_TYPE_LIST, mRowIndex);
406 mObserver.onSliceAction(info, mRowAction);
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800407 }
Mady Mellor238b9b62018-01-09 16:15:40 -0800408 } catch (CanceledException e) {
409 Log.w(TAG, "PendingIntent for slice cannot be sent", e);
410 }
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500411 } else if (mToggles.size() == 1) {
412 // If there is only one toggle and no row action, just toggle it.
413 mToggles.get(0).toggle();
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800414 }
415 }
416
Mady Mellordf269702017-12-20 15:40:00 -0800417 private void setViewClickable(View layout, boolean isClickable) {
418 layout.setOnClickListener(isClickable ? this : null);
419 layout.setBackground(isClickable ? SliceViewUtil.getDrawable(getContext(),
420 android.R.attr.selectableItemBackground) : null);
Mady Mellor238b9b62018-01-09 16:15:40 -0800421 layout.setClickable(isClickable);
Jason Monk8a452e92017-10-31 19:21:47 -0400422 }
423
Mady Mellordf269702017-12-20 15:40:00 -0800424 @Override
425 public void resetView() {
426 setViewClickable(this, false);
427 setViewClickable(mContent, false);
Jason Monk8a452e92017-10-31 19:21:47 -0400428 mStartContainer.removeAllViews();
429 mEndContainer.removeAllViews();
Mady Mellordb8aa8c2017-11-08 14:26:17 -0800430 mPrimaryText.setText(null);
Jason Monk8a452e92017-10-31 19:21:47 -0400431 mSecondaryText.setText(null);
Amin Shaikhbfeddba2018-01-10 14:51:13 -0500432 mToggles.clear();
Mady Mellordf269702017-12-20 15:40:00 -0800433 mRowAction = null;
Mady Mellorc1334182017-11-10 15:50:35 -0800434 mDivider.setVisibility(View.GONE);
Amin Shaikhf2cdc3a2018-01-17 09:35:23 -0500435 mSeekBar.setVisibility(View.GONE);
436 mProgressBar.setVisibility(View.GONE);
Jason Monk8a452e92017-10-31 19:21:47 -0400437 }
438}