1 /* 2 * Copyright (C) 2015 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.android.tv.onboarding; 18 19 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS; 20 21 import android.animation.Animator; 22 import android.animation.AnimatorInflater; 23 import android.animation.AnimatorListenerAdapter; 24 import android.animation.AnimatorSet; 25 import android.content.Context; 26 import android.os.Bundle; 27 import android.support.annotation.Nullable; 28 import androidx.leanback.app.OnboardingFragment; 29 import android.text.Editable; 30 import android.text.TextWatcher; 31 import android.view.Gravity; 32 import android.view.LayoutInflater; 33 import android.view.View; 34 import android.view.View.AccessibilityDelegate; 35 import android.view.ViewGroup; 36 import android.view.accessibility.AccessibilityEvent; 37 import android.view.accessibility.AccessibilityNodeInfo; 38 import android.widget.Button; 39 import android.widget.ImageView; 40 import android.widget.TextView; 41 import com.android.tv.R; 42 import com.android.tv.common.ui.setup.SetupActionHelper; 43 import com.android.tv.common.ui.setup.animation.SetupAnimationHelper; 44 import java.util.ArrayList; 45 import java.util.List; 46 47 /** A fragment for the onboarding welcome screen. */ 48 public class WelcomeFragment extends OnboardingFragment { 49 public static final String ACTION_CATEGORY = "com.android.tv.onboarding.WelcomeFragment"; 50 public static final int ACTION_NEXT = 1; 51 52 private static final long START_DELAY_CLOUD_MS = 33; 53 private static final long START_DELAY_TV_MS = 567; 54 private static final long START_DELAY_TV_CONTENTS_MS = 833; 55 private static final long START_DELAY_SHADOW_MS = 567; 56 57 private static final long VIDEO_FADE_OUT_DURATION_MS = 333; 58 59 private static final long BLUE_SCREEN_HOLD_DURATION_MS = 1500; 60 61 // TODO: Use animator list xml. 62 private static final int[] TV_FRAMES_1_START = { 63 R.drawable.tv_1a_01, 64 R.drawable.tv_1a_02, 65 R.drawable.tv_1a_03, 66 R.drawable.tv_1a_04, 67 R.drawable.tv_1a_05, 68 R.drawable.tv_1a_06, 69 R.drawable.tv_1a_07, 70 R.drawable.tv_1a_08, 71 R.drawable.tv_1a_09, 72 R.drawable.tv_1a_10, 73 R.drawable.tv_1a_11, 74 R.drawable.tv_1a_12, 75 R.drawable.tv_1a_13, 76 R.drawable.tv_1a_14, 77 R.drawable.tv_1a_15, 78 R.drawable.tv_1a_16, 79 R.drawable.tv_1a_17, 80 R.drawable.tv_1a_18, 81 R.drawable.tv_1a_19, 82 R.drawable.tv_1a_20 83 }; 84 85 private static final int[] TV_FRAMES_1_END = { 86 R.drawable.tv_1b_01, 87 R.drawable.tv_1b_02, 88 R.drawable.tv_1b_03, 89 R.drawable.tv_1b_04, 90 R.drawable.tv_1b_05, 91 R.drawable.tv_1b_06, 92 R.drawable.tv_1b_07, 93 R.drawable.tv_1b_08, 94 R.drawable.tv_1b_09, 95 R.drawable.tv_1b_10, 96 R.drawable.tv_1b_11 97 }; 98 99 private static final int[] TV_FRAMES_2_START = { 100 R.drawable.tv_5a_0, 101 R.drawable.tv_5a_1, 102 R.drawable.tv_5a_2, 103 R.drawable.tv_5a_3, 104 R.drawable.tv_5a_4, 105 R.drawable.tv_5a_5, 106 R.drawable.tv_5a_6, 107 R.drawable.tv_5a_7, 108 R.drawable.tv_5a_8, 109 R.drawable.tv_5a_9, 110 R.drawable.tv_5a_10, 111 R.drawable.tv_5a_11, 112 R.drawable.tv_5a_12, 113 R.drawable.tv_5a_13, 114 R.drawable.tv_5a_14, 115 R.drawable.tv_5a_15, 116 R.drawable.tv_5a_16, 117 R.drawable.tv_5a_17, 118 R.drawable.tv_5a_18, 119 R.drawable.tv_5a_19, 120 R.drawable.tv_5a_20, 121 R.drawable.tv_5a_21, 122 R.drawable.tv_5a_22, 123 R.drawable.tv_5a_23, 124 R.drawable.tv_5a_24, 125 R.drawable.tv_5a_25, 126 R.drawable.tv_5a_26, 127 R.drawable.tv_5a_27, 128 R.drawable.tv_5a_28, 129 R.drawable.tv_5a_29, 130 R.drawable.tv_5a_30, 131 R.drawable.tv_5a_31, 132 R.drawable.tv_5a_32, 133 R.drawable.tv_5a_33, 134 R.drawable.tv_5a_34, 135 R.drawable.tv_5a_35, 136 R.drawable.tv_5a_36, 137 R.drawable.tv_5a_37, 138 R.drawable.tv_5a_38, 139 R.drawable.tv_5a_39, 140 R.drawable.tv_5a_40, 141 R.drawable.tv_5a_41, 142 R.drawable.tv_5a_42, 143 R.drawable.tv_5a_43, 144 R.drawable.tv_5a_44, 145 R.drawable.tv_5a_45, 146 R.drawable.tv_5a_46, 147 R.drawable.tv_5a_47, 148 R.drawable.tv_5a_48, 149 R.drawable.tv_5a_49, 150 R.drawable.tv_5a_50, 151 R.drawable.tv_5a_51, 152 R.drawable.tv_5a_52, 153 R.drawable.tv_5a_53, 154 R.drawable.tv_5a_54, 155 R.drawable.tv_5a_55, 156 R.drawable.tv_5a_56, 157 R.drawable.tv_5a_57, 158 R.drawable.tv_5a_58, 159 R.drawable.tv_5a_59, 160 R.drawable.tv_5a_60, 161 R.drawable.tv_5a_61, 162 R.drawable.tv_5a_62, 163 R.drawable.tv_5a_63, 164 R.drawable.tv_5a_64, 165 R.drawable.tv_5a_65, 166 R.drawable.tv_5a_66, 167 R.drawable.tv_5a_67, 168 R.drawable.tv_5a_68, 169 R.drawable.tv_5a_69, 170 R.drawable.tv_5a_70, 171 R.drawable.tv_5a_71, 172 R.drawable.tv_5a_72, 173 R.drawable.tv_5a_73, 174 R.drawable.tv_5a_74, 175 R.drawable.tv_5a_75, 176 R.drawable.tv_5a_76, 177 R.drawable.tv_5a_77, 178 R.drawable.tv_5a_78, 179 R.drawable.tv_5a_79, 180 R.drawable.tv_5a_80, 181 R.drawable.tv_5a_81, 182 R.drawable.tv_5a_82, 183 R.drawable.tv_5a_83, 184 R.drawable.tv_5a_84, 185 R.drawable.tv_5a_85, 186 R.drawable.tv_5a_86, 187 R.drawable.tv_5a_87, 188 R.drawable.tv_5a_88, 189 R.drawable.tv_5a_89, 190 R.drawable.tv_5a_90, 191 R.drawable.tv_5a_91, 192 R.drawable.tv_5a_92, 193 R.drawable.tv_5a_93, 194 R.drawable.tv_5a_94, 195 R.drawable.tv_5a_95, 196 R.drawable.tv_5a_96, 197 R.drawable.tv_5a_97, 198 R.drawable.tv_5a_98, 199 R.drawable.tv_5a_99, 200 R.drawable.tv_5a_100, 201 R.drawable.tv_5a_101, 202 R.drawable.tv_5a_102, 203 R.drawable.tv_5a_103, 204 R.drawable.tv_5a_104, 205 R.drawable.tv_5a_105, 206 R.drawable.tv_5a_106, 207 R.drawable.tv_5a_107, 208 R.drawable.tv_5a_108, 209 R.drawable.tv_5a_109, 210 R.drawable.tv_5a_110, 211 R.drawable.tv_5a_111, 212 R.drawable.tv_5a_112, 213 R.drawable.tv_5a_113, 214 R.drawable.tv_5a_114, 215 R.drawable.tv_5a_115, 216 R.drawable.tv_5a_116, 217 R.drawable.tv_5a_117, 218 R.drawable.tv_5a_118, 219 R.drawable.tv_5a_119, 220 R.drawable.tv_5a_120, 221 R.drawable.tv_5a_121, 222 R.drawable.tv_5a_122, 223 R.drawable.tv_5a_123, 224 R.drawable.tv_5a_124, 225 R.drawable.tv_5a_125, 226 R.drawable.tv_5a_126, 227 R.drawable.tv_5a_127, 228 R.drawable.tv_5a_128, 229 R.drawable.tv_5a_129, 230 R.drawable.tv_5a_130, 231 R.drawable.tv_5a_131, 232 R.drawable.tv_5a_132, 233 R.drawable.tv_5a_133, 234 R.drawable.tv_5a_134, 235 R.drawable.tv_5a_135, 236 R.drawable.tv_5a_136, 237 R.drawable.tv_5a_137, 238 R.drawable.tv_5a_138, 239 R.drawable.tv_5a_139, 240 R.drawable.tv_5a_140, 241 R.drawable.tv_5a_141, 242 R.drawable.tv_5a_142, 243 R.drawable.tv_5a_143, 244 R.drawable.tv_5a_144, 245 R.drawable.tv_5a_145, 246 R.drawable.tv_5a_146, 247 R.drawable.tv_5a_147, 248 R.drawable.tv_5a_148, 249 R.drawable.tv_5a_149, 250 R.drawable.tv_5a_150, 251 R.drawable.tv_5a_151, 252 R.drawable.tv_5a_152, 253 R.drawable.tv_5a_153, 254 R.drawable.tv_5a_154, 255 R.drawable.tv_5a_155, 256 R.drawable.tv_5a_156, 257 R.drawable.tv_5a_157, 258 R.drawable.tv_5a_158, 259 R.drawable.tv_5a_159, 260 R.drawable.tv_5a_160, 261 R.drawable.tv_5a_161, 262 R.drawable.tv_5a_162, 263 R.drawable.tv_5a_163, 264 R.drawable.tv_5a_164, 265 R.drawable.tv_5a_165, 266 R.drawable.tv_5a_166, 267 R.drawable.tv_5a_167, 268 R.drawable.tv_5a_168, 269 R.drawable.tv_5a_169, 270 R.drawable.tv_5a_170, 271 R.drawable.tv_5a_171, 272 R.drawable.tv_5a_172, 273 R.drawable.tv_5a_173, 274 R.drawable.tv_5a_174, 275 R.drawable.tv_5a_175, 276 R.drawable.tv_5a_176, 277 R.drawable.tv_5a_177, 278 R.drawable.tv_5a_178, 279 R.drawable.tv_5a_179, 280 R.drawable.tv_5a_180, 281 R.drawable.tv_5a_181, 282 R.drawable.tv_5a_182, 283 R.drawable.tv_5a_183, 284 R.drawable.tv_5a_184, 285 R.drawable.tv_5a_185, 286 R.drawable.tv_5a_186, 287 R.drawable.tv_5a_187, 288 R.drawable.tv_5a_188, 289 R.drawable.tv_5a_189, 290 R.drawable.tv_5a_190, 291 R.drawable.tv_5a_191, 292 R.drawable.tv_5a_192, 293 R.drawable.tv_5a_193, 294 R.drawable.tv_5a_194, 295 R.drawable.tv_5a_195, 296 R.drawable.tv_5a_196, 297 R.drawable.tv_5a_197, 298 R.drawable.tv_5a_198, 299 R.drawable.tv_5a_199, 300 R.drawable.tv_5a_200, 301 R.drawable.tv_5a_201, 302 R.drawable.tv_5a_202, 303 R.drawable.tv_5a_203, 304 R.drawable.tv_5a_204, 305 R.drawable.tv_5a_205, 306 R.drawable.tv_5a_206, 307 R.drawable.tv_5a_207, 308 R.drawable.tv_5a_208, 309 R.drawable.tv_5a_209, 310 R.drawable.tv_5a_210, 311 R.drawable.tv_5a_211, 312 R.drawable.tv_5a_212, 313 R.drawable.tv_5a_213, 314 R.drawable.tv_5a_214, 315 R.drawable.tv_5a_215, 316 R.drawable.tv_5a_216, 317 R.drawable.tv_5a_217, 318 R.drawable.tv_5a_218, 319 R.drawable.tv_5a_219, 320 R.drawable.tv_5a_220, 321 R.drawable.tv_5a_221, 322 R.drawable.tv_5a_222, 323 R.drawable.tv_5a_223, 324 R.drawable.tv_5a_224 325 }; 326 327 private static final int[] TV_FRAMES_3_BLUE_ARROW = { 328 R.drawable.arrow_blue_00, 329 R.drawable.arrow_blue_01, 330 R.drawable.arrow_blue_02, 331 R.drawable.arrow_blue_03, 332 R.drawable.arrow_blue_04, 333 R.drawable.arrow_blue_05, 334 R.drawable.arrow_blue_06, 335 R.drawable.arrow_blue_07, 336 R.drawable.arrow_blue_08, 337 R.drawable.arrow_blue_09, 338 R.drawable.arrow_blue_10, 339 R.drawable.arrow_blue_11, 340 R.drawable.arrow_blue_12, 341 R.drawable.arrow_blue_13, 342 R.drawable.arrow_blue_14, 343 R.drawable.arrow_blue_15, 344 R.drawable.arrow_blue_16, 345 R.drawable.arrow_blue_17, 346 R.drawable.arrow_blue_18, 347 R.drawable.arrow_blue_19, 348 R.drawable.arrow_blue_20, 349 R.drawable.arrow_blue_21, 350 R.drawable.arrow_blue_22, 351 R.drawable.arrow_blue_23, 352 R.drawable.arrow_blue_24, 353 R.drawable.arrow_blue_25, 354 R.drawable.arrow_blue_26, 355 R.drawable.arrow_blue_27, 356 R.drawable.arrow_blue_28, 357 R.drawable.arrow_blue_29, 358 R.drawable.arrow_blue_30, 359 R.drawable.arrow_blue_31, 360 R.drawable.arrow_blue_32, 361 R.drawable.arrow_blue_33, 362 R.drawable.arrow_blue_34, 363 R.drawable.arrow_blue_35, 364 R.drawable.arrow_blue_36, 365 R.drawable.arrow_blue_37, 366 R.drawable.arrow_blue_38, 367 R.drawable.arrow_blue_39, 368 R.drawable.arrow_blue_40, 369 R.drawable.arrow_blue_41, 370 R.drawable.arrow_blue_42, 371 R.drawable.arrow_blue_43, 372 R.drawable.arrow_blue_44, 373 R.drawable.arrow_blue_45, 374 R.drawable.arrow_blue_46, 375 R.drawable.arrow_blue_47, 376 R.drawable.arrow_blue_48, 377 R.drawable.arrow_blue_49, 378 R.drawable.arrow_blue_50, 379 R.drawable.arrow_blue_51, 380 R.drawable.arrow_blue_52, 381 R.drawable.arrow_blue_53, 382 R.drawable.arrow_blue_54, 383 R.drawable.arrow_blue_55, 384 R.drawable.arrow_blue_56, 385 R.drawable.arrow_blue_57, 386 R.drawable.arrow_blue_58, 387 R.drawable.arrow_blue_59, 388 R.drawable.arrow_blue_60 389 }; 390 391 private static final int[] TV_FRAMES_3_BLUE_START = { 392 R.drawable.tv_2a_01, 393 R.drawable.tv_2a_02, 394 R.drawable.tv_2a_03, 395 R.drawable.tv_2a_04, 396 R.drawable.tv_2a_05, 397 R.drawable.tv_2a_06, 398 R.drawable.tv_2a_07, 399 R.drawable.tv_2a_08, 400 R.drawable.tv_2a_09, 401 R.drawable.tv_2a_10, 402 R.drawable.tv_2a_11, 403 R.drawable.tv_2a_12, 404 R.drawable.tv_2a_13, 405 R.drawable.tv_2a_14, 406 R.drawable.tv_2a_15, 407 R.drawable.tv_2a_16, 408 R.drawable.tv_2a_17, 409 R.drawable.tv_2a_18, 410 R.drawable.tv_2a_19 411 }; 412 413 private static final int[] TV_FRAMES_3_BLUE_END = { 414 R.drawable.tv_2b_01, 415 R.drawable.tv_2b_02, 416 R.drawable.tv_2b_03, 417 R.drawable.tv_2b_04, 418 R.drawable.tv_2b_05, 419 R.drawable.tv_2b_06, 420 R.drawable.tv_2b_07, 421 R.drawable.tv_2b_08, 422 R.drawable.tv_2b_09, 423 R.drawable.tv_2b_10, 424 R.drawable.tv_2b_11, 425 R.drawable.tv_2b_12, 426 R.drawable.tv_2b_13, 427 R.drawable.tv_2b_14, 428 R.drawable.tv_2b_15, 429 R.drawable.tv_2b_16, 430 R.drawable.tv_2b_17, 431 R.drawable.tv_2b_18, 432 R.drawable.tv_2b_19 433 }; 434 435 private static final int[] TV_FRAMES_3_ORANGE_ARROW = { 436 R.drawable.arrow_orange_180, 437 R.drawable.arrow_orange_181, 438 R.drawable.arrow_orange_182, 439 R.drawable.arrow_orange_183, 440 R.drawable.arrow_orange_184, 441 R.drawable.arrow_orange_185, 442 R.drawable.arrow_orange_186, 443 R.drawable.arrow_orange_187, 444 R.drawable.arrow_orange_188, 445 R.drawable.arrow_orange_189, 446 R.drawable.arrow_orange_190, 447 R.drawable.arrow_orange_191, 448 R.drawable.arrow_orange_192, 449 R.drawable.arrow_orange_193, 450 R.drawable.arrow_orange_194, 451 R.drawable.arrow_orange_195, 452 R.drawable.arrow_orange_196, 453 R.drawable.arrow_orange_197, 454 R.drawable.arrow_orange_198, 455 R.drawable.arrow_orange_199, 456 R.drawable.arrow_orange_200, 457 R.drawable.arrow_orange_201, 458 R.drawable.arrow_orange_202, 459 R.drawable.arrow_orange_203, 460 R.drawable.arrow_orange_204, 461 R.drawable.arrow_orange_205, 462 R.drawable.arrow_orange_206, 463 R.drawable.arrow_orange_207, 464 R.drawable.arrow_orange_208, 465 R.drawable.arrow_orange_209, 466 R.drawable.arrow_orange_210, 467 R.drawable.arrow_orange_211, 468 R.drawable.arrow_orange_212, 469 R.drawable.arrow_orange_213, 470 R.drawable.arrow_orange_214, 471 R.drawable.arrow_orange_215, 472 R.drawable.arrow_orange_216, 473 R.drawable.arrow_orange_217, 474 R.drawable.arrow_orange_218, 475 R.drawable.arrow_orange_219, 476 R.drawable.arrow_orange_220, 477 R.drawable.arrow_orange_221, 478 R.drawable.arrow_orange_222, 479 R.drawable.arrow_orange_223, 480 R.drawable.arrow_orange_224, 481 R.drawable.arrow_orange_225, 482 R.drawable.arrow_orange_226, 483 R.drawable.arrow_orange_227, 484 R.drawable.arrow_orange_228, 485 R.drawable.arrow_orange_229, 486 R.drawable.arrow_orange_230, 487 R.drawable.arrow_orange_231, 488 R.drawable.arrow_orange_232, 489 R.drawable.arrow_orange_233, 490 R.drawable.arrow_orange_234, 491 R.drawable.arrow_orange_235, 492 R.drawable.arrow_orange_236, 493 R.drawable.arrow_orange_237, 494 R.drawable.arrow_orange_238, 495 R.drawable.arrow_orange_239, 496 R.drawable.arrow_orange_240 497 }; 498 499 private static final int[] TV_FRAMES_3_ORANGE_START = { 500 R.drawable.tv_2c_01, 501 R.drawable.tv_2c_02, 502 R.drawable.tv_2c_03, 503 R.drawable.tv_2c_04, 504 R.drawable.tv_2c_05, 505 R.drawable.tv_2c_06, 506 R.drawable.tv_2c_07, 507 R.drawable.tv_2c_08, 508 R.drawable.tv_2c_09, 509 R.drawable.tv_2c_10, 510 R.drawable.tv_2c_11, 511 R.drawable.tv_2c_12, 512 R.drawable.tv_2c_13, 513 R.drawable.tv_2c_14, 514 R.drawable.tv_2c_15, 515 R.drawable.tv_2c_16 516 }; 517 518 private static final int[] TV_FRAMES_4_START = { 519 R.drawable.tv_3a_01, 520 R.drawable.tv_3a_02, 521 R.drawable.tv_3a_03, 522 R.drawable.tv_3a_04, 523 R.drawable.tv_3a_05, 524 R.drawable.tv_3a_06, 525 R.drawable.tv_3a_07, 526 R.drawable.tv_3a_08, 527 R.drawable.tv_3a_09, 528 R.drawable.tv_3a_10, 529 R.drawable.tv_3a_11, 530 R.drawable.tv_3a_12, 531 R.drawable.tv_3a_13, 532 R.drawable.tv_3a_14, 533 R.drawable.tv_3a_15, 534 R.drawable.tv_3a_16, 535 R.drawable.tv_3a_17, 536 R.drawable.tv_3b_75, 537 R.drawable.tv_3b_76, 538 R.drawable.tv_3b_77, 539 R.drawable.tv_3b_78, 540 R.drawable.tv_3b_79, 541 R.drawable.tv_3b_80, 542 R.drawable.tv_3b_81, 543 R.drawable.tv_3b_82, 544 R.drawable.tv_3b_83, 545 R.drawable.tv_3b_84, 546 R.drawable.tv_3b_85, 547 R.drawable.tv_3b_86, 548 R.drawable.tv_3b_87, 549 R.drawable.tv_3b_88, 550 R.drawable.tv_3b_89, 551 R.drawable.tv_3b_90, 552 R.drawable.tv_3b_91, 553 R.drawable.tv_3b_92, 554 R.drawable.tv_3b_93, 555 R.drawable.tv_3b_94, 556 R.drawable.tv_3b_95, 557 R.drawable.tv_3b_96, 558 R.drawable.tv_3b_97, 559 R.drawable.tv_3b_98, 560 R.drawable.tv_3b_99, 561 R.drawable.tv_3b_100, 562 R.drawable.tv_3b_101, 563 R.drawable.tv_3b_102, 564 R.drawable.tv_3b_103, 565 R.drawable.tv_3b_104, 566 R.drawable.tv_3b_105, 567 R.drawable.tv_3b_106, 568 R.drawable.tv_3b_107, 569 R.drawable.tv_3b_108, 570 R.drawable.tv_3b_109, 571 R.drawable.tv_3b_110, 572 R.drawable.tv_3b_111, 573 R.drawable.tv_3b_112, 574 R.drawable.tv_3b_113, 575 R.drawable.tv_3b_114, 576 R.drawable.tv_3b_115, 577 R.drawable.tv_3b_116, 578 R.drawable.tv_3b_117, 579 R.drawable.tv_3b_118 580 }; 581 582 private String[] mPageTitles; 583 private String[] mPageDescriptions; 584 585 private ImageView mTvContentView; 586 private ImageView mArrowView; 587 588 private TextView mTitleView; 589 private Button mStartButton; 590 private View mPagingIndicator; 591 592 private Animator mAnimator; 593 594 private boolean mLogoAnimationFinished; 595 private boolean mTitleChanged; 596 WelcomeFragment()597 public WelcomeFragment() { 598 setExitTransition( 599 new SetupAnimationHelper.TransitionBuilder() 600 .setSlideEdge(Gravity.START) 601 .setParentIdsForDelay(new int[] {R.id.onboarding_fragment_root}) 602 .build()); 603 } 604 605 @Override onAttach(Context context)606 public void onAttach(Context context) { 607 super.onAttach(context); 608 initialize(); 609 } 610 initialize()611 private void initialize() { 612 if (mPageTitles == null) { 613 mPageTitles = getResources().getStringArray(R.array.welcome_page_titles); 614 mPageDescriptions = getResources().getStringArray(R.array.welcome_page_descriptions); 615 } 616 } 617 618 @Nullable 619 @Override onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)620 public View onCreateView( 621 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 622 View view = super.onCreateView(inflater, container, savedInstanceState); 623 setLogoResourceId(R.drawable.splash_logo); 624 mTitleView = view.findViewById(androidx.leanback.R.id.title); 625 mPagingIndicator = view.findViewById(androidx.leanback.R.id.page_indicator); 626 mStartButton = view.findViewById(androidx.leanback.R.id.button_start); 627 628 mStartButton.setAccessibilityDelegate( 629 new AccessibilityDelegate() { 630 @Override 631 public void onInitializeAccessibilityEvent( 632 View host, AccessibilityEvent event) { 633 int type = event.getEventType(); 634 if (type == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED 635 || type == AccessibilityEvent.TYPE_VIEW_FOCUSED) { 636 if (!mTitleChanged || mTitleView.isAccessibilityFocused()) { 637 // Skip the event before the title is accessibility focused to avoid 638 // race 639 // conditions 640 return; 641 } 642 } 643 super.onInitializeAccessibilityEvent(host, event); 644 } 645 }); 646 647 mPagingIndicator.setAccessibilityDelegate( 648 new AccessibilityDelegate() { 649 @Override 650 public void onInitializeAccessibilityEvent( 651 View host, AccessibilityEvent event) { 652 int type = event.getEventType(); 653 if (type == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED 654 || type == AccessibilityEvent.TYPE_VIEW_FOCUSED) { 655 if (!mTitleChanged || mTitleView.isAccessibilityFocused()) { 656 // Skip the event before the title is accessibility focused to avoid 657 // race 658 // conditions 659 return; 660 } 661 } 662 super.onInitializeAccessibilityEvent(host, event); 663 } 664 }); 665 666 mTitleView.setAccessibilityDelegate( 667 new AccessibilityDelegate() { 668 @Override 669 public boolean performAccessibilityAction(View host, int action, Bundle args) { 670 if (action == ACTION_CLEAR_ACCESSIBILITY_FOCUS) { 671 if (!mTitleChanged || mTitleView.isAccessibilityFocused()) { 672 // Skip the event before the title is accessibility focused to avoid 673 // race 674 // conditions 675 return false; 676 } 677 } 678 return super.performAccessibilityAction(host, action, args); 679 } 680 }); 681 682 mTitleView.addTextChangedListener( 683 new TextWatcher() { 684 @Override 685 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 686 mTitleChanged = false; 687 } 688 689 @Override 690 public void onTextChanged(CharSequence s, int start, int before, int count) {} 691 692 @Override 693 public void afterTextChanged(Editable s) { 694 if (!mTitleView.isAccessibilityFocused()) { 695 mTitleView.performAccessibilityAction( 696 AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null); 697 } else { 698 mTitleView.sendAccessibilityEvent( 699 AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED); 700 } 701 mTitleChanged = true; 702 } 703 }); 704 return view; 705 } 706 707 @Override onViewCreated(View view, Bundle savedInstanceState)708 public void onViewCreated(View view, Bundle savedInstanceState) { 709 super.onViewCreated(view, savedInstanceState); 710 if (savedInstanceState != null && mLogoAnimationFinished) { 711 switch (getCurrentPageIndex()) { 712 case 0: 713 mTvContentView.setImageResource( 714 TV_FRAMES_1_START[TV_FRAMES_1_START.length - 1]); 715 break; 716 case 1: 717 mTvContentView.setImageResource( 718 TV_FRAMES_2_START[TV_FRAMES_2_START.length - 1]); 719 break; 720 case 2: 721 mTvContentView.setImageResource( 722 TV_FRAMES_3_ORANGE_START[TV_FRAMES_3_ORANGE_START.length - 1]); 723 mArrowView.setImageResource(TV_FRAMES_3_BLUE_ARROW[0]); 724 break; 725 case 3: 726 default: 727 mTvContentView.setImageResource( 728 TV_FRAMES_4_START[TV_FRAMES_4_START.length - 1]); 729 break; 730 } 731 } 732 } 733 734 @Override onProvideTheme()735 public int onProvideTheme() { 736 return R.style.Theme_Leanback_Onboarding; 737 } 738 739 @Override onLogoAnimationFinished()740 protected void onLogoAnimationFinished() { 741 super.onLogoAnimationFinished(); 742 mLogoAnimationFinished = true; 743 } 744 745 @Override onCreateEnterAnimation()746 protected Animator onCreateEnterAnimation() { 747 List<Animator> animators = new ArrayList<>(); 748 // Cloud 1 749 View view = getActivity().findViewById(R.id.cloud1); 750 view.setAlpha(0); 751 Animator animator = 752 AnimatorInflater.loadAnimator( 753 getActivity(), R.animator.onboarding_welcome_cloud_enter); 754 animator.setStartDelay(START_DELAY_CLOUD_MS); 755 animator.setTarget(view); 756 animators.add(animator); 757 // Cloud 2 758 view = getActivity().findViewById(R.id.cloud2); 759 view.setAlpha(0); 760 animator = 761 AnimatorInflater.loadAnimator( 762 getActivity(), R.animator.onboarding_welcome_cloud_enter); 763 animator.setStartDelay(START_DELAY_CLOUD_MS); 764 animator.setTarget(view); 765 animators.add(animator); 766 // TV container 767 view = getActivity().findViewById(R.id.tv_container); 768 view.setAlpha(0); 769 animator = 770 AnimatorInflater.loadAnimator( 771 getActivity(), R.animator.onboarding_welcome_tv_enter); 772 animator.setStartDelay(START_DELAY_TV_MS); 773 animator.setTarget(view); 774 animators.add(animator); 775 // TV content 776 view = getActivity().findViewById(R.id.tv_content); 777 animator = SetupAnimationHelper.createFrameAnimator((ImageView) view, TV_FRAMES_1_START); 778 animator.setStartDelay(START_DELAY_TV_CONTENTS_MS); 779 animator.setTarget(view); 780 animators.add(animator); 781 // Shadow 782 view = getActivity().findViewById(R.id.shadow); 783 view.setAlpha(0); 784 animator = 785 AnimatorInflater.loadAnimator( 786 getActivity(), R.animator.onboarding_welcome_shadow_enter); 787 animator.setStartDelay(START_DELAY_SHADOW_MS); 788 animator.setTarget(view); 789 animators.add(animator); 790 AnimatorSet set = new AnimatorSet(); 791 set.playTogether(animators); 792 return set; 793 } 794 795 @Nullable 796 @Override onCreateBackgroundView(LayoutInflater inflater, ViewGroup container)797 protected View onCreateBackgroundView(LayoutInflater inflater, ViewGroup container) { 798 return inflater.inflate(R.layout.onboarding_welcome_background, container, false); 799 } 800 801 @Nullable 802 @Override onCreateContentView(LayoutInflater inflater, ViewGroup container)803 protected View onCreateContentView(LayoutInflater inflater, ViewGroup container) { 804 View view = inflater.inflate(R.layout.onboarding_welcome_content, container, false); 805 mTvContentView = (ImageView) view.findViewById(R.id.tv_content); 806 return view; 807 } 808 809 @Nullable 810 @Override onCreateForegroundView(LayoutInflater inflater, ViewGroup container)811 protected View onCreateForegroundView(LayoutInflater inflater, ViewGroup container) { 812 mArrowView = 813 (ImageView) 814 inflater.inflate(R.layout.onboarding_welcome_foreground, container, false); 815 return mArrowView; 816 } 817 818 @Override getPageCount()819 protected int getPageCount() { 820 return mPageTitles.length; 821 } 822 823 @Override getPageTitle(int pageIndex)824 protected String getPageTitle(int pageIndex) { 825 return mPageTitles[pageIndex]; 826 } 827 828 @Override getPageDescription(int pageIndex)829 protected String getPageDescription(int pageIndex) { 830 return mPageDescriptions[pageIndex]; 831 } 832 833 @Override onFinishFragment()834 protected void onFinishFragment() { 835 SetupActionHelper.onActionClick(WelcomeFragment.this, ACTION_CATEGORY, ACTION_NEXT); 836 } 837 838 @Override onPageChanged(int newPage, int previousPage)839 protected void onPageChanged(int newPage, int previousPage) { 840 if (mAnimator != null) { 841 mAnimator.cancel(); 842 } 843 mTitleChanged = false; 844 mArrowView.setVisibility(View.GONE); 845 // TV screen hiding animator. 846 Animator hideAnimator = 847 previousPage == 0 848 ? SetupAnimationHelper.createFrameAnimator(mTvContentView, TV_FRAMES_1_END) 849 : SetupAnimationHelper.createFadeOutAnimator( 850 mTvContentView, VIDEO_FADE_OUT_DURATION_MS, true); 851 // TV screen showing animator. 852 AnimatorSet animatorSet = new AnimatorSet(); 853 int firstFrame; 854 switch (newPage) { 855 case 0: 856 animatorSet.playSequentially( 857 hideAnimator, 858 SetupAnimationHelper.createFrameAnimator( 859 mTvContentView, TV_FRAMES_1_START)); 860 firstFrame = TV_FRAMES_1_START[0]; 861 break; 862 case 1: 863 animatorSet.playSequentially( 864 hideAnimator, 865 SetupAnimationHelper.createFrameAnimator( 866 mTvContentView, TV_FRAMES_2_START)); 867 firstFrame = TV_FRAMES_2_START[0]; 868 break; 869 case 2: 870 mArrowView.setVisibility(View.VISIBLE); 871 animatorSet.playSequentially( 872 hideAnimator, 873 SetupAnimationHelper.createFrameAnimator( 874 mArrowView, TV_FRAMES_3_BLUE_ARROW), 875 SetupAnimationHelper.createFrameAnimator( 876 mTvContentView, TV_FRAMES_3_BLUE_START), 877 SetupAnimationHelper.createFrameAnimatorWithDelay( 878 mTvContentView, TV_FRAMES_3_BLUE_END, BLUE_SCREEN_HOLD_DURATION_MS), 879 SetupAnimationHelper.createFrameAnimator( 880 mArrowView, TV_FRAMES_3_ORANGE_ARROW), 881 SetupAnimationHelper.createFrameAnimator( 882 mTvContentView, TV_FRAMES_3_ORANGE_START)); 883 animatorSet.addListener( 884 new AnimatorListenerAdapter() { 885 @Override 886 public void onAnimationEnd(Animator animation) { 887 mArrowView.setImageResource(TV_FRAMES_3_BLUE_ARROW[0]); 888 } 889 }); 890 firstFrame = TV_FRAMES_3_BLUE_START[0]; 891 break; 892 case 3: 893 default: 894 animatorSet.playSequentially( 895 hideAnimator, 896 SetupAnimationHelper.createFrameAnimator( 897 mTvContentView, TV_FRAMES_4_START)); 898 firstFrame = TV_FRAMES_4_START[0]; 899 break; 900 } 901 final int firstImageResource = firstFrame; 902 hideAnimator.addListener( 903 new AnimatorListenerAdapter() { 904 @Override 905 public void onAnimationEnd(Animator animation) { 906 // Shows the first frame of show animation when the hide animator is 907 // canceled. 908 mTvContentView.setImageResource(firstImageResource); 909 } 910 }); 911 mAnimator = SetupAnimationHelper.applyAnimationTimeScale(animatorSet); 912 mAnimator.start(); 913 } 914 } 915