1 /* 2 * Copyright (C) 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 17 package com.example.android.wearable.watchface.config; 18 19 import static com.example.android.wearable.watchface.config.ColorSelectionActivity.EXTRA_SHARED_PREF; 20 21 import android.app.Activity; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.SharedPreferences; 26 import android.graphics.Color; 27 import android.graphics.PorterDuff; 28 import android.graphics.PorterDuffColorFilter; 29 import android.graphics.drawable.Drawable; 30 import android.support.annotation.Nullable; 31 import android.support.v7.widget.RecyclerView; 32 import android.support.wearable.complications.ComplicationHelperActivity; 33 import android.support.wearable.complications.ComplicationProviderInfo; 34 import android.support.wearable.complications.ProviderInfoRetriever; 35 import android.support.wearable.complications.ProviderInfoRetriever.OnProviderInfoReceivedCallback; 36 import android.util.Log; 37 import android.view.Gravity; 38 import android.view.LayoutInflater; 39 import android.view.View; 40 import android.view.View.OnClickListener; 41 import android.view.ViewGroup; 42 import android.widget.Button; 43 import android.widget.ImageButton; 44 import android.widget.ImageView; 45 import android.widget.Switch; 46 import android.widget.Toast; 47 48 import com.example.android.wearable.watchface.R; 49 import com.example.android.wearable.watchface.model.AnalogComplicationConfigData.BackgroundComplicationConfigItem; 50 import com.example.android.wearable.watchface.model.AnalogComplicationConfigData.ColorConfigItem; 51 import com.example.android.wearable.watchface.model.AnalogComplicationConfigData.ConfigItemType; 52 import com.example.android.wearable.watchface.model.AnalogComplicationConfigData.MoreOptionsConfigItem; 53 import com.example.android.wearable.watchface.model.AnalogComplicationConfigData.PreviewAndComplicationsConfigItem; 54 import com.example.android.wearable.watchface.model.AnalogComplicationConfigData.UnreadNotificationConfigItem; 55 import com.example.android.wearable.watchface.watchface.AnalogComplicationWatchFaceService; 56 57 import java.util.ArrayList; 58 import java.util.concurrent.Executors; 59 60 /** 61 * Displays different layouts for configuring watch face's complications and appearance settings 62 * (highlight color [second arm], background color, unread notifications, etc.). 63 * 64 * <p>All appearance settings are saved via {@link SharedPreferences}. 65 * 66 * <p>Layouts provided by this adapter are split into 5 main view types. 67 * 68 * <p>A watch face preview including complications. Allows user to tap on the complications to 69 * change the complication data and see a live preview of the watch face. 70 * 71 * <p>Simple arrow to indicate there are more options below the fold. 72 * 73 * <p>Color configuration options for both highlight (seconds hand) and background color. 74 * 75 * <p>Toggle for unread notifications. 76 * 77 * <p>Background image complication configuration for changing background image of watch face. 78 */ 79 public class AnalogComplicationConfigRecyclerViewAdapter 80 extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 81 82 private static final String TAG = "CompConfigAdapter"; 83 84 /** 85 * Used by associated watch face ({@link AnalogComplicationWatchFaceService}) to let this 86 * adapter know which complication locations are supported, their ids, and supported 87 * complication data types. 88 */ 89 public enum ComplicationLocation { 90 BACKGROUND, 91 LEFT, 92 RIGHT, 93 TOP, 94 BOTTOM 95 } 96 97 public static final int TYPE_PREVIEW_AND_COMPLICATIONS_CONFIG = 0; 98 public static final int TYPE_MORE_OPTIONS = 1; 99 public static final int TYPE_COLOR_CONFIG = 2; 100 public static final int TYPE_UNREAD_NOTIFICATION_CONFIG = 3; 101 public static final int TYPE_BACKGROUND_COMPLICATION_IMAGE_CONFIG = 4; 102 103 // ComponentName associated with watch face service (service that renders watch face). Used 104 // to retrieve complication information. 105 private ComponentName mWatchFaceComponentName; 106 107 private ArrayList<ConfigItemType> mSettingsDataSet; 108 109 private Context mContext; 110 111 SharedPreferences mSharedPref; 112 113 // Selected complication id by user. 114 private int mSelectedComplicationId; 115 116 private int mBackgroundComplicationId; 117 private int mLeftComplicationId; 118 private int mRightComplicationId; 119 120 // Required to retrieve complication data from watch face for preview. 121 private ProviderInfoRetriever mProviderInfoRetriever; 122 123 // Maintains reference view holder to dynamically update watch face preview. Used instead of 124 // notifyItemChanged(int position) to avoid flicker and re-inflating the view. 125 private PreviewAndComplicationsViewHolder mPreviewAndComplicationsViewHolder; 126 127 public AnalogComplicationConfigRecyclerViewAdapter( 128 Context context, 129 Class watchFaceServiceClass, 130 ArrayList<ConfigItemType> settingsDataSet) { 131 132 mContext = context; 133 mWatchFaceComponentName = new ComponentName(mContext, watchFaceServiceClass); 134 mSettingsDataSet = settingsDataSet; 135 136 // Default value is invalid (only changed when user taps to change complication). 137 mSelectedComplicationId = -1; 138 139 mBackgroundComplicationId = 140 AnalogComplicationWatchFaceService.getComplicationId( 141 ComplicationLocation.BACKGROUND); 142 143 mLeftComplicationId = 144 AnalogComplicationWatchFaceService.getComplicationId(ComplicationLocation.LEFT); 145 mRightComplicationId = 146 AnalogComplicationWatchFaceService.getComplicationId(ComplicationLocation.RIGHT); 147 148 mSharedPref = 149 context.getSharedPreferences( 150 context.getString(R.string.analog_complication_preference_file_key), 151 Context.MODE_PRIVATE); 152 153 // Initialization of code to retrieve active complication data for the watch face. 154 mProviderInfoRetriever = 155 new ProviderInfoRetriever(mContext, Executors.newCachedThreadPool()); 156 mProviderInfoRetriever.init(); 157 } 158 159 @Override 160 public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 161 Log.d(TAG, "onCreateViewHolder(): viewType: " + viewType); 162 163 RecyclerView.ViewHolder viewHolder = null; 164 165 switch (viewType) { 166 case TYPE_PREVIEW_AND_COMPLICATIONS_CONFIG: 167 // Need direct reference to watch face preview view holder to update watch face 168 // preview based on selections from the user. 169 mPreviewAndComplicationsViewHolder = 170 new PreviewAndComplicationsViewHolder( 171 LayoutInflater.from(parent.getContext()) 172 .inflate( 173 R.layout.config_list_preview_and_complications_item, 174 parent, 175 false)); 176 viewHolder = mPreviewAndComplicationsViewHolder; 177 break; 178 179 case TYPE_MORE_OPTIONS: 180 viewHolder = 181 new MoreOptionsViewHolder( 182 LayoutInflater.from(parent.getContext()) 183 .inflate( 184 R.layout.config_list_more_options_item, 185 parent, 186 false)); 187 break; 188 189 case TYPE_COLOR_CONFIG: 190 viewHolder = 191 new ColorPickerViewHolder( 192 LayoutInflater.from(parent.getContext()) 193 .inflate(R.layout.config_list_color_item, parent, false)); 194 break; 195 196 case TYPE_UNREAD_NOTIFICATION_CONFIG: 197 viewHolder = 198 new UnreadNotificationViewHolder( 199 LayoutInflater.from(parent.getContext()) 200 .inflate( 201 R.layout.config_list_unread_notif_item, 202 parent, 203 false)); 204 break; 205 206 case TYPE_BACKGROUND_COMPLICATION_IMAGE_CONFIG: 207 viewHolder = 208 new BackgroundComplicationViewHolder( 209 LayoutInflater.from(parent.getContext()) 210 .inflate( 211 R.layout.config_list_background_complication_item, 212 parent, 213 false)); 214 break; 215 } 216 217 return viewHolder; 218 } 219 220 @Override 221 public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { 222 Log.d(TAG, "Element " + position + " set."); 223 224 // Pulls all data required for creating the UX for the specific setting option. 225 ConfigItemType configItemType = mSettingsDataSet.get(position); 226 227 switch (viewHolder.getItemViewType()) { 228 case TYPE_PREVIEW_AND_COMPLICATIONS_CONFIG: 229 PreviewAndComplicationsViewHolder previewAndComplicationsViewHolder = 230 (PreviewAndComplicationsViewHolder) viewHolder; 231 232 PreviewAndComplicationsConfigItem previewAndComplicationsConfigItem = 233 (PreviewAndComplicationsConfigItem) configItemType; 234 235 int defaultComplicationResourceId = 236 previewAndComplicationsConfigItem.getDefaultComplicationResourceId(); 237 previewAndComplicationsViewHolder.setDefaultComplicationDrawable( 238 defaultComplicationResourceId); 239 240 previewAndComplicationsViewHolder.initializesColorsAndComplications(); 241 break; 242 243 case TYPE_MORE_OPTIONS: 244 MoreOptionsViewHolder moreOptionsViewHolder = (MoreOptionsViewHolder) viewHolder; 245 MoreOptionsConfigItem moreOptionsConfigItem = 246 (MoreOptionsConfigItem) configItemType; 247 248 moreOptionsViewHolder.setIcon(moreOptionsConfigItem.getIconResourceId()); 249 break; 250 251 case TYPE_COLOR_CONFIG: 252 ColorPickerViewHolder colorPickerViewHolder = (ColorPickerViewHolder) viewHolder; 253 ColorConfigItem colorConfigItem = (ColorConfigItem) configItemType; 254 255 int iconResourceId = colorConfigItem.getIconResourceId(); 256 String name = colorConfigItem.getName(); 257 String sharedPrefString = colorConfigItem.getSharedPrefString(); 258 Class<ColorSelectionActivity> activity = 259 colorConfigItem.getActivityToChoosePreference(); 260 261 colorPickerViewHolder.setIcon(iconResourceId); 262 colorPickerViewHolder.setName(name); 263 colorPickerViewHolder.setSharedPrefString(sharedPrefString); 264 colorPickerViewHolder.setLaunchActivityToSelectColor(activity); 265 break; 266 267 case TYPE_UNREAD_NOTIFICATION_CONFIG: 268 UnreadNotificationViewHolder unreadViewHolder = 269 (UnreadNotificationViewHolder) viewHolder; 270 271 UnreadNotificationConfigItem unreadConfigItem = 272 (UnreadNotificationConfigItem) configItemType; 273 274 int unreadEnabledIconResourceId = unreadConfigItem.getIconEnabledResourceId(); 275 int unreadDisabledIconResourceId = unreadConfigItem.getIconDisabledResourceId(); 276 277 String unreadName = unreadConfigItem.getName(); 278 int unreadSharedPrefId = unreadConfigItem.getSharedPrefId(); 279 280 unreadViewHolder.setIcons( 281 unreadEnabledIconResourceId, unreadDisabledIconResourceId); 282 unreadViewHolder.setName(unreadName); 283 unreadViewHolder.setSharedPrefId(unreadSharedPrefId); 284 break; 285 286 case TYPE_BACKGROUND_COMPLICATION_IMAGE_CONFIG: 287 BackgroundComplicationViewHolder backgroundComplicationViewHolder = 288 (BackgroundComplicationViewHolder) viewHolder; 289 290 BackgroundComplicationConfigItem backgroundComplicationConfigItem = 291 (BackgroundComplicationConfigItem) configItemType; 292 293 int backgroundIconResourceId = backgroundComplicationConfigItem.getIconResourceId(); 294 String backgroundName = backgroundComplicationConfigItem.getName(); 295 296 backgroundComplicationViewHolder.setIcon(backgroundIconResourceId); 297 backgroundComplicationViewHolder.setName(backgroundName); 298 break; 299 } 300 } 301 302 @Override 303 public int getItemViewType(int position) { 304 ConfigItemType configItemType = mSettingsDataSet.get(position); 305 return configItemType.getConfigType(); 306 } 307 308 @Override 309 public int getItemCount() { 310 return mSettingsDataSet.size(); 311 } 312 313 /** Updates the selected complication id saved earlier with the new information. */ 314 public void updateSelectedComplication(ComplicationProviderInfo complicationProviderInfo) { 315 316 Log.d(TAG, "updateSelectedComplication: " + mPreviewAndComplicationsViewHolder); 317 318 // Checks if view is inflated and complication id is valid. 319 if (mPreviewAndComplicationsViewHolder != null && mSelectedComplicationId >= 0) { 320 mPreviewAndComplicationsViewHolder.updateComplicationViews( 321 mSelectedComplicationId, complicationProviderInfo); 322 } 323 } 324 325 @Override 326 public void onDetachedFromRecyclerView(RecyclerView recyclerView) { 327 super.onDetachedFromRecyclerView(recyclerView); 328 // Required to release retriever for active complication data on detach. 329 mProviderInfoRetriever.release(); 330 } 331 332 public void updatePreviewColors() { 333 Log.d(TAG, "updatePreviewColors(): " + mPreviewAndComplicationsViewHolder); 334 335 if (mPreviewAndComplicationsViewHolder != null) { 336 mPreviewAndComplicationsViewHolder.updateWatchFaceColors(); 337 } 338 } 339 340 /** 341 * Displays watch face preview along with complication locations. Allows user to tap on the 342 * complication they want to change and preview updates dynamically. 343 */ 344 public class PreviewAndComplicationsViewHolder extends RecyclerView.ViewHolder 345 implements OnClickListener { 346 347 private View mWatchFaceArmsAndTicksView; 348 private View mWatchFaceHighlightPreviewView; 349 private ImageView mWatchFaceBackgroundPreviewImageView; 350 351 private ImageView mLeftComplicationBackground; 352 private ImageView mRightComplicationBackground; 353 354 private ImageButton mLeftComplication; 355 private ImageButton mRightComplication; 356 357 private Drawable mDefaultComplicationDrawable; 358 359 private boolean mBackgroundComplicationEnabled; 360 361 public PreviewAndComplicationsViewHolder(final View view) { 362 super(view); 363 364 mWatchFaceBackgroundPreviewImageView = 365 (ImageView) view.findViewById(R.id.watch_face_background); 366 mWatchFaceArmsAndTicksView = view.findViewById(R.id.watch_face_arms_and_ticks); 367 368 // In our case, just the second arm. 369 mWatchFaceHighlightPreviewView = view.findViewById(R.id.watch_face_highlight); 370 371 // Sets up left complication preview. 372 mLeftComplicationBackground = 373 (ImageView) view.findViewById(R.id.left_complication_background); 374 mLeftComplication = (ImageButton) view.findViewById(R.id.left_complication); 375 mLeftComplication.setOnClickListener(this); 376 377 // Sets up right complication preview. 378 mRightComplicationBackground = 379 (ImageView) view.findViewById(R.id.right_complication_background); 380 mRightComplication = (ImageButton) view.findViewById(R.id.right_complication); 381 mRightComplication.setOnClickListener(this); 382 } 383 384 @Override 385 public void onClick(View view) { 386 if (view.equals(mLeftComplication)) { 387 Log.d(TAG, "Left Complication click()"); 388 389 Activity currentActivity = (Activity) view.getContext(); 390 launchComplicationHelperActivity(currentActivity, ComplicationLocation.LEFT); 391 392 } else if (view.equals(mRightComplication)) { 393 Log.d(TAG, "Right Complication click()"); 394 395 Activity currentActivity = (Activity) view.getContext(); 396 launchComplicationHelperActivity(currentActivity, ComplicationLocation.RIGHT); 397 } 398 } 399 400 public void updateWatchFaceColors() { 401 402 // Only update background colors for preview if background complications are disabled. 403 if (!mBackgroundComplicationEnabled) { 404 // Updates background color. 405 String backgroundSharedPrefString = 406 mContext.getString(R.string.saved_background_color); 407 int currentBackgroundColor = 408 mSharedPref.getInt(backgroundSharedPrefString, Color.BLACK); 409 410 PorterDuffColorFilter backgroundColorFilter = 411 new PorterDuffColorFilter(currentBackgroundColor, PorterDuff.Mode.SRC_ATOP); 412 413 mWatchFaceBackgroundPreviewImageView 414 .getBackground() 415 .setColorFilter(backgroundColorFilter); 416 417 } else { 418 // Inform user that they need to disable background image for color to work. 419 CharSequence text = "Selected image overrides background color."; 420 int duration = Toast.LENGTH_SHORT; 421 Toast toast = Toast.makeText(mContext, text, duration); 422 toast.setGravity(Gravity.CENTER, 0, 0); 423 toast.show(); 424 } 425 426 // Updates highlight color (just second arm). 427 String highlightSharedPrefString = mContext.getString(R.string.saved_marker_color); 428 int currentHighlightColor = mSharedPref.getInt(highlightSharedPrefString, Color.RED); 429 430 PorterDuffColorFilter highlightColorFilter = 431 new PorterDuffColorFilter(currentHighlightColor, PorterDuff.Mode.SRC_ATOP); 432 433 mWatchFaceHighlightPreviewView.getBackground().setColorFilter(highlightColorFilter); 434 } 435 436 // Verifies the watch face supports the complication location, then launches the helper 437 // class, so user can choose their complication data provider. 438 private void launchComplicationHelperActivity( 439 Activity currentActivity, ComplicationLocation complicationLocation) { 440 441 mSelectedComplicationId = 442 AnalogComplicationWatchFaceService.getComplicationId(complicationLocation); 443 444 mBackgroundComplicationEnabled = false; 445 446 if (mSelectedComplicationId >= 0) { 447 448 int[] supportedTypes = 449 AnalogComplicationWatchFaceService.getSupportedComplicationTypes( 450 complicationLocation); 451 452 ComponentName watchFace = 453 new ComponentName( 454 currentActivity, AnalogComplicationWatchFaceService.class); 455 456 currentActivity.startActivityForResult( 457 ComplicationHelperActivity.createProviderChooserHelperIntent( 458 currentActivity, 459 watchFace, 460 mSelectedComplicationId, 461 supportedTypes), 462 AnalogComplicationConfigActivity.COMPLICATION_CONFIG_REQUEST_CODE); 463 464 } else { 465 Log.d(TAG, "Complication not supported by watch face."); 466 } 467 } 468 469 public void setDefaultComplicationDrawable(int resourceId) { 470 Context context = mWatchFaceArmsAndTicksView.getContext(); 471 mDefaultComplicationDrawable = context.getDrawable(resourceId); 472 473 mLeftComplication.setImageDrawable(mDefaultComplicationDrawable); 474 mLeftComplicationBackground.setVisibility(View.INVISIBLE); 475 476 mRightComplication.setImageDrawable(mDefaultComplicationDrawable); 477 mRightComplicationBackground.setVisibility(View.INVISIBLE); 478 } 479 480 public void updateComplicationViews( 481 int watchFaceComplicationId, ComplicationProviderInfo complicationProviderInfo) { 482 Log.d(TAG, "updateComplicationViews(): id: " + watchFaceComplicationId); 483 Log.d(TAG, "\tinfo: " + complicationProviderInfo); 484 485 if (watchFaceComplicationId == mBackgroundComplicationId) { 486 if (complicationProviderInfo != null) { 487 mBackgroundComplicationEnabled = true; 488 489 // Since we can't get the background complication image outside of the 490 // watch face, we set the icon for that provider instead with a gray background. 491 PorterDuffColorFilter backgroundColorFilter = 492 new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP); 493 494 mWatchFaceBackgroundPreviewImageView 495 .getBackground() 496 .setColorFilter(backgroundColorFilter); 497 mWatchFaceBackgroundPreviewImageView.setImageIcon( 498 complicationProviderInfo.providerIcon); 499 500 } else { 501 mBackgroundComplicationEnabled = false; 502 503 // Clears icon for background if it was present before. 504 mWatchFaceBackgroundPreviewImageView.setImageResource( 505 android.R.color.transparent); 506 String backgroundSharedPrefString = 507 mContext.getString(R.string.saved_background_color); 508 int currentBackgroundColor = 509 mSharedPref.getInt(backgroundSharedPrefString, Color.BLACK); 510 511 PorterDuffColorFilter backgroundColorFilter = 512 new PorterDuffColorFilter( 513 currentBackgroundColor, PorterDuff.Mode.SRC_ATOP); 514 515 mWatchFaceBackgroundPreviewImageView 516 .getBackground() 517 .setColorFilter(backgroundColorFilter); 518 } 519 520 } else if (watchFaceComplicationId == mLeftComplicationId) { 521 updateComplicationView(complicationProviderInfo, mLeftComplication, 522 mLeftComplicationBackground); 523 524 } else if (watchFaceComplicationId == mRightComplicationId) { 525 updateComplicationView(complicationProviderInfo, mRightComplication, 526 mRightComplicationBackground); 527 } 528 } 529 530 private void updateComplicationView(ComplicationProviderInfo complicationProviderInfo, 531 ImageButton button, ImageView background) { 532 if (complicationProviderInfo != null) { 533 button.setImageIcon(complicationProviderInfo.providerIcon); 534 button.setContentDescription( 535 mContext.getString(R.string.edit_complication, 536 complicationProviderInfo.appName + " " + 537 complicationProviderInfo.providerName)); 538 background.setVisibility(View.VISIBLE); 539 } else { 540 button.setImageDrawable(mDefaultComplicationDrawable); 541 button.setContentDescription(mContext.getString(R.string.add_complication)); 542 background.setVisibility(View.INVISIBLE); 543 } 544 } 545 546 public void initializesColorsAndComplications() { 547 548 // Initializes highlight color (just second arm and part of complications). 549 String highlightSharedPrefString = mContext.getString(R.string.saved_marker_color); 550 int currentHighlightColor = mSharedPref.getInt(highlightSharedPrefString, Color.RED); 551 552 PorterDuffColorFilter highlightColorFilter = 553 new PorterDuffColorFilter(currentHighlightColor, PorterDuff.Mode.SRC_ATOP); 554 555 mWatchFaceHighlightPreviewView.getBackground().setColorFilter(highlightColorFilter); 556 557 // Initializes background color to gray (updates to color or complication icon based 558 // on whether the background complication is live or not. 559 PorterDuffColorFilter backgroundColorFilter = 560 new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP); 561 562 mWatchFaceBackgroundPreviewImageView 563 .getBackground() 564 .setColorFilter(backgroundColorFilter); 565 566 final int[] complicationIds = AnalogComplicationWatchFaceService.getComplicationIds(); 567 568 mProviderInfoRetriever.retrieveProviderInfo( 569 new OnProviderInfoReceivedCallback() { 570 @Override 571 public void onProviderInfoReceived( 572 int watchFaceComplicationId, 573 @Nullable ComplicationProviderInfo complicationProviderInfo) { 574 575 Log.d(TAG, "onProviderInfoReceived: " + complicationProviderInfo); 576 577 updateComplicationViews( 578 watchFaceComplicationId, complicationProviderInfo); 579 } 580 }, 581 mWatchFaceComponentName, 582 complicationIds); 583 } 584 } 585 586 /** Displays icon to indicate there are more options below the fold. */ 587 public class MoreOptionsViewHolder extends RecyclerView.ViewHolder { 588 589 private ImageView mMoreOptionsImageView; 590 591 public MoreOptionsViewHolder(View view) { 592 super(view); 593 mMoreOptionsImageView = (ImageView) view.findViewById(R.id.more_options_image_view); 594 } 595 596 public void setIcon(int resourceId) { 597 Context context = mMoreOptionsImageView.getContext(); 598 mMoreOptionsImageView.setImageDrawable(context.getDrawable(resourceId)); 599 } 600 } 601 602 /** 603 * Displays color options for the an item on the watch face. These could include marker color, 604 * background color, etc. 605 */ 606 public class ColorPickerViewHolder extends RecyclerView.ViewHolder implements OnClickListener { 607 608 private Button mAppearanceButton; 609 610 private String mSharedPrefResourceString; 611 612 private Class<ColorSelectionActivity> mLaunchActivityToSelectColor; 613 614 public ColorPickerViewHolder(View view) { 615 super(view); 616 617 mAppearanceButton = (Button) view.findViewById(R.id.color_picker_button); 618 view.setOnClickListener(this); 619 } 620 621 public void setName(String name) { 622 mAppearanceButton.setText(name); 623 } 624 625 public void setIcon(int resourceId) { 626 Context context = mAppearanceButton.getContext(); 627 mAppearanceButton.setCompoundDrawablesWithIntrinsicBounds( 628 context.getDrawable(resourceId), null, null, null); 629 } 630 631 public void setSharedPrefString(String sharedPrefString) { 632 mSharedPrefResourceString = sharedPrefString; 633 } 634 635 public void setLaunchActivityToSelectColor(Class<ColorSelectionActivity> activity) { 636 mLaunchActivityToSelectColor = activity; 637 } 638 639 @Override 640 public void onClick(View view) { 641 int position = getAdapterPosition(); 642 Log.d(TAG, "Complication onClick() position: " + position); 643 644 if (mLaunchActivityToSelectColor != null) { 645 Intent launchIntent = new Intent(view.getContext(), mLaunchActivityToSelectColor); 646 647 // Pass shared preference name to save color value to. 648 launchIntent.putExtra(EXTRA_SHARED_PREF, mSharedPrefResourceString); 649 650 Activity activity = (Activity) view.getContext(); 651 activity.startActivityForResult( 652 launchIntent, 653 AnalogComplicationConfigActivity.UPDATE_COLORS_CONFIG_REQUEST_CODE); 654 } 655 } 656 } 657 658 /** 659 * Displays switch to indicate whether or not icon appears for unread notifications. User can 660 * toggle on/off. 661 */ 662 public class UnreadNotificationViewHolder extends RecyclerView.ViewHolder 663 implements OnClickListener { 664 665 private Switch mUnreadNotificationSwitch; 666 667 private int mEnabledIconResourceId; 668 private int mDisabledIconResourceId; 669 670 private int mSharedPrefResourceId; 671 672 public UnreadNotificationViewHolder(View view) { 673 super(view); 674 675 mUnreadNotificationSwitch = (Switch) view.findViewById(R.id.unread_notification_switch); 676 view.setOnClickListener(this); 677 } 678 679 public void setName(String name) { 680 mUnreadNotificationSwitch.setText(name); 681 } 682 683 public void setIcons(int enabledIconResourceId, int disabledIconResourceId) { 684 685 mEnabledIconResourceId = enabledIconResourceId; 686 mDisabledIconResourceId = disabledIconResourceId; 687 688 Context context = mUnreadNotificationSwitch.getContext(); 689 690 // Set default to enabled. 691 mUnreadNotificationSwitch.setCompoundDrawablesWithIntrinsicBounds( 692 context.getDrawable(mEnabledIconResourceId), null, null, null); 693 } 694 695 public void setSharedPrefId(int sharedPrefId) { 696 mSharedPrefResourceId = sharedPrefId; 697 698 if (mUnreadNotificationSwitch != null) { 699 700 Context context = mUnreadNotificationSwitch.getContext(); 701 String sharedPreferenceString = context.getString(mSharedPrefResourceId); 702 Boolean currentState = mSharedPref.getBoolean(sharedPreferenceString, true); 703 704 updateIcon(context, currentState); 705 } 706 } 707 708 private void updateIcon(Context context, Boolean currentState) { 709 int currentIconResourceId; 710 711 if (currentState) { 712 currentIconResourceId = mEnabledIconResourceId; 713 } else { 714 currentIconResourceId = mDisabledIconResourceId; 715 } 716 717 mUnreadNotificationSwitch.setChecked(currentState); 718 mUnreadNotificationSwitch.setCompoundDrawablesWithIntrinsicBounds( 719 context.getDrawable(currentIconResourceId), null, null, null); 720 } 721 722 @Override 723 public void onClick(View view) { 724 int position = getAdapterPosition(); 725 Log.d(TAG, "Complication onClick() position: " + position); 726 727 Context context = view.getContext(); 728 String sharedPreferenceString = context.getString(mSharedPrefResourceId); 729 730 // Since user clicked on a switch, new state should be opposite of current state. 731 Boolean newState = !mSharedPref.getBoolean(sharedPreferenceString, true); 732 733 SharedPreferences.Editor editor = mSharedPref.edit(); 734 editor.putBoolean(sharedPreferenceString, newState); 735 editor.apply(); 736 737 updateIcon(context, newState); 738 } 739 } 740 741 /** Displays button to trigger background image complication selector. */ 742 public class BackgroundComplicationViewHolder extends RecyclerView.ViewHolder 743 implements OnClickListener { 744 745 private Button mBackgroundComplicationButton; 746 747 public BackgroundComplicationViewHolder(View view) { 748 super(view); 749 750 mBackgroundComplicationButton = 751 (Button) view.findViewById(R.id.background_complication_button); 752 view.setOnClickListener(this); 753 } 754 755 public void setName(String name) { 756 mBackgroundComplicationButton.setText(name); 757 } 758 759 public void setIcon(int resourceId) { 760 Context context = mBackgroundComplicationButton.getContext(); 761 mBackgroundComplicationButton.setCompoundDrawablesWithIntrinsicBounds( 762 context.getDrawable(resourceId), null, null, null); 763 } 764 765 @Override 766 public void onClick(View view) { 767 int position = getAdapterPosition(); 768 Log.d(TAG, "Background Complication onClick() position: " + position); 769 770 Activity currentActivity = (Activity) view.getContext(); 771 772 mSelectedComplicationId = 773 AnalogComplicationWatchFaceService.getComplicationId( 774 ComplicationLocation.BACKGROUND); 775 776 if (mSelectedComplicationId >= 0) { 777 778 int[] supportedTypes = 779 AnalogComplicationWatchFaceService.getSupportedComplicationTypes( 780 ComplicationLocation.BACKGROUND); 781 782 ComponentName watchFace = 783 new ComponentName( 784 currentActivity, AnalogComplicationWatchFaceService.class); 785 786 currentActivity.startActivityForResult( 787 ComplicationHelperActivity.createProviderChooserHelperIntent( 788 currentActivity, 789 watchFace, 790 mSelectedComplicationId, 791 supportedTypes), 792 AnalogComplicationConfigActivity.COMPLICATION_CONFIG_REQUEST_CODE); 793 794 } else { 795 Log.d(TAG, "Complication not supported by watch face."); 796 } 797 } 798 } 799 } 800