SupportLeanbackShowcase: Added new credit card workflow and theme
background for the wizard view Created a payment workflow consisting of a set of fragments for entering & adding new credit card information (checks in place for validity of the card number as well as expiration date). Also, changed the dropdown subaction's background colors to be consistent with the rest of guided step fragment view. Fixed the back key pressed to "not" exit the entire wizard on the last fragment (it not goes back to the payment fragment section when back button is pressed). Change-Id: I39cf316f09b765cffbd0a7e012539c49dbe238ed
This commit is contained in:
@@ -56,7 +56,7 @@ public class WizardExample1stStepFragment extends WizardExampleBaseStepFragment
|
||||
.title(getString(R.string.wizard_example_rent_sd))
|
||||
.editable(false)
|
||||
.description(mMovie.getPriceSd() + " " +
|
||||
R.string.wizard_example_watch_sd)
|
||||
getString(R.string.wizard_example_watch_sd))
|
||||
.build();
|
||||
actions.add(action);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
package android.support.v17.leanback.supportleanbackshowcase.app.wizard;
|
||||
|
||||
import android.app.FragmentManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
@@ -26,6 +27,7 @@ import android.support.v17.leanback.widget.GuidedAction;
|
||||
import android.support.v17.leanback.widget.GuidedActionsStylist;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -36,6 +38,16 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment
|
||||
private static final String ARG_HD = "hd";
|
||||
private static final int ACTION_ID_CONFIRM = 1;
|
||||
private static final int ACTION_ID_PAYMENT_METHOD = ACTION_ID_CONFIRM + 1;
|
||||
private static final int ACTION_ID_NEW_PAYMENT = ACTION_ID_PAYMENT_METHOD + 1;
|
||||
|
||||
protected static ArrayList<String> sCards = new ArrayList<>();
|
||||
protected static int sSelectedCard = -1;
|
||||
|
||||
static {
|
||||
sCards.add("Visa-1234");
|
||||
sCards.add("Master-4321");
|
||||
}
|
||||
|
||||
|
||||
public static GuidedStepFragment build(boolean hd, WizardExampleBaseStepFragment previousFragment) {
|
||||
GuidedStepFragment fragment = new WizardExample2ndStepFragment();
|
||||
@@ -66,27 +78,67 @@ public class WizardExample2ndStepFragment extends WizardExampleBaseStepFragment
|
||||
.description(rentHighDefinition ? mMovie.getPriceHd() : mMovie.getPriceSd())
|
||||
.editable(false)
|
||||
.build();
|
||||
action.setEnabled(false);
|
||||
actions.add(action);
|
||||
List<GuidedAction> subActions = new ArrayList<>();
|
||||
action = new GuidedAction.Builder(getActivity())
|
||||
.id(ACTION_ID_PAYMENT_METHOD)
|
||||
.title(R.string.wizard_example_payment_method)
|
||||
.editTitle("")
|
||||
.description(R.string.wizard_example_input_credit)
|
||||
.editable(true)
|
||||
.subActions(subActions)
|
||||
.build();
|
||||
actions.add(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuidedActionEdited(GuidedAction action) {
|
||||
CharSequence editTitle = action.getEditTitle();
|
||||
if (TextUtils.isDigitsOnly(editTitle) && editTitle.length() == 16) {
|
||||
action.setDescription(getString(R.string.wizard_example_visa,
|
||||
editTitle.subSequence(editTitle.length() - 4, editTitle.length())));
|
||||
} else if (editTitle.length() == 0) {
|
||||
action.setDescription(getString(R.string.wizard_example_input_credit));
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
GuidedAction payment = findActionById(ACTION_ID_PAYMENT_METHOD);
|
||||
|
||||
List<GuidedAction> paymentSubActions = payment.getSubActions();
|
||||
paymentSubActions.clear();
|
||||
for (int i = 0; i < sCards.size(); i++) {
|
||||
paymentSubActions.add(new GuidedAction.Builder(getActivity())
|
||||
.title(sCards.get(i))
|
||||
.description("")
|
||||
.checkSetId(GuidedAction.DEFAULT_CHECK_SET_ID)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
paymentSubActions.add(new GuidedAction.Builder(getActivity())
|
||||
.id(ACTION_ID_NEW_PAYMENT)
|
||||
.title("Add New Card")
|
||||
.description("")
|
||||
.editable(false)
|
||||
.build()
|
||||
);
|
||||
if ( sSelectedCard >= 0 && sSelectedCard < sCards.size() ) {
|
||||
payment.setDescription(sCards.get(sSelectedCard));
|
||||
findActionById(ACTION_ID_CONFIRM).setEnabled(true);
|
||||
} else
|
||||
findActionById(ACTION_ID_CONFIRM).setEnabled(false);
|
||||
notifyActionChanged(findActionPositionById(ACTION_ID_CONFIRM));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSubGuidedActionClicked(GuidedAction action) {
|
||||
|
||||
if (action.isChecked()) {
|
||||
String payment = action.getTitle().toString();
|
||||
if ( (sSelectedCard = sCards.indexOf(payment)) != -1 ) {
|
||||
findActionById(ACTION_ID_PAYMENT_METHOD).setDescription(payment);
|
||||
notifyActionChanged(findActionPositionById(ACTION_ID_PAYMENT_METHOD));
|
||||
findActionById(ACTION_ID_CONFIRM).setEnabled(true);
|
||||
notifyActionChanged(findActionPositionById(ACTION_ID_CONFIRM));
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
action.setDescription(getString(R.string.wizard_example_input_credit_wrong));
|
||||
FragmentManager fm = getFragmentManager();
|
||||
GuidedStepFragment fragment = new WizardNewPaymentStepFragment();
|
||||
fragment.setArguments(getArguments());
|
||||
add(fm, fragment);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ import android.support.v17.leanback.supportleanbackshowcase.R;
|
||||
*/
|
||||
public class WizardExampleActivity extends Activity {
|
||||
|
||||
@Override public void onCreate(Bundle savedInstanceState) {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setBackgroundDrawableResource(R.drawable.wizard_background_blackned);
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
package android.support.v17.leanback.supportleanbackshowcase.app.wizard;
|
||||
|
||||
import android.app.FragmentManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v17.leanback.supportleanbackshowcase.R;
|
||||
import android.support.v17.leanback.widget.GuidanceStylist;
|
||||
import android.support.v17.leanback.widget.GuidedAction;
|
||||
import android.support.v17.leanback.widget.GuidedDatePickerAction;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by keyvana on 2/8/16.
|
||||
*/
|
||||
public class WizardNewPaymentStepFragment extends WizardExampleBaseStepFragment {
|
||||
|
||||
private static final int ACTION_ID_CARD_NUMBER = 1;
|
||||
private static final int ACTION_ID_PAYMENT_EXP = ACTION_ID_CARD_NUMBER + 1;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
|
||||
String title = getString(R.string.wizard_example_new_payment_guidance_title);
|
||||
String description = getString(R.string.wizard_example_new_payment_guidance_description);
|
||||
String breadcrumb = mMovie.getBreadcrump();
|
||||
|
||||
GuidanceStylist.Guidance guidance = new GuidanceStylist.Guidance(title, description,
|
||||
breadcrumb, null);
|
||||
return guidance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
|
||||
actions.add(new GuidedAction.Builder(getActivity())
|
||||
.id(ACTION_ID_CARD_NUMBER)
|
||||
.title(R.string.wizard_example_input_card)
|
||||
.editTitle("")
|
||||
.description(R.string.wizard_example_input_card)
|
||||
.editDescription("Card number")
|
||||
.editable(true)
|
||||
.build()
|
||||
);
|
||||
|
||||
actions.add(new GuidedDatePickerAction.Builder(getActivity())
|
||||
.id(ACTION_ID_PAYMENT_EXP)
|
||||
.title(R.string.wizard_example_expiration_date)
|
||||
.datePickerFormat("MY")
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateButtonActions(@NonNull List<GuidedAction> actions,
|
||||
Bundle savedInstanceState) {
|
||||
actions.add(new GuidedAction.Builder(getActivity())
|
||||
.clickAction(GuidedAction.ACTION_ID_OK)
|
||||
.build()
|
||||
);
|
||||
actions.get(actions.size() - 1).setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuidedActionClicked(GuidedAction action) {
|
||||
if (action.getId() == GuidedAction.ACTION_ID_OK) {
|
||||
CharSequence cardNumber = findActionById(ACTION_ID_CARD_NUMBER).getDescription();
|
||||
WizardExample2ndStepFragment.sSelectedCard = WizardExample2ndStepFragment.sCards.size();
|
||||
WizardExample2ndStepFragment.sCards.add(cardNumber.toString());
|
||||
popBackStackToGuidedStepFragment(WizardNewPaymentStepFragment.class,
|
||||
FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long onGuidedActionEditedAndProceed(GuidedAction action) {
|
||||
|
||||
boolean cardNumberCheck = false;
|
||||
boolean expDateCheck = false;
|
||||
|
||||
if (action.getId() == ACTION_ID_CARD_NUMBER) {
|
||||
CharSequence cardNumber = action.getEditTitle();
|
||||
cardNumberCheck = isCardNumberValid(cardNumber);
|
||||
expDateCheck = isExpDateValid(findActionById(ACTION_ID_PAYMENT_EXP));
|
||||
updateOkButton(cardNumberCheck && expDateCheck);
|
||||
|
||||
if (cardNumberCheck) {
|
||||
String last4Digits = cardNumber.subSequence(cardNumber.length() - 4,
|
||||
cardNumber.length()).toString();
|
||||
|
||||
if ( (Integer.parseInt(last4Digits) & 1) == 0 )
|
||||
action.setDescription(getString(R.string.wizard_example_visa,
|
||||
last4Digits));
|
||||
else
|
||||
action.setDescription(getString(R.string.wizard_example_master,
|
||||
last4Digits));
|
||||
|
||||
return GuidedAction.ACTION_ID_NEXT;
|
||||
} else if (cardNumber.length() == 0) {
|
||||
action.setDescription(getString(R.string.wizard_example_input_card));
|
||||
return GuidedAction.ACTION_ID_CURRENT;
|
||||
} else {
|
||||
action.setDescription(getString(R.string.wizard_example_input_credit_wrong));
|
||||
return GuidedAction.ACTION_ID_CURRENT;
|
||||
}
|
||||
|
||||
} else if (action.getId() == ACTION_ID_PAYMENT_EXP) {
|
||||
expDateCheck = isExpDateValid(action);
|
||||
cardNumberCheck = isCardNumberValid(findActionById(ACTION_ID_CARD_NUMBER)
|
||||
.getEditTitle());
|
||||
updateOkButton(cardNumberCheck && expDateCheck);
|
||||
if (expDateCheck) {
|
||||
return GuidedAction.ACTION_ID_NEXT;
|
||||
}
|
||||
}
|
||||
return GuidedAction.ACTION_ID_CURRENT;
|
||||
}
|
||||
|
||||
private void updateOkButton(boolean enabled) {
|
||||
findButtonActionById(GuidedAction.ACTION_ID_OK).setEnabled(enabled);
|
||||
notifyButtonActionChanged(findButtonActionPositionById(GuidedAction.ACTION_ID_OK));
|
||||
}
|
||||
|
||||
private static boolean isCardNumberValid(CharSequence number) {
|
||||
return (TextUtils.isDigitsOnly(number) && number.length() == 16);
|
||||
}
|
||||
|
||||
private static boolean isExpDateValid(GuidedAction dateAction) {
|
||||
long date = ((GuidedDatePickerAction) dateAction).getDate();
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTimeInMillis(date);
|
||||
return Calendar.getInstance().before(c);
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@
|
||||
<color name="detail_view_background">#0374BF</color>
|
||||
<color name="detail_view_related_background">#022A4E</color>
|
||||
|
||||
<color name="guidedstep_actions_background">#C03800</color>
|
||||
<color name="guidedstep_dialog_actions_background">#263238</color>
|
||||
<color name="app_guidedstep_actions_background">#C03800</color>
|
||||
<color name="app_guidedstep_subactions_background">#C03800</color>
|
||||
<color name="app_guidedstep_dialog_actions_background">#263238</color>
|
||||
</resources>
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
<string name="wizard_example_watch_hd">Watch in HD on supported devices</string>
|
||||
<string name="wizard_example_watch_sd">Watch in standard definition on the web and supported devices</string>
|
||||
<string name="wizard_example_rental_period">Rental period: start within 30 days,\nfinish within 24 hours</string>
|
||||
<string name="wizard_example_input_card">Enter credit card number</string>
|
||||
<string name="wizard_example_expiration_date">Exp. date</string>
|
||||
<string name="wizard_example_payment_method">Payment Method</string>
|
||||
<string name="wizard_example_toast_payment_method_clicked">\'Payment Method\' clicked.</string>
|
||||
<string name="wizard_example_rent">Rent</string>
|
||||
@@ -51,8 +53,11 @@
|
||||
<string name="wizard_example_watch_now">Watch now</string>
|
||||
<string name="wizard_example_later">Later</string>
|
||||
<string name="wizard_example_watch_now_clicked">\'Watch now\' clicked.</string>
|
||||
<string name="wizard_example_input_credit">Input credit card number</string>
|
||||
<string name="wizard_example_visa">Visa XXXX-XXXX-XXXX-%s</string>
|
||||
<string name="wizard_example_input_credit_wrong">Error credit card number</string>
|
||||
<string name="wizard_example_new_payment_guidance_title">New credit card</string>
|
||||
<string name="wizard_example_new_payment_guidance_description">Enter new credit card information here</string>
|
||||
<string name="wizard_example_input_credit">Input Payment Type</string>
|
||||
<string name="wizard_example_visa">Visa-%s</string>
|
||||
<string name="wizard_example_master">Master-%s</string>
|
||||
<string name="wizard_example_input_credit_wrong">Error: invalid credit card number</string>
|
||||
s<string name="wizard_example_just_a_second">Just a second...</string>
|
||||
</resources>
|
||||
@@ -35,7 +35,8 @@
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.LeanbackWizard" parent="Theme.Leanback.GuidedStep">
|
||||
<item name="guidedActionsBackground">@color/guidedstep_actions_background</item>
|
||||
<item name="guidedActionsBackground">@color/app_guidedstep_actions_background</item>
|
||||
<item name="guidedActionsBackgroundDark">@color/app_guidedstep_subactions_background</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.LeanbackWizard.NoSelector">
|
||||
@@ -43,7 +44,7 @@
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.LeanbackDialog" parent="Theme.Leanback.GuidedStep">
|
||||
<item name="guidedActionsBackground">@color/guidedstep_dialog_actions_background</item>
|
||||
<item name="guidedActionsBackground">@color/app_guidedstep_dialog_actions_background</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Example.LeanbackPreferences" parent="Theme.Leanback">
|
||||
|
||||
Reference in New Issue
Block a user