GuidedStepSupportActivity.java revision 20767a171ab46addb5d50248d4267db14c0c8883
1/* This file is auto-generated from GuidedStepActivity.java. DO NOT MODIFY. */ 2 3/* 4 * Copyright (C) 2014 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19package com.example.android.leanback; 20 21import android.support.v4.app.FragmentActivity; 22import android.support.v4.app.FragmentManager; 23import android.content.Context; 24import android.content.Intent; 25import android.content.res.Configuration; 26import android.graphics.drawable.Drawable; 27import android.os.Bundle; 28import android.support.v17.leanback.app.GuidedStepSupportFragment; 29import android.support.v17.leanback.widget.GuidanceStylist; 30import android.support.v17.leanback.widget.GuidanceStylist.Guidance; 31import android.support.v17.leanback.widget.GuidedAction; 32import android.support.v17.leanback.widget.GuidedActionsStylist; 33import android.support.v17.leanback.widget.GuidedActionsStylist.ViewHolder; 34import android.support.v17.leanback.widget.GuidedDatePickerAction; 35import android.text.InputType; 36import android.text.TextUtils; 37import android.util.Log; 38import android.view.ViewGroup; 39import android.view.ViewTreeObserver.OnGlobalLayoutListener; 40import android.view.inputmethod.EditorInfo; 41 42import java.util.ArrayList; 43import java.util.Calendar; 44import java.util.List; 45 46/** 47 * Activity that showcases different aspects of GuidedStepSupportFragments. 48 */ 49public class GuidedStepSupportActivity extends FragmentActivity { 50 51 private static final int BACK = 2; 52 53 private static final int FIRST_NAME = 3; 54 private static final int LAST_NAME = 4; 55 private static final int PASSWORD = 5; 56 private static final int PAYMENT = 6; 57 private static final int NEW_PAYMENT = 7; 58 private static final int PAYMENT_EXPIRE = 8; 59 60 private static final int OPTION_CHECK_SET_ID = 10; 61 private static final int DEFAULT_OPTION = 0; 62 private static final String[] OPTION_NAMES = { "Option A", "Option B", "Option C" }; 63 private static final String[] OPTION_DESCRIPTIONS = { "Here's one thing you can do", 64 "Here's another thing you can do", "Here's one more thing you can do" }; 65 66 private static final String TAG = GuidedStepSupportActivity.class.getSimpleName(); 67 68 @Override 69 protected void onCreate(Bundle savedInstanceState) { 70 Log.v(TAG, "onCreate"); 71 super.onCreate(savedInstanceState); 72 setContentView(R.layout.guided_step_activity); 73 GuidedStepSupportFragment.addAsRoot(this, new FirstStepFragment(), R.id.lb_guidedstep_host); 74 } 75 76 @Override 77 public void onConfigurationChanged(Configuration newConfig) { 78 Log.v(TAG, "onConfigurationChanged"); 79 super.onConfigurationChanged(newConfig); 80 } 81 82 @Override 83 protected void onSaveInstanceState(Bundle outState) { 84 Log.v(TAG, "onSaveInstanceState"); 85 super.onSaveInstanceState(outState); 86 } 87 88 @Override 89 protected void onRestoreInstanceState(Bundle savedInstanceState) { 90 Log.v(TAG, "onRestoreInstanceState"); 91 super.onRestoreInstanceState(savedInstanceState); 92 } 93 94 private static void addAction(List<GuidedAction> actions, long id, String title, String desc) { 95 actions.add(new GuidedAction.Builder() 96 .id(id) 97 .title(title) 98 .description(desc) 99 .build()); 100 } 101 102 private static void addAction(List<GuidedAction> actions, long id, String title, String desc, 103 List<GuidedAction> subActions) { 104 actions.add(new GuidedAction.Builder() 105 .id(id) 106 .title(title) 107 .description(desc) 108 .subActions(subActions) 109 .build()); 110 } 111 112 private static void addEditableAction(Context context, List<GuidedAction> actions, 113 long id, String title, String desc) { 114 actions.add(new GuidedAction.Builder(context) 115 .id(id) 116 .title(title) 117 .description(desc) 118 .editable(true) 119 .icon(R.drawable.lb_ic_search_mic) 120 .build()); 121 } 122 123 private static void addEditableAction(List<GuidedAction> actions, long id, String title, 124 String editTitle, String desc) { 125 actions.add(new GuidedAction.Builder() 126 .id(id) 127 .title(title) 128 .editTitle(editTitle) 129 .description(desc) 130 .editable(true) 131 .build()); 132 } 133 134 private static void addEditableAction(List<GuidedAction> actions, long id, String title, 135 String editTitle, int editInputType, String desc, String editDesc) { 136 actions.add(new GuidedAction.Builder() 137 .id(id) 138 .title(title) 139 .editTitle(editTitle) 140 .editInputType(editInputType) 141 .description(desc) 142 .editDescription(editDesc) 143 .editable(true) 144 .build()); 145 } 146 147 private static void addDatePickerAction(List<GuidedAction> actions, long id, String title) { 148 actions.add(new GuidedDatePickerAction.Builder(null) 149 .id(id) 150 .title(title) 151 .datePickerFormat("MY") 152 .build()); 153 } 154 155 private static void addEditableDescriptionAction(List<GuidedAction> actions, long id, 156 String title, String desc, String editDescription, int descriptionEditInputType) { 157 actions.add(new GuidedAction.Builder() 158 .id(id) 159 .title(title) 160 .description(desc) 161 .editDescription(editDescription) 162 .descriptionEditInputType(descriptionEditInputType) 163 .descriptionEditable(true) 164 .build()); 165 } 166 167 private static void addCheckedAction(List<GuidedAction> actions, Context context, 168 String title, String desc, int checkSetId) { 169 actions.add(new GuidedAction.Builder() 170 .title(title) 171 .description(desc) 172 .checkSetId(checkSetId) 173 .build()); 174 } 175 176 public static class FirstStepFragment extends GuidedStepSupportFragment { 177 178 @Override 179 public int onProvideTheme() { 180 return R.style.Theme_Example_Leanback_GuidedStep_First; 181 } 182 183 @Override 184 public Guidance onCreateGuidance(Bundle savedInstanceState) { 185 String title = getString(R.string.guidedstep_first_title); 186 String breadcrumb = getString(R.string.guidedstep_first_breadcrumb); 187 String description = getString(R.string.guidedstep_first_description); 188 Drawable icon = getActivity().getResources().getDrawable(R.drawable.ic_main_icon); 189 return new Guidance(title, description, breadcrumb, icon); 190 } 191 192 @Override 193 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 194 Context context = getActivity(); 195 actions.add(new GuidedAction.Builder(context) 196 .clickAction(GuidedAction.ACTION_ID_CONTINUE) 197 .description("Let's do it") 198 .build()); 199 actions.add(new GuidedAction.Builder(context) 200 .clickAction(GuidedAction.ACTION_ID_CANCEL) 201 .description("Never mind") 202 .build()); 203 } 204 205 @Override 206 public void onGuidedActionClicked(GuidedAction action) { 207 FragmentManager fm = getFragmentManager(); 208 if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) { 209 GuidedStepSupportFragment.add(fm, new SecondStepFragment(), R.id.lb_guidedstep_host); 210 } else if (action.getId() == GuidedAction.ACTION_ID_CANCEL){ 211 finishGuidedStepSupportFragments(); 212 } 213 } 214 } 215 216 static ArrayList<String> sCards = new ArrayList<String>(); 217 static int sSelectedCard = -1; 218 static { 219 sCards.add("Visa-1234"); 220 sCards.add("Master-4321"); 221 } 222 223 public static class NewPaymentStepFragment extends GuidedStepSupportFragment { 224 225 @Override 226 public Guidance onCreateGuidance(Bundle savedInstanceState) { 227 String title = getString(R.string.guidedstep_newpayment_title); 228 String breadcrumb = getString(R.string.guidedstep_newpayment_breadcrumb); 229 String description = getString(R.string.guidedstep_newpayment_description); 230 Drawable icon = getActivity().getResources().getDrawable(R.drawable.ic_main_icon); 231 return new Guidance(title, description, breadcrumb, icon); 232 } 233 234 @Override 235 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 236 addEditableAction(actions, NEW_PAYMENT, "Input credit card number", "", 237 InputType.TYPE_CLASS_NUMBER, 238 "Input credit card number", "Input credit card number"); 239 addDatePickerAction(actions, PAYMENT_EXPIRE, "Exp:"); 240 } 241 242 @Override 243 public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) { 244 Context context = getActivity(); 245 actions.add(new GuidedAction.Builder(context).clickAction(GuidedAction.ACTION_ID_OK) 246 .build()); 247 actions.get(actions.size() - 1).setEnabled(false); 248 } 249 250 @Override 251 public void onGuidedActionClicked(GuidedAction action) { 252 if (action.getId() == GuidedAction.ACTION_ID_OK) { 253 CharSequence desc = findActionById(NEW_PAYMENT).getDescription(); 254 String cardNumber = desc.subSequence(desc.length() - 4, desc.length()).toString(); 255 String card; 256 if ((Integer.parseInt(cardNumber) & 1) == 0) { 257 card = "Visa "+cardNumber; 258 } else { 259 card = "Master "+cardNumber; 260 } 261 sSelectedCard = sCards.size(); 262 sCards.add(card); 263 popBackStackToGuidedStepSupportFragment(NewPaymentStepFragment.class, 264 FragmentManager.POP_BACK_STACK_INCLUSIVE); 265 } 266 } 267 268 @Override 269 public long onGuidedActionEditedAndProceed(GuidedAction action) { 270 if (action.getId() == NEW_PAYMENT) { 271 CharSequence editTitle = action.getEditTitle(); 272 if (isCardNumberValid(editTitle)) { 273 editTitle = editTitle.subSequence(editTitle.length() - 4, editTitle.length()); 274 action.setDescription("Visa XXXX-XXXX-XXXX-" + editTitle); 275 updateOkButton(isExpDateValid(findActionById(PAYMENT_EXPIRE))); 276 return GuidedAction.ACTION_ID_NEXT; 277 } else if (editTitle.length() == 0) { 278 action.setDescription("Input credit card number"); 279 updateOkButton(false); 280 return GuidedAction.ACTION_ID_CURRENT; 281 } else { 282 action.setDescription("Error credit card number"); 283 updateOkButton(false); 284 return GuidedAction.ACTION_ID_CURRENT; 285 } 286 } else if (action.getId() == PAYMENT_EXPIRE) { 287 updateOkButton(isExpDateValid(action) && 288 isCardNumberValid(findActionById(NEW_PAYMENT).getEditTitle())); 289 } 290 return GuidedAction.ACTION_ID_NEXT; 291 } 292 293 boolean isCardNumberValid(CharSequence number) { 294 return TextUtils.isDigitsOnly(number) && number.length() == 16; 295 } 296 297 boolean isExpDateValid(GuidedAction action) { 298 long date = ((GuidedDatePickerAction) action).getDate(); 299 Calendar c = Calendar.getInstance(); 300 c.setTimeInMillis(date); 301 return Calendar.getInstance().before(c); 302 } 303 304 void updateOkButton(boolean enabled) { 305 findButtonActionById(GuidedAction.ACTION_ID_OK).setEnabled(enabled); 306 notifyButtonActionChanged(findButtonActionPositionById(GuidedAction.ACTION_ID_OK)); 307 } 308 } 309 310 public static class SecondStepFragment extends GuidedStepSupportFragment { 311 312 public GuidedActionsStylist onCreateActionsStylist() { 313 return new GuidedActionsStylist() { 314 protected void setupImeOptions(GuidedActionsStylist.ViewHolder vh, 315 GuidedAction action) { 316 if (action.getId() == PASSWORD) { 317 vh.getEditableDescriptionView().setImeActionLabel("Confirm!", 318 EditorInfo.IME_ACTION_DONE); 319 } else { 320 super.setupImeOptions(vh, action); 321 } 322 } 323 }; 324 } 325 326 @Override 327 public Guidance onCreateGuidance(Bundle savedInstanceState) { 328 String title = getString(R.string.guidedstep_second_title); 329 String breadcrumb = getString(R.string.guidedstep_second_breadcrumb); 330 String description = getString(R.string.guidedstep_second_description); 331 Drawable icon = getActivity().getResources().getDrawable(R.drawable.ic_main_icon); 332 return new Guidance(title, description, breadcrumb, icon); 333 } 334 335 @Override 336 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 337 addEditableAction(getContext(), actions, FIRST_NAME, "Pat", "Your first name"); 338 addEditableAction(getContext(), actions, LAST_NAME, "Smith", "Your last name"); 339 List<GuidedAction> subActions = new ArrayList<GuidedAction>(); 340 addAction(actions, PAYMENT, "Select Payment", "", subActions); 341 addEditableDescriptionAction(actions, PASSWORD, "Password", "", "", 342 InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); 343 } 344 345 @Override 346 public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) { 347 actions.add(new GuidedAction.Builder(getActivity()) 348 .clickAction(GuidedAction.ACTION_ID_CONTINUE) 349 .description("Continue") 350 .build()); 351 } 352 353 @Override 354 public void onGuidedActionClicked(GuidedAction action) { 355 if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) { 356 FragmentManager fm = getFragmentManager(); 357 GuidedStepSupportFragment.add(fm, new ThirdStepFragment(), R.id.lb_guidedstep_host); 358 } 359 } 360 361 @Override 362 public long onGuidedActionEditedAndProceed(GuidedAction action) { 363 if (action.getId() == PASSWORD) { 364 CharSequence password = action.getEditDescription(); 365 if (password.length() > 0) { 366 if (isPaymentValid()) { 367 updateContinue(true); 368 return GuidedAction.ACTION_ID_NEXT; 369 } else { 370 updateContinue(false); 371 return GuidedAction.ACTION_ID_CURRENT; 372 } 373 } else { 374 updateContinue(false); 375 return GuidedAction.ACTION_ID_CURRENT; 376 } 377 } 378 return GuidedAction.ACTION_ID_NEXT; 379 } 380 381 @Override 382 public boolean onSubGuidedActionClicked(GuidedAction action) { 383 if (action.isChecked()) { 384 String payment = action.getTitle().toString(); 385 for (int i = 0; i < sCards.size(); i++) { 386 if (payment.equals(sCards.get(i))) { 387 sSelectedCard = i; 388 findActionById(PAYMENT).setDescription(payment); 389 notifyActionChanged(findActionPositionById(PAYMENT)); 390 updateContinue(isPasswordValid()); 391 break; 392 } 393 } 394 return true; 395 } else { 396 FragmentManager fm = getFragmentManager(); 397 GuidedStepSupportFragment.add(fm, new NewPaymentStepFragment(), R.id.lb_guidedstep_host); 398 return false; 399 } 400 } 401 402 @Override 403 public void onResume() { 404 super.onResume(); 405 // when resumed, update sub actions list and selected index from data model. 406 GuidedAction payments = findActionById(PAYMENT); 407 payments.getSubActions().clear(); 408 for (int i = 0; i < sCards.size(); i++) { 409 addCheckedAction(payments.getSubActions(), getActivity(), sCards.get(i), "", 410 GuidedAction.DEFAULT_CHECK_SET_ID); 411 if (i == sSelectedCard) { 412 payments.getSubActions().get(i).setChecked(true); 413 } 414 } 415 addAction(payments.getSubActions(), NEW_PAYMENT, "Add New Card", ""); 416 if (sSelectedCard != -1) { 417 payments.setDescription(sCards.get(sSelectedCard)); 418 } 419 notifyActionChanged(findActionPositionById(PAYMENT)); 420 updateContinue(isPasswordValid() && isPaymentValid()); 421 } 422 423 boolean isPaymentValid() { 424 CharSequence paymentType = findActionById(PAYMENT).getDescription(); 425 return paymentType.subSequence(0, 4).toString().equals("Visa") || 426 paymentType.subSequence(0, 6).toString().equals("Master"); 427 } 428 429 boolean isPasswordValid() { 430 return findActionById(PASSWORD).getEditDescription().length() > 0; 431 } 432 433 void updateContinue(boolean enabled) { 434 findButtonActionById(GuidedAction.ACTION_ID_CONTINUE).setEnabled(enabled); 435 notifyButtonActionChanged(findButtonActionPositionById( 436 GuidedAction.ACTION_ID_CONTINUE)); 437 } 438 } 439 440 public static class ThirdStepFragment extends GuidedStepSupportFragment { 441 442 private int mSelectedOption = DEFAULT_OPTION; 443 444 @Override 445 public Guidance onCreateGuidance(Bundle savedInstanceState) { 446 String title = getString(R.string.guidedstep_third_title); 447 String breadcrumb = getString(R.string.guidedstep_third_breadcrumb); 448 String description = getString(R.string.guidedstep_third_description); 449 Drawable icon = getActivity().getResources().getDrawable(R.drawable.ic_main_icon); 450 return new Guidance(title, description, breadcrumb, icon); 451 } 452 453 @Override 454 public GuidanceStylist onCreateGuidanceStylist() { 455 return new GuidanceStylist() { 456 @Override 457 public int onProvideLayoutId() { 458 return R.layout.guidedstep_second_guidance; 459 } 460 }; 461 } 462 463 @Override 464 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 465 String desc = "The description can be quite long as well. "; 466 desc += "Just be sure to set multilineDescription to true in the GuidedAction."; 467 actions.add(new GuidedAction.Builder() 468 .title("Note that Guided Actions can have titles that are quite long.") 469 .description(desc) 470 .multilineDescription(true) 471 .infoOnly(true) 472 .enabled(true) 473 .focusable(false) 474 .build()); 475 for (int i = 0; i < OPTION_NAMES.length; i++) { 476 addCheckedAction(actions, getActivity(), OPTION_NAMES[i], 477 OPTION_DESCRIPTIONS[i], GuidedAction.DEFAULT_CHECK_SET_ID); 478 if (i == DEFAULT_OPTION) { 479 actions.get(actions.size() -1).setChecked(true); 480 } 481 } 482 for (int i = 0; i < OPTION_NAMES.length; i++) { 483 addCheckedAction(actions, getActivity(), OPTION_NAMES[i], 484 OPTION_DESCRIPTIONS[i], GuidedAction.CHECKBOX_CHECK_SET_ID); 485 } 486 } 487 488 @Override 489 public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) { 490 actions.add(new GuidedAction.Builder(getActivity()) 491 .clickAction(GuidedAction.ACTION_ID_CONTINUE) 492 .build()); 493 } 494 495 @Override 496 public void onGuidedActionClicked(GuidedAction action) { 497 if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) { 498 FragmentManager fm = getFragmentManager(); 499 FourthStepFragment f = new FourthStepFragment(); 500 Bundle arguments = new Bundle(); 501 arguments.putInt(FourthStepFragment.EXTRA_OPTION, mSelectedOption); 502 f.setArguments(arguments); 503 GuidedStepSupportFragment.add(fm, f, R.id.lb_guidedstep_host); 504 } else if (action.getCheckSetId() == GuidedAction.DEFAULT_CHECK_SET_ID) { 505 mSelectedOption = getSelectedActionPosition()-1; 506 } 507 } 508 509 } 510 511 public static class FourthStepFragment extends GuidedStepSupportFragment { 512 public static final String EXTRA_OPTION = "extra_option"; 513 514 public FourthStepFragment() { 515 } 516 517 public int getOption() { 518 Bundle b = getArguments(); 519 if (b == null) return 0; 520 return b.getInt(EXTRA_OPTION, 0); 521 } 522 523 @Override 524 public Guidance onCreateGuidance(Bundle savedInstanceState) { 525 String title = getString(R.string.guidedstep_fourth_title); 526 String breadcrumb = getString(R.string.guidedstep_fourth_breadcrumb); 527 String description = "You chose: " + OPTION_NAMES[getOption()]; 528 Drawable icon = getActivity().getResources().getDrawable(R.drawable.ic_main_icon); 529 return new Guidance(title, description, breadcrumb, icon); 530 } 531 532 @Override 533 public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) { 534 actions.add(new GuidedAction.Builder(getActivity()) 535 .clickAction(GuidedAction.ACTION_ID_FINISH) 536 .description("All Done...") 537 .build()); 538 addAction(actions, BACK, "Start Over", "Let's try this again..."); 539 } 540 541 @Override 542 public void onGuidedActionClicked(GuidedAction action) { 543 if (action.getId() == GuidedAction.ACTION_ID_FINISH) { 544 finishGuidedStepSupportFragments(); 545 } else if (action.getId() == BACK) { 546 // pop 4, 3, 2 547 popBackStackToGuidedStepSupportFragment(SecondStepFragment.class, 548 FragmentManager.POP_BACK_STACK_INCLUSIVE); 549 } 550 } 551 552 } 553 554} 555