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 if (complicationProviderInfo != null) { 522 mLeftComplication.setImageIcon(complicationProviderInfo.providerIcon); 523 mLeftComplicationBackground.setVisibility(View.VISIBLE); 524 525 } else { 526 mLeftComplication.setImageDrawable(mDefaultComplicationDrawable); 527 mLeftComplicationBackground.setVisibility(View.INVISIBLE); 528 } 529 530 } else if (watchFaceComplicationId == mRightComplicationId) { 531 if (complicationProviderInfo != null) { 532 mRightComplication.setImageIcon(complicationProviderInfo.providerIcon); 533 mRightComplicationBackground.setVisibility(View.VISIBLE); 534 535 } else { 536 mRightComplication.setImageDrawable(mDefaultComplicationDrawable); 537 mRightComplicationBackground.setVisibility(View.INVISIBLE); 538 } 539 } 540 } 541 542 public void initializesColorsAndComplications() { 543 544 // Initializes highlight color (just second arm and part of complications). 545 String highlightSharedPrefString = mContext.getString(R.string.saved_marker_color); 546 int currentHighlightColor = mSharedPref.getInt(highlightSharedPrefString, Color.RED); 547 548 PorterDuffColorFilter highlightColorFilter = 549 new PorterDuffColorFilter(currentHighlightColor, PorterDuff.Mode.SRC_ATOP); 550 551 mWatchFaceHighlightPreviewView.getBackground().setColorFilter(highlightColorFilter); 552 553 // Initializes background color to gray (updates to color or complication icon based 554 // on whether the background complication is live or not. 555 PorterDuffColorFilter backgroundColorFilter = 556 new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP); 557 558 mWatchFaceBackgroundPreviewImageView 559 .getBackground() 560 .setColorFilter(backgroundColorFilter); 561 562 final int[] complicationIds = AnalogComplicationWatchFaceService.getComplicationIds(); 563 564 mProviderInfoRetriever.retrieveProviderInfo( 565 new OnProviderInfoReceivedCallback() { 566 @Override 567 public void onProviderInfoReceived( 568 int watchFaceComplicationId, 569 @Nullable ComplicationProviderInfo complicationProviderInfo) { 570 571 Log.d(TAG, "onProviderInfoReceived: " + complicationProviderInfo); 572 573 updateComplicationViews( 574 watchFaceComplicationId, complicationProviderInfo); 575 } 576 }, 577 mWatchFaceComponentName, 578 complicationIds); 579 } 580 } 581 582 /** Displays icon to indicate there are more options below the fold. */ 583 public class MoreOptionsViewHolder extends RecyclerView.ViewHolder { 584 585 private ImageView mMoreOptionsImageView; 586 587 public MoreOptionsViewHolder(View view) { 588 super(view); 589 mMoreOptionsImageView = (ImageView) view.findViewById(R.id.more_options_image_view); 590 } 591 592 public void setIcon(int resourceId) { 593 Context context = mMoreOptionsImageView.getContext(); 594 mMoreOptionsImageView.setImageDrawable(context.getDrawable(resourceId)); 595 } 596 } 597 598 /** 599 * Displays color options for the an item on the watch face. These could include marker color, 600 * background color, etc. 601 */ 602 public class ColorPickerViewHolder extends RecyclerView.ViewHolder implements OnClickListener { 603 604 private Button mAppearanceButton; 605 606 private String mSharedPrefResourceString; 607 608 private Class<ColorSelectionActivity> mLaunchActivityToSelectColor; 609 610 public ColorPickerViewHolder(View view) { 611 super(view); 612 613 mAppearanceButton = (Button) view.findViewById(R.id.color_picker_button); 614 view.setOnClickListener(this); 615 } 616 617 public void setName(String name) { 618 mAppearanceButton.setText(name); 619 } 620 621 public void setIcon(int resourceId) { 622 Context context = mAppearanceButton.getContext(); 623 mAppearanceButton.setCompoundDrawablesWithIntrinsicBounds( 624 context.getDrawable(resourceId), null, null, null); 625 } 626 627 public void setSharedPrefString(String sharedPrefString) { 628 mSharedPrefResourceString = sharedPrefString; 629 } 630 631 public void setLaunchActivityToSelectColor(Class<ColorSelectionActivity> activity) { 632 mLaunchActivityToSelectColor = activity; 633 } 634 635 @Override 636 public void onClick(View view) { 637 int position = getAdapterPosition(); 638 Log.d(TAG, "Complication onClick() position: " + position); 639 640 if (mLaunchActivityToSelectColor != null) { 641 Intent launchIntent = new Intent(view.getContext(), mLaunchActivityToSelectColor); 642 643 // Pass shared preference name to save color value to. 644 launchIntent.putExtra(EXTRA_SHARED_PREF, mSharedPrefResourceString); 645 646 Activity activity = (Activity) view.getContext(); 647 activity.startActivityForResult( 648 launchIntent, 649 AnalogComplicationConfigActivity.UPDATE_COLORS_CONFIG_REQUEST_CODE); 650 } 651 } 652 } 653 654 /** 655 * Displays switch to indicate whether or not icon appears for unread notifications. User can 656 * toggle on/off. 657 */ 658 public class UnreadNotificationViewHolder extends RecyclerView.ViewHolder 659 implements OnClickListener { 660 661 private Switch mUnreadNotificationSwitch; 662 663 private int mEnabledIconResourceId; 664 private int mDisabledIconResourceId; 665 666 private int mSharedPrefResourceId; 667 668 public UnreadNotificationViewHolder(View view) { 669 super(view); 670 671 mUnreadNotificationSwitch = (Switch) view.findViewById(R.id.unread_notification_switch); 672 view.setOnClickListener(this); 673 } 674 675 public void setName(String name) { 676 mUnreadNotificationSwitch.setText(name); 677 } 678 679 public void setIcons(int enabledIconResourceId, int disabledIconResourceId) { 680 681 mEnabledIconResourceId = enabledIconResourceId; 682 mDisabledIconResourceId = disabledIconResourceId; 683 684 Context context = mUnreadNotificationSwitch.getContext(); 685 686 // Set default to enabled. 687 mUnreadNotificationSwitch.setCompoundDrawablesWithIntrinsicBounds( 688 context.getDrawable(mEnabledIconResourceId), null, null, null); 689 } 690 691 public void setSharedPrefId(int sharedPrefId) { 692 mSharedPrefResourceId = sharedPrefId; 693 694 if (mUnreadNotificationSwitch != null) { 695 696 Context context = mUnreadNotificationSwitch.getContext(); 697 String sharedPreferenceString = context.getString(mSharedPrefResourceId); 698 Boolean currentState = mSharedPref.getBoolean(sharedPreferenceString, true); 699 700 updateIcon(context, currentState); 701 } 702 } 703 704 private void updateIcon(Context context, Boolean currentState) { 705 int currentIconResourceId; 706 707 if (currentState) { 708 currentIconResourceId = mEnabledIconResourceId; 709 } else { 710 currentIconResourceId = mDisabledIconResourceId; 711 } 712 713 mUnreadNotificationSwitch.setChecked(currentState); 714 mUnreadNotificationSwitch.setCompoundDrawablesWithIntrinsicBounds( 715 context.getDrawable(currentIconResourceId), null, null, null); 716 } 717 718 @Override 719 public void onClick(View view) { 720 int position = getAdapterPosition(); 721 Log.d(TAG, "Complication onClick() position: " + position); 722 723 Context context = view.getContext(); 724 String sharedPreferenceString = context.getString(mSharedPrefResourceId); 725 726 // Since user clicked on a switch, new state should be opposite of current state. 727 Boolean newState = !mSharedPref.getBoolean(sharedPreferenceString, true); 728 729 SharedPreferences.Editor editor = mSharedPref.edit(); 730 editor.putBoolean(sharedPreferenceString, newState); 731 editor.apply(); 732 733 updateIcon(context, newState); 734 } 735 } 736 737 /** Displays button to trigger background image complication selector. */ 738 public class BackgroundComplicationViewHolder extends RecyclerView.ViewHolder 739 implements OnClickListener { 740 741 private Button mBackgroundComplicationButton; 742 743 public BackgroundComplicationViewHolder(View view) { 744 super(view); 745 746 mBackgroundComplicationButton = 747 (Button) view.findViewById(R.id.background_complication_button); 748 view.setOnClickListener(this); 749 } 750 751 public void setName(String name) { 752 mBackgroundComplicationButton.setText(name); 753 } 754 755 public void setIcon(int resourceId) { 756 Context context = mBackgroundComplicationButton.getContext(); 757 mBackgroundComplicationButton.setCompoundDrawablesWithIntrinsicBounds( 758 context.getDrawable(resourceId), null, null, null); 759 } 760 761 @Override 762 public void onClick(View view) { 763 int position = getAdapterPosition(); 764 Log.d(TAG, "Background Complication onClick() position: " + position); 765 766 Activity currentActivity = (Activity) view.getContext(); 767 768 mSelectedComplicationId = 769 AnalogComplicationWatchFaceService.getComplicationId( 770 ComplicationLocation.BACKGROUND); 771 772 if (mSelectedComplicationId >= 0) { 773 774 int[] supportedTypes = 775 AnalogComplicationWatchFaceService.getSupportedComplicationTypes( 776 ComplicationLocation.BACKGROUND); 777 778 ComponentName watchFace = 779 new ComponentName( 780 currentActivity, AnalogComplicationWatchFaceService.class); 781 782 currentActivity.startActivityForResult( 783 ComplicationHelperActivity.createProviderChooserHelperIntent( 784 currentActivity, 785 watchFace, 786 mSelectedComplicationId, 787 supportedTypes), 788 AnalogComplicationConfigActivity.COMPLICATION_CONFIG_REQUEST_CODE); 789 790 } else { 791 Log.d(TAG, "Complication not supported by watch face."); 792 } 793 } 794 } 795 } 796