• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.leanback;
18 
19 import android.app.Activity;
20 import android.app.Fragment;
21 import android.app.FragmentManager;
22 import android.content.Context;
23 import android.content.res.Configuration;
24 import android.graphics.drawable.Drawable;
25 import android.os.Bundle;
26 import android.text.InputType;
27 import android.text.TextUtils;
28 import android.util.Log;
29 import android.view.LayoutInflater;
30 import android.view.View;
31 import android.view.ViewGroup;
32 import android.view.inputmethod.EditorInfo;
33 
34 import androidx.core.content.res.ResourcesCompat;
35 import androidx.leanback.app.GuidedStepFragment;
36 import androidx.leanback.widget.GuidanceStylist;
37 import androidx.leanback.widget.GuidanceStylist.Guidance;
38 import androidx.leanback.widget.GuidedAction;
39 import androidx.leanback.widget.GuidedActionsStylist;
40 import androidx.leanback.widget.GuidedDatePickerAction;
41 
42 import java.util.ArrayList;
43 import java.util.Calendar;
44 import java.util.List;
45 
46 /**
47  * Activity that showcases different aspects of GuidedStepFragments.
48  */
49 public class GuidedStepActivity extends Activity {
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     private static final int REFRESH = 9;
60 
61     private static final long RADIO_ID_BASE = 0;
62     private static final long CHECKBOX_ID_BASE = 100;
63 
64     private static final long DEFAULT_OPTION = RADIO_ID_BASE;
65 
66     private static final String[] OPTION_NAMES = { "Option A", "Option B", "Option C" };
67     private static final String[] OPTION_DESCRIPTIONS = { "Here's one thing you can do",
68             "Here's another thing you can do", "Here's one more thing you can do" };
69 
70     private static final String TAG = GuidedStepActivity.class.getSimpleName();
71 
72     @Override
onCreate(Bundle savedInstanceState)73     protected void onCreate(Bundle savedInstanceState) {
74         Log.v(TAG, "onCreate");
75         super.onCreate(savedInstanceState);
76         setContentView(R.layout.guided_step_activity);
77         if (savedInstanceState == null) {
78             GuidedStepFragment.addAsRoot(this, new FirstStepFragment(), R.id.lb_guidedstep_host);
79         }
80     }
81 
82     @Override
onConfigurationChanged(Configuration newConfig)83     public void onConfigurationChanged(Configuration newConfig) {
84         Log.v(TAG, "onConfigurationChanged");
85         super.onConfigurationChanged(newConfig);
86     }
87 
88     @Override
onSaveInstanceState(Bundle outState)89     protected void onSaveInstanceState(Bundle outState) {
90         Log.v(TAG, "onSaveInstanceState");
91         super.onSaveInstanceState(outState);
92     }
93 
94     @Override
onRestoreInstanceState(Bundle savedInstanceState)95     protected void onRestoreInstanceState(Bundle savedInstanceState) {
96         Log.v(TAG, "onRestoreInstanceState");
97         super.onRestoreInstanceState(savedInstanceState);
98     }
99 
addAction(List<GuidedAction> actions, long id, String title, String desc)100     private static GuidedAction addAction(List<GuidedAction> actions, long id, String title,
101             String desc) {
102         GuidedAction action;
103         actions.add(action = new GuidedAction.Builder(null)
104                 .id(id)
105                 .title(title)
106                 .description(desc)
107                 .build());
108         return action;
109     }
110 
addAction(List<GuidedAction> actions, long id, String title, String desc, List<GuidedAction> subActions)111     private static GuidedAction addAction(List<GuidedAction> actions, long id, String title,
112             String desc, List<GuidedAction> subActions) {
113         GuidedAction action;
114         actions.add(action = new GuidedAction.Builder(null)
115                 .id(id)
116                 .title(title)
117                 .description(desc)
118                 .subActions(subActions)
119                 .build());
120         return action;
121     }
122 
addEditableAction(Context context, List<GuidedAction> actions, long id, String title, String desc)123     private static GuidedAction addEditableAction(Context context, List<GuidedAction> actions,
124             long id, String title, String desc) {
125         GuidedAction action;
126         actions.add(action = new GuidedAction.Builder(context)
127                 .id(id)
128                 .title(title)
129                 .description(desc)
130                 .editable(true)
131                 .icon(R.drawable.lb_ic_search_mic)
132                 .build());
133         return action;
134     }
135 
addEditableAction(List<GuidedAction> actions, long id, String title, String editTitle, String desc)136     private static GuidedAction addEditableAction(List<GuidedAction> actions, long id, String title,
137             String editTitle, String desc) {
138         GuidedAction action;
139         actions.add(action = new GuidedAction.Builder(null)
140                 .id(id)
141                 .title(title)
142                 .editTitle(editTitle)
143                 .description(desc)
144                 .editable(true)
145                 .build());
146         return action;
147     }
148 
addEditableAction(List<GuidedAction> actions, long id, String title, String editTitle, int editInputType, String desc, String editDesc)149     private static GuidedAction addEditableAction(List<GuidedAction> actions, long id, String title,
150             String editTitle, int editInputType, String desc, String editDesc) {
151         GuidedAction action;
152         actions.add(action = new GuidedAction.Builder(null)
153                 .id(id)
154                 .title(title)
155                 .editTitle(editTitle)
156                 .editInputType(editInputType)
157                 .description(desc)
158                 .editDescription(editDesc)
159                 .editable(true)
160                 .build());
161         return action;
162     }
163 
addDatePickerAction(List<GuidedAction> actions, long id, String title)164     private static GuidedDatePickerAction addDatePickerAction(List<GuidedAction> actions, long id,
165             String title) {
166         GuidedDatePickerAction action;
167         actions.add(action = new GuidedDatePickerAction.Builder(null)
168                 .id(id)
169                 .title(title)
170                 .datePickerFormat("MY")
171                 .build());
172         return action;
173     }
174 
addEditableDescriptionAction(List<GuidedAction> actions, long id, String title, String desc, String editDescription, int descriptionEditInputType)175     private static GuidedAction addEditableDescriptionAction(List<GuidedAction> actions, long id,
176             String title, String desc, String editDescription, int descriptionEditInputType) {
177         GuidedAction action;
178         actions.add(action = new GuidedAction.Builder(null)
179                 .id(id)
180                 .title(title)
181                 .description(desc)
182                 .editDescription(editDescription)
183                 .descriptionEditInputType(descriptionEditInputType)
184                 .descriptionEditable(true)
185                 .build());
186         return action;
187     }
188 
addCheckedAction(List<GuidedAction> actions, long id, String title, String desc, int checkSetId)189     private static GuidedAction addCheckedAction(List<GuidedAction> actions, long id,
190             String title, String desc, int checkSetId) {
191         GuidedAction action;
192         actions.add(action = new GuidedAction.Builder(null)
193                 .id(id)
194                 .title(title)
195                 .description(desc)
196                 .checkSetId(checkSetId)
197                 .build());
198         return action;
199     }
200 
201     public static class FirstStepFragment extends GuidedStepFragment {
202 
203         @Override
onProvideTheme()204         public int onProvideTheme() {
205             return R.style.Theme_Example_Leanback_GuidedStep_First;
206         }
207 
208         @Override
onCreateGuidance(Bundle savedInstanceState)209         public Guidance onCreateGuidance(Bundle savedInstanceState) {
210             String title = getString(R.string.guidedstep_first_title);
211             String breadcrumb = getString(R.string.guidedstep_first_breadcrumb);
212             String description = getString(R.string.guidedstep_first_description);
213             final Context context = getActivity();
214             Drawable icon = ResourcesCompat.getDrawable(context.getResources(),
215                     R.drawable.ic_main_icon, context.getTheme());
216             return new Guidance(title, description, breadcrumb, icon);
217         }
218 
219         @Override
onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState)220         public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
221             Context context = getActivity();
222             actions.add(new GuidedAction.Builder(context)
223                     .clickAction(GuidedAction.ACTION_ID_CONTINUE)
224                     .description("Let's do it")
225                     .build());
226             actions.add(new GuidedAction.Builder(context)
227                     .id(REFRESH)
228                     .title("Refresh")
229                     .build());
230             actions.add(new GuidedAction.Builder(context)
231                     .clickAction(GuidedAction.ACTION_ID_CANCEL)
232                     .description("Never mind")
233                     .build());
234         }
235 
236         @Override
onGuidedActionClicked(GuidedAction action)237         public void onGuidedActionClicked(GuidedAction action) {
238             FragmentManager fm = getFragmentManager();
239             if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
240                 GuidedStepFragment.add(fm, new SecondStepFragment(), R.id.lb_guidedstep_host);
241             } else if (action.getId() == REFRESH) {
242                 // swap actions position and change content:
243                 Context context = getActivity();
244                 ArrayList<GuidedAction> newActions = new ArrayList();
245                 newActions.add(new GuidedAction.Builder(context)
246                         .id(REFRESH)
247                         .title("Refresh done")
248                         .build());
249                 newActions.add(new GuidedAction.Builder(context)
250                         .clickAction(GuidedAction.ACTION_ID_CONTINUE)
251                         .description("Let's do it")
252                         .build());
253                 newActions.add(new GuidedAction.Builder(context)
254                         .clickAction(GuidedAction.ACTION_ID_CANCEL)
255                         .description("Never mind")
256                         .build());
257                 //setActionsDiffCallback(null);
258                 setActions(newActions);
259             } else if (action.getId() == GuidedAction.ACTION_ID_CANCEL){
260                 finishGuidedStepFragments();
261             }
262         }
263     }
264 
265     public interface NewPaymentFragmentTarget {
onNewPaymentFragmentStarted()266         void onNewPaymentFragmentStarted();
onNewPaymentAdded(int selection)267         void onNewPaymentAdded(int selection);
268     }
269 
270     static ArrayList<String> sCards = new ArrayList<String>();
271     static int sSelectedCard = -1;
272     static {
273         sCards.add("Visa-1234");
274         sCards.add("Master-4321");
275     }
276 
277     public static class NewPaymentStepFragment extends GuidedStepFragment {
278 
279         NewPaymentFragmentTarget mNewPaymentTarget;
280 
281         @Override
onCreate(Bundle savedInstance)282         public void onCreate(Bundle savedInstance) {
283             super.onCreate(savedInstance);
284             Fragment targetFragment = getTargetFragment();
285             if (targetFragment instanceof NewPaymentFragmentTarget) {
286                 mNewPaymentTarget = ((NewPaymentFragmentTarget) targetFragment);
287                 mNewPaymentTarget.onNewPaymentFragmentStarted();
288             }
289         }
290 
291         @Override
onCreateGuidance(Bundle savedInstanceState)292         public Guidance onCreateGuidance(Bundle savedInstanceState) {
293             String title = getString(R.string.guidedstep_newpayment_title);
294             String breadcrumb = getString(R.string.guidedstep_newpayment_breadcrumb);
295             String description = getString(R.string.guidedstep_newpayment_description);
296             final Context context = getActivity();
297             Drawable icon = ResourcesCompat.getDrawable(context.getResources(),
298                     R.drawable.ic_main_icon, context.getTheme());
299             return new Guidance(title, description, breadcrumb, icon);
300         }
301 
302         @Override
onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState)303         public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
304             addEditableAction(actions, NEW_PAYMENT, "Input credit card number", "",
305                     InputType.TYPE_CLASS_NUMBER,
306                     "Input credit card number", "Input credit card number");
307             addDatePickerAction(actions, PAYMENT_EXPIRE, "Exp:");
308         }
309 
310         @Override
onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState)311         public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
312             Context context = getActivity();
313             actions.add(new GuidedAction.Builder(context).clickAction(GuidedAction.ACTION_ID_OK)
314                     .build());
315             actions.get(actions.size() - 1).setEnabled(false);
316         }
317 
318         @Override
onGuidedActionClicked(GuidedAction action)319         public void onGuidedActionClicked(GuidedAction action) {
320             if (action.getId() == GuidedAction.ACTION_ID_OK) {
321                 CharSequence desc = findActionById(NEW_PAYMENT).getDescription();
322                 String cardNumber = desc.subSequence(desc.length() - 4, desc.length()).toString();
323                 String card;
324                 if ((Integer.parseInt(cardNumber) & 1) == 0) {
325                     card = "Visa "+cardNumber;
326                 } else {
327                     card = "Master "+cardNumber;
328                 }
329                 int selection = sCards.size();
330                 sCards.add(card);
331                 if (mNewPaymentTarget != null) {
332                     mNewPaymentTarget.onNewPaymentAdded(selection);
333                 }
334                 popBackStackToGuidedStepFragment(NewPaymentStepFragment.class,
335                         FragmentManager.POP_BACK_STACK_INCLUSIVE);
336             }
337         }
338 
339         @Override
onGuidedActionEditedAndProceed(GuidedAction action)340         public long onGuidedActionEditedAndProceed(GuidedAction action) {
341             if (action.getId() == NEW_PAYMENT) {
342                 CharSequence editTitle = action.getEditTitle();
343                 if (isCardNumberValid(editTitle)) {
344                     editTitle = editTitle.subSequence(editTitle.length() - 4, editTitle.length());
345                     action.setDescription("Visa XXXX-XXXX-XXXX-" + editTitle);
346                     updateOkButton(isExpDateValid(findActionById(PAYMENT_EXPIRE)));
347                     return GuidedAction.ACTION_ID_NEXT;
348                 } else if (editTitle.length() == 0) {
349                     action.setDescription("Input credit card number");
350                     updateOkButton(false);
351                     return GuidedAction.ACTION_ID_CURRENT;
352                 } else {
353                     action.setDescription("Error credit card number");
354                     updateOkButton(false);
355                     return GuidedAction.ACTION_ID_CURRENT;
356                 }
357             } else if (action.getId() == PAYMENT_EXPIRE) {
358                 updateOkButton(isExpDateValid(action) &&
359                         isCardNumberValid(findActionById(NEW_PAYMENT).getEditTitle()));
360             }
361             return GuidedAction.ACTION_ID_NEXT;
362         }
363 
isCardNumberValid(CharSequence number)364         boolean isCardNumberValid(CharSequence number) {
365             return TextUtils.isDigitsOnly(number) && number.length() == 16;
366         }
367 
isExpDateValid(GuidedAction action)368         boolean isExpDateValid(GuidedAction action) {
369             long date = ((GuidedDatePickerAction) action).getDate();
370             Calendar c = Calendar.getInstance();
371             c.setTimeInMillis(date);
372             return Calendar.getInstance().before(c);
373         }
374 
updateOkButton(boolean enabled)375         void updateOkButton(boolean enabled) {
376             findButtonActionById(GuidedAction.ACTION_ID_OK).setEnabled(enabled);
377             notifyButtonActionChanged(findButtonActionPositionById(GuidedAction.ACTION_ID_OK));
378         }
379     }
380 
381     public static class SecondStepFragment extends GuidedStepFragment
382             implements NewPaymentFragmentTarget {
383 
384 
385         boolean mExpandPaymentListInOnCreateView;
386 
387         @Override
onNewPaymentAdded(int selection)388         public void onNewPaymentAdded(int selection) {
389             // if a new payment is added, we dont need expand the sub actions list.
390             mExpandPaymentListInOnCreateView = false;
391             sSelectedCard = selection;
392             updatePaymentAction(findActionById(PAYMENT));
393             findButtonActionById(GuidedAction.ACTION_ID_CONTINUE).setEnabled(sSelectedCard != -1);
394         }
395 
396         @Override
onNewPaymentFragmentStarted()397         public void onNewPaymentFragmentStarted() {
398             // if a new payment fragment is opened, when come back we should expand the payment
399             // sub actions list unless user created a new payment in onNewPaymentAdded
400             mExpandPaymentListInOnCreateView = true;
401         }
402 
403         @Override
onCreateActionsStylist()404         public GuidedActionsStylist onCreateActionsStylist() {
405             return new GuidedActionsStylist() {
406                 @Override
407                 protected void setupImeOptions(GuidedActionsStylist.ViewHolder vh,
408                         GuidedAction action) {
409                     if (action.getId() == PASSWORD) {
410                         vh.getEditableDescriptionView().setImeActionLabel("Confirm!",
411                                 EditorInfo.IME_ACTION_DONE);
412                     } else {
413                         super.setupImeOptions(vh, action);
414                     }
415                 }
416             };
417         }
418 
419         @Override
420         public Guidance onCreateGuidance(Bundle savedInstanceState) {
421             String title = getString(R.string.guidedstep_second_title);
422             String breadcrumb = getString(R.string.guidedstep_second_breadcrumb);
423             String description = getString(R.string.guidedstep_second_description);
424             final Context context = getActivity();
425             Drawable icon = ResourcesCompat.getDrawable(context.getResources(),
426                     R.drawable.ic_main_icon, context.getTheme());
427             return new Guidance(title, description, breadcrumb, icon);
428         }
429 
430         @Override
431         public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
432             addEditableAction(getActivity(), actions, FIRST_NAME, "Pat", "Your first name");
433             addEditableAction(getActivity(), actions, LAST_NAME, "Smith", "Your last name");
434             List<GuidedAction> subActions = new ArrayList<GuidedAction>();
435             updatePaymentAction(addAction(actions, PAYMENT, "Select Payment", "", subActions));
436             addEditableDescriptionAction(actions, PASSWORD, "Password", "", "",
437                     InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
438         }
439 
440         @Override
441         public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
442             actions.add(new GuidedAction.Builder(getActivity())
443                     .clickAction(GuidedAction.ACTION_ID_CONTINUE)
444                     .description("Continue")
445                     .enabled(isPasswordValid() && isPaymentValid())
446                     .build());
447         }
448 
449         @Override
450         public void onGuidedActionClicked(GuidedAction action) {
451             if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
452                 FragmentManager fm = getFragmentManager();
453                 GuidedStepFragment.add(fm, new ThirdStepFragment(), R.id.lb_guidedstep_host);
454             }
455         }
456 
457         void updatePaymentAction(GuidedAction paymentAction) {
458             List<GuidedAction> subActions = paymentAction.getSubActions();
459             subActions.clear();
460             for (int i = 0; i < sCards.size(); i++) {
461                 addCheckedAction(subActions, -1, sCards.get(i), "",
462                         GuidedAction.DEFAULT_CHECK_SET_ID);
463                 if (i == sSelectedCard) {
464                     subActions.get(i).setChecked(true);
465                 }
466             }
467             addAction(subActions, NEW_PAYMENT, "Add New Card", "");
468             paymentAction.setDescription(sSelectedCard == -1 ? "" : sCards.get(sSelectedCard));
469         }
470 
471         @Override
472         public long onGuidedActionEditedAndProceed(GuidedAction action) {
473             if (action.getId() == PASSWORD) {
474                 CharSequence password = action.getEditDescription();
475                 if (password.length() > 0) {
476                     if (isPaymentValid()) {
477                         updateContinue(true);
478                         return GuidedAction.ACTION_ID_NEXT;
479                     } else {
480                         updateContinue(false);
481                         return GuidedAction.ACTION_ID_CURRENT;
482                     }
483                 } else {
484                     updateContinue(false);
485                     return GuidedAction.ACTION_ID_CURRENT;
486                 }
487             }
488             return GuidedAction.ACTION_ID_NEXT;
489         }
490 
491         @Override
492         public boolean onSubGuidedActionClicked(GuidedAction action) {
493             if (action.isChecked()) {
494                 String payment = action.getTitle().toString();
495                 for (int i = 0; i < sCards.size(); i++) {
496                     if (payment.equals(sCards.get(i))) {
497                         sSelectedCard = i;
498                         findActionById(PAYMENT).setDescription(payment);
499                         notifyActionChanged(findActionPositionById(PAYMENT));
500                         updateContinue(isPasswordValid());
501                         break;
502                     }
503                 }
504                 return true;
505             } else {
506                 FragmentManager fm = getFragmentManager();
507                 NewPaymentStepFragment newPaymentFragment = new NewPaymentStepFragment();
508                 newPaymentFragment.setTargetFragment(this, 0);
509                 GuidedStepFragment.add(fm, newPaymentFragment, R.id.lb_guidedstep_host);
510                 return false;
511             }
512         }
513 
514         @Override
515         public View onCreateView(LayoutInflater inflater, ViewGroup container,
516                 Bundle savedInstanceState) {
517             View view = super.onCreateView(inflater, container, savedInstanceState);
518             if (mExpandPaymentListInOnCreateView) {
519                 expandAction(findActionById(PAYMENT), false);
520             }
521             return view;
522         }
523 
524         boolean isPaymentValid() {
525             CharSequence paymentType = findActionById(PAYMENT).getDescription();
526             return (paymentType.length() >= 4 &&
527                     paymentType.subSequence(0, 4).toString().equals("Visa")) ||
528                     (paymentType.length() >= 6 &&
529                     paymentType.subSequence(0, 6).toString().equals("Master"));
530         }
531 
532         boolean isPasswordValid() {
533             return findActionById(PASSWORD).getEditDescription().length() > 0;
534         }
535 
536         void updateContinue(boolean enabled) {
537             findButtonActionById(GuidedAction.ACTION_ID_CONTINUE).setEnabled(enabled);
538             notifyButtonActionChanged(findButtonActionPositionById(
539                     GuidedAction.ACTION_ID_CONTINUE));
540         }
541     }
542 
543     public static class ThirdStepFragment extends GuidedStepFragment {
544 
545         private long mSelectedOption = DEFAULT_OPTION;
546 
547         @Override
548         public Guidance onCreateGuidance(Bundle savedInstanceState) {
549             String title = getString(R.string.guidedstep_third_title);
550             String breadcrumb = getString(R.string.guidedstep_third_breadcrumb);
551             String description = getString(R.string.guidedstep_third_description);
552             final Context context = getActivity();
553             Drawable icon = ResourcesCompat.getDrawable(context.getResources(),
554                     R.drawable.ic_main_icon, context.getTheme());
555             return new Guidance(title, description, breadcrumb, icon);
556         }
557 
558         @Override
559         public GuidanceStylist onCreateGuidanceStylist() {
560             return new GuidanceStylist() {
561                 @Override
562                 public int onProvideLayoutId() {
563                     return R.layout.guidedstep_second_guidance;
564                 }
565             };
566         }
567 
568         @Override
569         public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
570             String desc = "The description can be quite long as well.  "
571                     + "Just be sure to set multilineDescription to true in the GuidedAction."
572                     + "For testing purpose we make this line even longer since "
573                     + "multilineDescriptionMinLines will be set to 2.";
574             actions.add(new GuidedAction.Builder(getActivity())
575                     .title("Note that Guided Actions can have titles that are quite long.")
576                     .description(desc)
577                     .multilineDescription(true)
578                     .infoOnly(true)
579                     .enabled(true)
580                     .focusable(false)
581                     .build());
582             for (int i = 0; i < OPTION_NAMES.length; i++) {
583                 addCheckedAction(actions, RADIO_ID_BASE + i, OPTION_NAMES[i],
584                         OPTION_DESCRIPTIONS[i], GuidedAction.DEFAULT_CHECK_SET_ID);
585                 if (i == DEFAULT_OPTION) {
586                     actions.get(actions.size() -1).setChecked(true);
587                 }
588             }
589             for (int i = 0; i < OPTION_NAMES.length; i++) {
590                 addCheckedAction(actions, CHECKBOX_ID_BASE + i, OPTION_NAMES[i],
591                         OPTION_DESCRIPTIONS[i], GuidedAction.CHECKBOX_CHECK_SET_ID);
592             }
593         }
594 
595         @Override
596         public void onCreateButtonActions(List<GuidedAction> actions, Bundle savedInstanceState) {
597             actions.add(new GuidedAction.Builder(getActivity())
598                     .clickAction(GuidedAction.ACTION_ID_CONTINUE)
599                     .build());
600         }
601 
602         @Override
603         public void onGuidedActionClicked(GuidedAction action) {
604             if (action.getId() == GuidedAction.ACTION_ID_CONTINUE) {
605                 FragmentManager fm = getFragmentManager();
606                 FourthStepFragment f = new FourthStepFragment();
607                 Bundle arguments = new Bundle();
608                 arguments.putLong(FourthStepFragment.EXTRA_OPTION, mSelectedOption);
609                 f.setArguments(arguments);
610                 GuidedStepFragment.add(fm, f, R.id.lb_guidedstep_host);
611             } else if (action.getCheckSetId() == GuidedAction.DEFAULT_CHECK_SET_ID) {
612                 mSelectedOption = action.getId();
613             }
614         }
615 
616     }
617 
618     public static class FourthStepFragment extends GuidedStepFragment {
619         public static final String EXTRA_OPTION = "extra_option";
620 
621         public FourthStepFragment() {
622         }
623 
624         public long getOption() {
625             Bundle b = getArguments();
626             if (b == null) return 0;
627             return b.getLong(EXTRA_OPTION, 0);
628         }
629 
630         @Override
631         public Guidance onCreateGuidance(Bundle savedInstanceState) {
632             String title = getString(R.string.guidedstep_fourth_title);
633             String breadcrumb = getString(R.string.guidedstep_fourth_breadcrumb);
634             String description = "You chose: " + OPTION_NAMES[(int) getOption()];
635             final Context context = getActivity();
636             Drawable icon = ResourcesCompat.getDrawable(context.getResources(),
637                     R.drawable.ic_main_icon, context.getTheme());
638             return new Guidance(title, description, breadcrumb, icon);
639         }
640 
641         @Override
642         public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
643             actions.add(new GuidedAction.Builder(getActivity())
644                     .clickAction(GuidedAction.ACTION_ID_FINISH)
645                     .description("All Done...")
646                     .build());
647             addAction(actions, BACK, "Start Over", "Let's try this again...");
648         }
649 
650         @Override
651         public void onGuidedActionClicked(GuidedAction action) {
652             if (action.getId() == GuidedAction.ACTION_ID_FINISH) {
653                 finishGuidedStepFragments();
654             } else if (action.getId() == BACK) {
655                 // pop 4, 3, 2
656                 popBackStackToGuidedStepFragment(SecondStepFragment.class,
657                         FragmentManager.POP_BACK_STACK_INCLUSIVE);
658             }
659         }
660 
661     }
662 
663 }
664