OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.payments.ui; | 5 package org.chromium.chrome.browser.payments.ui; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.content.res.Resources; | 8 import android.content.res.Resources; |
9 import android.graphics.Color; | 9 import android.graphics.Color; |
10 import android.graphics.Typeface; | 10 import android.graphics.Typeface; |
11 import android.graphics.drawable.Drawable; | 11 import android.graphics.drawable.Drawable; |
12 import android.os.Handler; | 12 import android.os.Handler; |
13 import android.support.v4.view.animation.LinearOutSlowInInterpolator; | 13 import android.support.v4.view.animation.LinearOutSlowInInterpolator; |
14 import android.support.v7.widget.GridLayout; | 14 import android.support.v7.widget.GridLayout; |
| 15 import android.text.Layout; |
15 import android.text.SpannableStringBuilder; | 16 import android.text.SpannableStringBuilder; |
| 17 import android.text.TextPaint; |
16 import android.text.TextUtils; | 18 import android.text.TextUtils; |
17 import android.text.TextUtils.TruncateAt; | 19 import android.text.TextUtils.TruncateAt; |
18 import android.text.style.AbsoluteSizeSpan; | 20 import android.text.style.AbsoluteSizeSpan; |
19 import android.text.style.ForegroundColorSpan; | 21 import android.text.style.ForegroundColorSpan; |
20 import android.text.style.StyleSpan; | 22 import android.text.style.StyleSpan; |
21 import android.view.Gravity; | 23 import android.view.Gravity; |
22 import android.view.LayoutInflater; | 24 import android.view.LayoutInflater; |
23 import android.view.MotionEvent; | 25 import android.view.MotionEvent; |
24 import android.view.View; | 26 import android.view.View; |
25 import android.view.ViewGroup; | 27 import android.view.ViewGroup; |
(...skipping 19 matching lines...) Expand all Loading... |
45 | 47 |
46 /** | 48 /** |
47 * Represents a single section in the {@link PaymentRequestUI} that flips betwee
n multiple states. | 49 * Represents a single section in the {@link PaymentRequestUI} that flips betwee
n multiple states. |
48 * | 50 * |
49 * The row is broken up into three major, vertically-centered sections: | 51 * The row is broken up into three major, vertically-centered sections: |
50 * .............................................................................
................ | 52 * .............................................................................
................ |
51 * . TITLE |
| CHEVRON . | 53 * . TITLE |
| CHEVRON . |
52 * .................................................................|
| or . | 54 * .................................................................|
| or . |
53 * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT |
LOGO | ADD . | 55 * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT |
LOGO | ADD . |
54 * .................................................................|
| or . | 56 * .................................................................|
| or . |
55 * . MAIN SECTION CONTENT |
| SELECT . | 57 * . MAIN SECTION CONTENT |
| CHOOSE . |
56 * .............................................................................
................ | 58 * .............................................................................
................ |
57 * | 59 * |
58 * 1) MAIN CONTENT | 60 * 1) MAIN CONTENT |
59 * The main content is on the left side of the UI. This includes the title o
f the section and | 61 * The main content is on the left side of the UI. This includes the title o
f the section and |
60 * two bits of optional summary text. Subclasses may extend this class to ap
pend more controls | 62 * two bits of optional summary text. Subclasses may extend this class to ap
pend more controls |
61 * via the {@link #createMainSectionContent} function. | 63 * via the {@link #createMainSectionContent} function. |
62 * | 64 * |
63 * 2) LOGO | 65 * 2) LOGO |
64 * Displays an optional logo (e.g. a credit card image) that floats to the ri
ght of the main | 66 * Displays an optional logo (e.g. a credit card image) that floats to the ri
ght of the main |
65 * content. | 67 * content. |
66 * | 68 * |
67 * 3) CHEVRON or ADD or SELECT | 69 * 3) CHEVRON or ADD or CHOOSE |
68 * Drawn to indicate that the current section may be expanded. Displayed onl
y when the view is | 70 * Drawn to indicate that the current section may be expanded. Displayed onl
y when the view is |
69 * in the {@link #DISPLAY_MODE_EXPANDABLE} state and only if an ADD or SELECT
button isn't shown. | 71 * in the {@link #DISPLAY_MODE_EXPANDABLE} state and only if an ADD or CHOOSE
button isn't shown. |
70 * | 72 * |
71 * There are three states that the UI may flip between; see {@link #DISPLAY_MODE
_NORMAL}, | 73 * There are three states that the UI may flip between; see {@link #DISPLAY_MODE
_NORMAL}, |
72 * {@link #DISPLAY_MODE_EXPANDABLE}, and {@link #DISPLAY_MODE_FOCUSED} for detai
ls. | 74 * {@link #DISPLAY_MODE_EXPANDABLE}, and {@link #DISPLAY_MODE_FOCUSED} for detai
ls. |
73 */ | 75 */ |
74 public abstract class PaymentRequestSection extends LinearLayout implements View
.OnClickListener { | 76 public abstract class PaymentRequestSection extends LinearLayout implements View
.OnClickListener { |
75 public static final String TAG = "PaymentRequestUI"; | 77 public static final String TAG = "PaymentRequestUI"; |
76 | 78 |
77 /** Handles clicks on the widgets and providing data to the PaymentsRequestS
ection. */ | 79 /** Handles clicks on the widgets and providing data to the PaymentsRequestS
ection. */ |
78 public interface SectionDelegate extends View.OnClickListener { | 80 public interface SectionDelegate extends View.OnClickListener { |
79 /** | 81 /** |
(...skipping 23 matching lines...) Expand all Loading... |
103 boolean isAdditionalTextDisplayingWarning(PaymentRequestSection section)
; | 105 boolean isAdditionalTextDisplayingWarning(PaymentRequestSection section)
; |
104 | 106 |
105 /** Called when a section has been clicked. */ | 107 /** Called when a section has been clicked. */ |
106 void onSectionClicked(PaymentRequestSection section); | 108 void onSectionClicked(PaymentRequestSection section); |
107 } | 109 } |
108 | 110 |
109 /** Edit button mode: Hide the button. */ | 111 /** Edit button mode: Hide the button. */ |
110 public static final int EDIT_BUTTON_GONE = 0; | 112 public static final int EDIT_BUTTON_GONE = 0; |
111 | 113 |
112 /** Edit button mode: Indicate that the section requires a selection. */ | 114 /** Edit button mode: Indicate that the section requires a selection. */ |
113 public static final int EDIT_BUTTON_SELECT = 1; | 115 public static final int EDIT_BUTTON_CHOOSE = 1; |
114 | 116 |
115 /** Edit button mode: Indicate that the section requires adding an option. *
/ | 117 /** Edit button mode: Indicate that the section requires adding an option. *
/ |
116 public static final int EDIT_BUTTON_ADD = 2; | 118 public static final int EDIT_BUTTON_ADD = 2; |
117 | 119 |
118 /** Normal mode: White background, displays the item assuming the user accep
ts it as is. */ | 120 /** Normal mode: White background, displays the item assuming the user accep
ts it as is. */ |
119 static final int DISPLAY_MODE_NORMAL = 3; | 121 static final int DISPLAY_MODE_NORMAL = 3; |
120 | 122 |
121 /** Editable mode: White background, displays the item with an edit chevron.
*/ | 123 /** Editable mode: White background, displays the item with an edit chevron.
*/ |
122 static final int DISPLAY_MODE_EXPANDABLE = 4; | 124 static final int DISPLAY_MODE_EXPANDABLE = 4; |
123 | 125 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 assert mSummaryLayout != null; | 205 assert mSummaryLayout != null; |
204 return mSummaryLayout; | 206 return mSummaryLayout; |
205 } | 207 } |
206 | 208 |
207 /** Returns the right summary TextView. */ | 209 /** Returns the right summary TextView. */ |
208 protected TextView getSummaryRightTextView() { | 210 protected TextView getSummaryRightTextView() { |
209 assert mSummaryRightTextView != null; | 211 assert mSummaryRightTextView != null; |
210 return mSummaryRightTextView; | 212 return mSummaryRightTextView; |
211 } | 213 } |
212 | 214 |
| 215 /** Returns the left summary TextView. */ |
| 216 protected TextView getSummaryLeftTextView() { |
| 217 assert mSummaryLeftTextView != null; |
| 218 return mSummaryLeftTextView; |
| 219 } |
| 220 |
213 @Override | 221 @Override |
214 public boolean onInterceptTouchEvent(MotionEvent event) { | 222 public boolean onInterceptTouchEvent(MotionEvent event) { |
215 // Allow touches to propagate to children only if the layout can be inte
racted with. | 223 // Allow touches to propagate to children only if the layout can be inte
racted with. |
216 return !mDelegate.isAcceptingUserInput(); | 224 return !mDelegate.isAcceptingUserInput(); |
217 } | 225 } |
218 | 226 |
219 @Override | 227 @Override |
220 public final void onClick(View v) { | 228 public final void onClick(View v) { |
221 if (!mDelegate.isAcceptingUserInput()) return; | 229 if (!mDelegate.isAcceptingUserInput()) return; |
222 | 230 |
223 // Handle clicking on "ADD" or "SELECT". | 231 // Handle clicking on "ADD" or "CHOOSE". |
224 if (v == mEditButtonView) { | 232 if (v == mEditButtonView) { |
225 if (getEditButtonState() == EDIT_BUTTON_ADD) { | 233 if (getEditButtonState() == EDIT_BUTTON_ADD) { |
226 mDelegate.onAddPaymentOption(this); | 234 mDelegate.onAddPaymentOption(this); |
227 } else { | 235 } else { |
228 mDelegate.onSectionClicked(this); | 236 mDelegate.onSectionClicked(this); |
229 } | 237 } |
230 return; | 238 return; |
231 } | 239 } |
232 | 240 |
233 handleClick(v); | 241 handleClick(v); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 LayoutParams params = | 399 LayoutParams params = |
392 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CO
NTENT); | 400 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CO
NTENT); |
393 ApiCompatibilityUtils.setMarginStart(params, startMargin); | 401 ApiCompatibilityUtils.setMarginStart(params, startMargin); |
394 parent.addView(view, params); | 402 parent.addView(view, params); |
395 return view; | 403 return view; |
396 } | 404 } |
397 | 405 |
398 private Button createAndAddEditButton(ViewGroup parent) { | 406 private Button createAndAddEditButton(ViewGroup parent) { |
399 Resources resources = parent.getResources(); | 407 Resources resources = parent.getResources(); |
400 Button view = DualControlLayout.createButtonForLayout( | 408 Button view = DualControlLayout.createButtonForLayout( |
401 parent.getContext(), true, resources.getString(R.string.select),
this); | 409 parent.getContext(), true, resources.getString(R.string.choose),
this); |
402 view.setId(R.id.payments_section); | 410 view.setId(R.id.payments_section); |
403 | 411 |
404 LayoutParams params = | 412 LayoutParams params = |
405 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CO
NTENT); | 413 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CO
NTENT); |
406 ApiCompatibilityUtils.setMarginStart(params, mLargeSpacing); | 414 ApiCompatibilityUtils.setMarginStart(params, mLargeSpacing); |
407 parent.addView(view, params); | 415 parent.addView(view, params); |
408 return view; | 416 return view; |
409 } | 417 } |
410 | 418 |
411 private ImageView createAndAddChevron(ViewGroup parent) { | 419 private ImageView createAndAddChevron(ViewGroup parent) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 boolean show = mLogo != null && mDisplayMode != DISPLAY_MODE_FOCUSED
; | 452 boolean show = mLogo != null && mDisplayMode != DISPLAY_MODE_FOCUSED
; |
445 mLogoView.setVisibility(show ? VISIBLE : GONE); | 453 mLogoView.setVisibility(show ? VISIBLE : GONE); |
446 } | 454 } |
447 | 455 |
448 // The button takes precedence over the summary text and the chevron. | 456 // The button takes precedence over the summary text and the chevron. |
449 int editButtonState = getEditButtonState(); | 457 int editButtonState = getEditButtonState(); |
450 if (editButtonState == EDIT_BUTTON_GONE) { | 458 if (editButtonState == EDIT_BUTTON_GONE) { |
451 mEditButtonView.setVisibility(GONE); | 459 mEditButtonView.setVisibility(GONE); |
452 mChevronView.setVisibility( | 460 mChevronView.setVisibility( |
453 mDisplayMode == DISPLAY_MODE_EXPANDABLE ? VISIBLE : GONE); | 461 mDisplayMode == DISPLAY_MODE_EXPANDABLE ? VISIBLE : GONE); |
454 | |
455 // Update whether the summary is displayed. | |
456 boolean showSummary = | |
457 mIsSummaryAllowed && !TextUtils.isEmpty(mSummaryLeftTextView
.getText()); | |
458 mSummaryLayout.setVisibility(showSummary ? VISIBLE : GONE); | |
459 } else { | 462 } else { |
460 // Show the edit button and hide the chevron and the summary. | 463 // Show the edit button and hide the chevron and the summary. |
461 boolean isButtonAllowed = mDisplayMode == DISPLAY_MODE_EXPANDABLE | 464 boolean isButtonAllowed = mDisplayMode == DISPLAY_MODE_EXPANDABLE |
462 || mDisplayMode == DISPLAY_MODE_NORMAL; | 465 || mDisplayMode == DISPLAY_MODE_NORMAL; |
463 mSummaryLayout.setVisibility(GONE); | |
464 mChevronView.setVisibility(GONE); | 466 mChevronView.setVisibility(GONE); |
465 mEditButtonView.setVisibility(isButtonAllowed ? VISIBLE : GONE); | 467 mEditButtonView.setVisibility(isButtonAllowed ? VISIBLE : GONE); |
466 mEditButtonView.setText( | 468 mEditButtonView.setText( |
467 editButtonState == EDIT_BUTTON_SELECT ? R.string.select : R.
string.add); | 469 editButtonState == EDIT_BUTTON_CHOOSE ? R.string.choose : R.
string.add); |
468 } | 470 } |
469 | 471 |
| 472 // Update whether the summary is displayed. |
| 473 mSummaryLayout.setVisibility(mIsSummaryAllowed ? VISIBLE : GONE); |
| 474 |
470 // The title gains extra spacing when there is another visible view in t
he main section. | 475 // The title gains extra spacing when there is another visible view in t
he main section. |
471 int numVisibleMainViews = 0; | 476 int numVisibleMainViews = 0; |
472 for (int i = 0; i < mMainSection.getChildCount(); i++) { | 477 for (int i = 0; i < mMainSection.getChildCount(); i++) { |
473 if (mMainSection.getChildAt(i).getVisibility() == VISIBLE) numVisibl
eMainViews += 1; | 478 if (mMainSection.getChildAt(i).getVisibility() == VISIBLE) numVisibl
eMainViews += 1; |
474 } | 479 } |
475 | 480 |
476 boolean isTitleMarginNecessary = numVisibleMainViews > 1 && isExpanded; | 481 boolean isTitleMarginNecessary = numVisibleMainViews > 1 && isExpanded; |
477 int oldMargin = | 482 int oldMargin = |
478 ((ViewGroup.MarginLayoutParams) mTitleView.getLayoutParams()).bo
ttomMargin; | 483 ((ViewGroup.MarginLayoutParams) mTitleView.getLayoutParams()).bo
ttomMargin; |
479 int newMargin = isTitleMarginNecessary ? mVerticalSpacing : 0; | 484 int newMargin = isTitleMarginNecessary ? mVerticalSpacing : 0; |
480 | 485 |
481 if (oldMargin != newMargin) { | 486 if (oldMargin != newMargin) { |
482 ((ViewGroup.MarginLayoutParams) mTitleView.getLayoutParams()).bottom
Margin = | 487 ((ViewGroup.MarginLayoutParams) mTitleView.getLayoutParams()).bottom
Margin = |
483 newMargin; | 488 newMargin; |
484 requestLayout(); | 489 requestLayout(); |
485 } | 490 } |
486 } | 491 } |
487 | 492 |
488 /** | 493 /** |
489 * Section with three extra TextViews beneath the summary to show additional
details. | 494 * Section with three extra TextViews beneath the summary to show additional
shipping details. |
490 * | 495 * |
491 * .........................................................................
... | 496 * .........................................................................
... |
492 * . TITLE |
. | 497 * . TITLE |
. |
493 * .................................................................|
. | 498 * .................................................................|
. |
494 * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | CHEVRO
N . | 499 * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | CHEVRO
N . |
495 * .................................................................| or
. | 500 * .................................................................| or
. |
496 * . EXTRA TEXT ONE | ADD
. | 501 * . EXTRA TEXT ONE | ADD
. |
497 * .................................................................| or
. | 502 * .................................................................| or
. |
498 * . EXTRA TEXT TWO | SELEC
T . | 503 * . EXTRA TEXT TWO | CHOOS
E . |
499 * .................................................................|
. | 504 * .................................................................|
. |
500 * . EXTRA TEXT THREE |
. | 505 * . EXTRA TEXT THREE |
. |
501 * .........................................................................
... | 506 * .........................................................................
... |
502 */ | 507 */ |
503 public static class ExtraTextsSection extends PaymentRequestSection { | 508 public static class ShippingSummarySection extends PaymentRequestSection { |
504 private TextView[] mExtraTextViews; | 509 private TextView[] mExtraTextViews; |
505 private int mEditButtonState = EDIT_BUTTON_GONE; | 510 private int mEditButtonState = EDIT_BUTTON_GONE; |
506 | 511 |
507 public ExtraTextsSection(Context context, String sectionName, SectionDel
egate delegate) { | 512 public ShippingSummarySection( |
| 513 Context context, String sectionName, SectionDelegate delegate) { |
508 super(context, sectionName, delegate); | 514 super(context, sectionName, delegate); |
509 setExtraTexts(new String[] {null, null, null}); | 515 setExtraTexts(new String[] {null, null, null}); |
510 } | 516 } |
511 | 517 |
512 @Override | 518 @Override |
513 protected void createMainSectionContent(LinearLayout mainSectionLayout)
{ | 519 protected void createMainSectionContent(LinearLayout mainSectionLayout)
{ |
514 Context context = mainSectionLayout.getContext(); | 520 Context context = mainSectionLayout.getContext(); |
515 | 521 |
516 mExtraTextViews = new TextView[3]; | 522 mExtraTextViews = new TextView[3]; |
517 for (int i = 0; i < mExtraTextViews.length; i++) { | 523 for (int i = 0; i < mExtraTextViews.length; i++) { |
518 mExtraTextViews[i] = new TextView(context); | 524 mExtraTextViews[i] = new TextView(context); |
519 ApiCompatibilityUtils.setTextAppearance( | 525 ApiCompatibilityUtils.setTextAppearance( |
520 mExtraTextViews[i], R.style.PaymentsUiSectionDefaultText
); | 526 mExtraTextViews[i], R.style.PaymentsUiSectionDefaultText
); |
521 mainSectionLayout.addView( | 527 mainSectionLayout.addView( |
522 mExtraTextViews[i], new LinearLayout.LayoutParams(Layout
Params.MATCH_PARENT, | 528 mExtraTextViews[i], new LinearLayout.LayoutParams(Layout
Params.MATCH_PARENT, |
523 LayoutParams.WRAP_CONTENT)); | 529 LayoutParams.WRAP_CONTENT)); |
524 } | 530 } |
525 } | 531 } |
526 | 532 |
| 533 /** Updates the View to account for the new {@link ShippingSummaryInform
ation} being passed |
| 534 * in. */ |
| 535 public void update(ShippingSummaryInformation info) { |
| 536 String selectedShippingName = info.getSelectedShippingAddressLabel()
; |
| 537 String selectedShippingAddress = info.getSelectedShippingAddressSubl
abel(); |
| 538 String selectedShippingPhone = info.getSelectedShippingAddressTertia
ryLabel(); |
| 539 String selectedShippingOptionLabel = info.getSelectedShippingOptionL
abel(); |
| 540 |
| 541 // Display the summary in a single line. |
| 542 setSummaryProperties(TruncateAt.END, true /* leftIsSingleLine */, |
| 543 null /* rightTruncate */, false /* rightIsSingleLine */); |
| 544 if (selectedShippingAddress == null || selectedShippingOptionLabel =
= null) { |
| 545 ApiCompatibilityUtils.setTextAppearance( |
| 546 getSummaryLeftTextView(), R.style.PaymentsUiSectionDescr
iptiveText); |
| 547 SectionUiUtils.showSectionSummaryInTextViewInSingeLine(getContex
t(), |
| 548 info.getShippingAddressSectionInfo(), getSummaryLeftText
View()); |
| 549 } else { |
| 550 // Show the shipping name in the summary section. |
| 551 setSummaryText(selectedShippingName, null); |
| 552 |
| 553 // Show the shipping address, phone and option below the summary
. |
| 554 setExtraTextsProperties( |
| 555 new TruncateAt[] {TruncateAt.MIDDLE, TruncateAt.END, Tru
ncateAt.END}, |
| 556 new boolean[] {true, true, true}); |
| 557 setExtraTexts(new String[] {selectedShippingAddress, selectedShi
ppingPhone, |
| 558 selectedShippingOptionLabel}); |
| 559 } |
| 560 } |
| 561 |
527 /** | 562 /** |
528 * Sets the CharSequences that are displayed in the extra TextViews. | 563 * Sets the CharSequences that are displayed in the extra TextViews. |
529 * | 564 * |
530 * @param extraTexts Texts to display in the extra TextViews. | 565 * @param extraTexts Texts to display in the extra TextViews. |
531 */ | 566 */ |
532 public void setExtraTexts(CharSequence[] extraTexts) { | 567 private void setExtraTexts(CharSequence[] extraTexts) { |
533 assert extraTexts.length == mExtraTextViews.length; | 568 assert extraTexts.length == mExtraTextViews.length; |
534 | 569 |
535 for (int i = 0; i < mExtraTextViews.length; i++) { | 570 for (int i = 0; i < mExtraTextViews.length; i++) { |
536 mExtraTextViews[i].setText(extraTexts[i]); | 571 mExtraTextViews[i].setText(extraTexts[i]); |
537 mExtraTextViews[i].setVisibility(TextUtils.isEmpty(extraTexts[i]
) ? GONE : VISIBLE); | 572 mExtraTextViews[i].setVisibility(TextUtils.isEmpty(extraTexts[i]
) ? GONE : VISIBLE); |
538 } | 573 } |
539 } | 574 } |
540 | 575 |
541 /** | 576 /** |
542 * Sets how the extra texts should be displayed. | 577 * Sets how the extra texts should be displayed. |
543 * | 578 * |
544 * @param textsTruncate How to truncate the extra texts. Set the element
to null to clear. | 579 * @param textsTruncate How to truncate the extra texts. Set the element
to null to clear. |
545 * @param textsAreSingleLine Whether the extra texts should be displayed
in a single line. | 580 * @param textsAreSingleLine Whether the extra texts should be displayed
in a single line. |
546 */ | 581 */ |
547 public void setExtraTextsProperties( | 582 private void setExtraTextsProperties( |
548 TruncateAt[] textsTruncate, boolean[] textsAreSingleLine) { | 583 TruncateAt[] textsTruncate, boolean[] textsAreSingleLine) { |
549 assert textsTruncate.length == mExtraTextViews.length; | 584 assert textsTruncate.length == mExtraTextViews.length; |
550 assert textsAreSingleLine.length == mExtraTextViews.length; | 585 assert textsAreSingleLine.length == mExtraTextViews.length; |
551 | 586 |
552 for (int i = 0; i < mExtraTextViews.length; i++) { | 587 for (int i = 0; i < mExtraTextViews.length; i++) { |
553 mExtraTextViews[i].setEllipsize(textsTruncate[i]); | 588 mExtraTextViews[i].setEllipsize(textsTruncate[i]); |
554 mExtraTextViews[i].setSingleLine(textsAreSingleLine[i]); | 589 mExtraTextViews[i].setSingleLine(textsAreSingleLine[i]); |
555 } | 590 } |
556 } | 591 } |
557 | 592 |
(...skipping 16 matching lines...) Expand all Loading... |
574 * If no option is selected, the "empty label" is displayed
in its place. | 609 * If no option is selected, the "empty label" is displayed
in its place. |
575 * Expandable mode: Same as Normal, but shows the chevron. | 610 * Expandable mode: Same as Normal, but shows the chevron. |
576 * Focused mode: Hides the summary and chevron, then displays the full se
t of options. | 611 * Focused mode: Hides the summary and chevron, then displays the full se
t of options. |
577 * | 612 * |
578 * .........................................................................
... | 613 * .........................................................................
... |
579 * . TITLE |
. | 614 * . TITLE |
. |
580 * .................................................................| CHERVO
N . | 615 * .................................................................| CHERVO
N . |
581 * . LEFT SUMMARY TEXT | UPDATE TEXT | RIGHT SUMMARY TEXT | or
. | 616 * . LEFT SUMMARY TEXT | UPDATE TEXT | RIGHT SUMMARY TEXT | or
. |
582 * .................................................................| ADD
. | 617 * .................................................................| ADD
. |
583 * . | Line item 1 | $13.99 | or
. | 618 * . | Line item 1 | $13.99 | or
. |
584 * . | Line item 2 | $.99 | SELEC
T . | 619 * . | Line item 2 | $.99 | CHOOS
E . |
585 * . | Line item 3 | $2.99 |
. | 620 * . | Line item 3 | $2.99 |
. |
586 * .........................................................................
... | 621 * .........................................................................
... |
587 */ | 622 */ |
588 public static class LineItemBreakdownSection extends PaymentRequestSection { | 623 public static class LineItemBreakdownSection extends PaymentRequestSection { |
589 /** The duration of the animation to show and hide the update text. */ | 624 /** The duration of the animation to show and hide the update text. */ |
590 static final int UPDATE_TEXT_ANIMATION_DURATION_MS = 500; | 625 static final int UPDATE_TEXT_ANIMATION_DURATION_MS = 500; |
591 | 626 |
592 /** The amount of time where the update text is visible before fading ou
t. */ | 627 /** The amount of time where the update text is visible before fading ou
t. */ |
593 static final int UPDATE_TEXT_VISIBILITY_DURATION_MS = 5000; | 628 static final int UPDATE_TEXT_VISIBILITY_DURATION_MS = 5000; |
594 | 629 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 * Focused mode: Hides the summary and chevron, then displays the full se
t of options. | 854 * Focused mode: Hides the summary and chevron, then displays the full se
t of options. |
820 * | 855 * |
821 * .........................................................................
.................... | 856 * .........................................................................
.................... |
822 * . TITLE |
| . | 857 * . TITLE |
| . |
823 * .................................................................|
| . | 858 * .................................................................|
| . |
824 * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT |
| . | 859 * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT |
| . |
825 * .................................................................|
| CHEVRON . | 860 * .................................................................|
| CHEVRON . |
826 * . Descriptive text that spans all three columns because it can. |
| or . | 861 * . Descriptive text that spans all three columns because it can. |
| or . |
827 * . ! Warning text that displays a big scary warning and icon. |
LOGO | ADD . | 862 * . ! Warning text that displays a big scary warning and icon. |
LOGO | ADD . |
828 * . O Option 1 ICON 1 | Edit Icon |
| or . | 863 * . O Option 1 ICON 1 | Edit Icon |
| or . |
829 * . O Option 2 ICON 2 | Edit Icon |
| SELECT . | 864 * . O Option 2 ICON 2 | Edit Icon |
| CHOOSE . |
830 * . O Option 3 ICON 3 | Edit Icon |
| . | 865 * . O Option 3 ICON 3 | Edit Icon |
| . |
831 * . + ADD THING |
| . | 866 * . + ADD THING |
| . |
832 * .........................................................................
.................... | 867 * .........................................................................
.................... |
833 */ | 868 */ |
834 public static class OptionSection extends PaymentRequestSection { | 869 public static class OptionSection extends PaymentRequestSection { |
835 | 870 |
836 private static final int INVALID_OPTION_INDEX = -1; | 871 private static final int INVALID_OPTION_INDEX = -1; |
837 | 872 |
838 private final List<TextView> mLabelsForTest = new ArrayList<>(); | 873 private final List<TextView> mLabelsForTest = new ArrayList<>(); |
839 private boolean mCanAddItems = true; | 874 private boolean mCanAddItems = true; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 ? createOptionIcon(parent, rowIndex, editIconExists) : n
ull; | 922 ? createOptionIcon(parent, rowIndex, editIconExists) : n
ull; |
888 mEditIcon = editIconExists ? createEditIcon(parent, rowIndex) :
null; | 923 mEditIcon = editIconExists ? createEditIcon(parent, rowIndex) :
null; |
889 } | 924 } |
890 | 925 |
891 /** Sets the selected state of this item, alerting the delegate if s
elected. */ | 926 /** Sets the selected state of this item, alerting the delegate if s
elected. */ |
892 public void setChecked(boolean isChecked) { | 927 public void setChecked(boolean isChecked) { |
893 if (mOption == null) return; | 928 if (mOption == null) return; |
894 | 929 |
895 ((RadioButton) mButton).setChecked(isChecked); | 930 ((RadioButton) mButton).setChecked(isChecked); |
896 if (isChecked) { | 931 if (isChecked) { |
897 updateSelectedItem(mOption); | |
898 mDelegate.onPaymentOptionChanged(OptionSection.this, mOption
); | 932 mDelegate.onPaymentOptionChanged(OptionSection.this, mOption
); |
899 } | 933 } |
900 } | 934 } |
901 | 935 |
902 /** Returns whether this OptionRow's RadioButton is checked. */ | 936 /** Returns whether this OptionRow's RadioButton is checked. */ |
903 public boolean isChecked() { | 937 public boolean isChecked() { |
904 return ((RadioButton) mButton).isChecked(); | 938 return ((RadioButton) mButton).isChecked(); |
905 } | 939 } |
906 | 940 |
907 /** Change the label for the row. */ | 941 /** Change the label for the row. */ |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 | 1143 |
1110 /** A spinner to show when the user selection is being checked. */ | 1144 /** A spinner to show when the user selection is being checked. */ |
1111 private View mCheckingProgress; | 1145 private View mCheckingProgress; |
1112 | 1146 |
1113 /** SectionInformation that is used to populate the views in this sectio
n. */ | 1147 /** SectionInformation that is used to populate the views in this sectio
n. */ |
1114 private SectionInformation mSectionInformation; | 1148 private SectionInformation mSectionInformation; |
1115 | 1149 |
1116 /** Indicates whether the summary should be a single line. */ | 1150 /** Indicates whether the summary should be a single line. */ |
1117 private boolean mSummaryInSingleLine; | 1151 private boolean mSummaryInSingleLine; |
1118 | 1152 |
| 1153 /** Indicates whether the summary is set to R.style.PaymentsUiSectionDes
criptiveText. */ |
| 1154 private boolean mSummaryInDescriptiveText; |
| 1155 |
1119 private FocusChangedObserver mFocusChangedObserver; | 1156 private FocusChangedObserver mFocusChangedObserver; |
1120 | 1157 |
1121 /** | 1158 /** |
1122 * Constructs an OptionSection. | 1159 * Constructs an OptionSection. |
1123 * | 1160 * |
1124 * @param context Context to pull resources from. | 1161 * @param context Context to pull resources from. |
1125 * @param sectionName Title of the section to display. | 1162 * @param sectionName Title of the section to display. |
1126 * @param delegate Delegate to alert when something changes in the di
alog. | 1163 * @param delegate Delegate to alert when something changes in the di
alog. |
1127 */ | 1164 */ |
1128 public OptionSection(Context context, String sectionName, SectionDelegat
e delegate) { | 1165 public OptionSection(Context context, String sectionName, SectionDelegat
e delegate) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 setDisplayMode(PaymentRequestSection.DISPLAY_MODE_NORMAL); | 1216 setDisplayMode(PaymentRequestSection.DISPLAY_MODE_NORMAL); |
1180 return; | 1217 return; |
1181 } | 1218 } |
1182 | 1219 |
1183 // Notify the observer that the focus is going to change. | 1220 // Notify the observer that the focus is going to change. |
1184 if (mFocusChangedObserver != null) { | 1221 if (mFocusChangedObserver != null) { |
1185 mFocusChangedObserver.onFocusChanged( | 1222 mFocusChangedObserver.onFocusChanged( |
1186 mSectionInformation.getDataType(), shouldFocus); | 1223 mSectionInformation.getDataType(), shouldFocus); |
1187 } | 1224 } |
1188 | 1225 |
| 1226 int previousDisplayMode = mDisplayMode; |
1189 super.focusSection(shouldFocus); | 1227 super.focusSection(shouldFocus); |
| 1228 |
| 1229 // Update summary when display mode changed from DISPLAY_MODE_NORMAL
to other modes. |
| 1230 if (mSectionInformation != null && previousDisplayMode == DISPLAY_MO
DE_NORMAL) { |
| 1231 updateSelectedItem(mSectionInformation.getSelectedItem()); |
| 1232 } |
1190 } | 1233 } |
1191 | 1234 |
1192 @Override | 1235 @Override |
1193 protected boolean isLogoNecessary() { | 1236 protected boolean isLogoNecessary() { |
1194 return true; | 1237 return true; |
1195 } | 1238 } |
1196 | 1239 |
1197 @Override | 1240 @Override |
1198 public void setSummaryProperties(@Nullable TruncateAt leftTruncate, | |
1199 boolean leftIsSingleLine, @Nullable TruncateAt rightTruncate, | |
1200 boolean rightIsSingleLine) { | |
1201 super.setSummaryProperties( | |
1202 leftTruncate, leftIsSingleLine, rightTruncate, rightIsSingle
Line); | |
1203 | |
1204 // Updates the summary if necessary after properties are changed. | |
1205 mSummaryInSingleLine = leftIsSingleLine; | |
1206 if (mSectionInformation != null) { | |
1207 updateSelectedItem(mSectionInformation.getSelectedItem()); | |
1208 } | |
1209 } | |
1210 | |
1211 @Override | |
1212 protected void createMainSectionContent(LinearLayout mainSectionLayout)
{ | 1241 protected void createMainSectionContent(LinearLayout mainSectionLayout)
{ |
1213 Context context = mainSectionLayout.getContext(); | 1242 Context context = mainSectionLayout.getContext(); |
1214 mCheckingProgress = createLoadingSpinner(); | 1243 mCheckingProgress = createLoadingSpinner(); |
1215 | 1244 |
1216 mOptionLayout = new GridLayout(context); | 1245 mOptionLayout = new GridLayout(context); |
1217 mOptionLayout.setColumnCount(4); | 1246 mOptionLayout.setColumnCount(4); |
1218 mainSectionLayout.addView(mOptionLayout, new LinearLayout.LayoutPara
ms( | 1247 mainSectionLayout.addView(mOptionLayout, new LinearLayout.LayoutPara
ms( |
1219 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); | 1248 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); |
1220 } | 1249 } |
1221 | 1250 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 | 1318 |
1290 @Override | 1319 @Override |
1291 public int getEditButtonState() { | 1320 public int getEditButtonState() { |
1292 if (mSectionInformation == null) return EDIT_BUTTON_GONE; | 1321 if (mSectionInformation == null) return EDIT_BUTTON_GONE; |
1293 | 1322 |
1294 if (mSectionInformation.getSize() == 0 && mCanAddItems) { | 1323 if (mSectionInformation.getSize() == 0 && mCanAddItems) { |
1295 // There aren't any PaymentOptions. Ask the user to add a new o
ne. | 1324 // There aren't any PaymentOptions. Ask the user to add a new o
ne. |
1296 return EDIT_BUTTON_ADD; | 1325 return EDIT_BUTTON_ADD; |
1297 } else if (mSectionInformation.getSelectedItem() == null) { | 1326 } else if (mSectionInformation.getSelectedItem() == null) { |
1298 // The user hasn't selected any available PaymentOptions. Ask t
he user to pick one. | 1327 // The user hasn't selected any available PaymentOptions. Ask t
he user to pick one. |
1299 return EDIT_BUTTON_SELECT; | 1328 return EDIT_BUTTON_CHOOSE; |
1300 } else { | 1329 } else { |
1301 return EDIT_BUTTON_GONE; | 1330 return EDIT_BUTTON_GONE; |
1302 } | 1331 } |
1303 } | 1332 } |
1304 | 1333 |
1305 private void updateSelectedItem(PaymentOption selectedItem) { | 1334 private void updateSelectedItem(PaymentOption selectedItem) { |
| 1335 // Display summary in a single line if no selected item or in DISPLA
Y_MODE_NORMAL. |
| 1336 if (selectedItem == null || mDisplayMode == DISPLAY_MODE_NORMAL) { |
| 1337 if (!mSummaryInSingleLine) { |
| 1338 setSummaryProperties(TruncateAt.END, true /* leftIsSingleLin
e */, |
| 1339 null /* rightTruncate */, false /* rightIsSingleLine
*/); |
| 1340 mSummaryInSingleLine = true; |
| 1341 } |
| 1342 } else if (mSummaryInSingleLine) { |
| 1343 setSummaryProperties(null /* leftTruncate */, false /* leftIsSin
gleLine */, |
| 1344 null /* rightTruncate */, false /* rightIsSingleLine */)
; |
| 1345 mSummaryInSingleLine = false; |
| 1346 } |
| 1347 |
1306 if (selectedItem == null) { | 1348 if (selectedItem == null) { |
1307 setLogoDrawable(null, false); | 1349 setLogoDrawable(null, false); |
1308 setIsSummaryAllowed(false); | 1350 if (!mSummaryInDescriptiveText) { |
1309 setSummaryText(null, null); | 1351 ApiCompatibilityUtils.setTextAppearance( |
| 1352 getSummaryLeftTextView(), R.style.PaymentsUiSectionD
escriptiveText); |
| 1353 } |
| 1354 SectionUiUtils.showSectionSummaryInTextViewInSingeLine( |
| 1355 getContext(), mSectionInformation, getSummaryLeftTextVie
w()); |
1310 } else { | 1356 } else { |
1311 setLogoDrawable(selectedItem.getDrawableIcon(), selectedItem.isE
ditable()); | 1357 setLogoDrawable(selectedItem.getDrawableIcon(), selectedItem.isE
ditable()); |
| 1358 if (mSummaryInDescriptiveText) { |
| 1359 ApiCompatibilityUtils.setTextAppearance( |
| 1360 getSummaryLeftTextView(), R.style.PaymentsUiSectionD
efaultText); |
| 1361 } |
1312 setSummaryText( | 1362 setSummaryText( |
1313 convertOptionToString(selectedItem, false /* useBoldLabe
l */, | 1363 convertOptionToString(selectedItem, false /* useBoldLabe
l */, |
1314 mSummaryInSingleLine), | 1364 mSummaryInSingleLine), |
1315 null); | 1365 null); |
1316 } | 1366 } |
1317 | 1367 |
1318 updateControlLayout(); | 1368 updateControlLayout(); |
1319 } | 1369 } |
1320 | 1370 |
1321 private void updateOptionList(SectionInformation information, PaymentOpt
ion selectedItem) { | 1371 private void updateOptionList(SectionInformation information, PaymentOpt
ion selectedItem) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1451 parent.addView(this, index, params); | 1501 parent.addView(this, index, params); |
1452 } | 1502 } |
1453 | 1503 |
1454 /** Expand the separator to be the full width of the dialog. */ | 1504 /** Expand the separator to be the full width of the dialog. */ |
1455 public void expand() { | 1505 public void expand() { |
1456 LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLa
youtParams(); | 1506 LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLa
youtParams(); |
1457 ApiCompatibilityUtils.setMarginStart(params, 0); | 1507 ApiCompatibilityUtils.setMarginStart(params, 0); |
1458 ApiCompatibilityUtils.setMarginEnd(params, 0); | 1508 ApiCompatibilityUtils.setMarginEnd(params, 0); |
1459 } | 1509 } |
1460 } | 1510 } |
| 1511 |
| 1512 private static class SectionUiUtils { |
| 1513 /** Avoid instantiation by accident. */ |
| 1514 private SectionUiUtils() {} |
| 1515 |
| 1516 /** |
| 1517 * Show the section summary in the view in a single line. |
| 1518 * |
| 1519 * @param context The context. |
| 1520 * @param section The section to summarize. |
| 1521 * @param view The view to display the summary. |
| 1522 */ |
| 1523 public static void showSectionSummaryInTextViewInSingeLine( |
| 1524 final Context context, final SectionInformation section, final T
extView view) { |
| 1525 int optionCount = section.getSize(); |
| 1526 if (optionCount == 0) { |
| 1527 view.setText(null); |
| 1528 return; |
| 1529 } |
| 1530 |
| 1531 if (view.getLayout() == null && optionCount > 1) { |
| 1532 // Listen for layout change so as to get proper summary to displ
ay in a single line. |
| 1533 view.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
{ |
| 1534 @Override |
| 1535 public void onLayoutChange(View v, int left, int top, int ri
ght, int bottom, |
| 1536 int oldLeft, int oldTop, int oldRight, int oldBottom
) { |
| 1537 view.removeOnLayoutChangeListener(this); |
| 1538 if (section.getSelectedItem() != null) return; |
| 1539 |
| 1540 Layout layout = view.getLayout(); |
| 1541 if (layout.getEllipsisCount(0) > 0) { |
| 1542 String summary = getSectionSummaryForPreviewInASingl
eLine( |
| 1543 context, section, layout, view.getPaint()); |
| 1544 view.setText(summary); |
| 1545 } |
| 1546 } |
| 1547 }); |
| 1548 } |
| 1549 |
| 1550 String summary = SectionUiUtils.getSectionSummaryForPreviewInASingle
Line( |
| 1551 context, section, view.getLayout(), view.getPaint()); |
| 1552 view.setText(summary); |
| 1553 } |
| 1554 |
| 1555 private static String getSectionSummaryForPreviewInASingleLine(Context c
ontext, |
| 1556 SectionInformation section, @Nullable Layout layout, @Nullable T
extPaint paint) { |
| 1557 int optionCount = section.getSize(); |
| 1558 assert optionCount != 0; |
| 1559 |
| 1560 PaymentOption option = section.getItem(0); |
| 1561 String optionSummary = convertOptionToPreviewString(option, context)
; |
| 1562 int moreOptionCount = optionCount - 1; |
| 1563 if (moreOptionCount == 0) return optionSummary; |
| 1564 |
| 1565 // Append string to indicate how many more options in the given sect
ion. |
| 1566 int resId = section.getPreviewStringResourceId(); |
| 1567 assert resId > 0; |
| 1568 if (paint == null || layout == null) { |
| 1569 return context.getString(resId, optionSummary, moreOptionCount); |
| 1570 } |
| 1571 |
| 1572 int ellipsizedWidth = layout.getEllipsizedWidth(); |
| 1573 if (option.isPaymentCard()) { |
| 1574 float desiredWidth = Layout.getDesiredWidth( |
| 1575 context.getString(resId, optionSummary, moreOptionCount)
, paint); |
| 1576 if (desiredWidth > ellipsizedWidth) { |
| 1577 // Only display network name which is separated by space at
the beginning for |
| 1578 // autofill payment cards if width is not enough. |
| 1579 optionSummary = optionSummary.substring(0, optionSummary.ind
exOf(" ")); |
| 1580 } |
| 1581 |
| 1582 return context.getString(resId, optionSummary, moreOptionCount); |
| 1583 } |
| 1584 |
| 1585 String summary = context.getString(resId, optionSummary, moreOptionC
ount); |
| 1586 while (Layout.getDesiredWidth(summary, paint) > ellipsizedWidth) { |
| 1587 optionSummary = optionSummary.substring(0, optionSummary.length(
) / 2); |
| 1588 summary = context.getString(resId, optionSummary, moreOptionCoun
t); |
| 1589 } |
| 1590 |
| 1591 return summary; |
| 1592 } |
| 1593 |
| 1594 private static String convertOptionToPreviewString(PaymentOption option,
Context context) { |
| 1595 String previewString = option.getLabel(); |
| 1596 if (option.isPaymentCard()) return previewString; |
| 1597 |
| 1598 String labelSeparator = context.getString(R.string.autofill_address_
summary_separator); |
| 1599 if (!TextUtils.isEmpty(option.getSublabel())) { |
| 1600 if (previewString.length() > 0) previewString += labelSeparator; |
| 1601 previewString += option.getSublabel(); |
| 1602 } |
| 1603 |
| 1604 if (!TextUtils.isEmpty(option.getTertiaryLabel())) { |
| 1605 if (previewString.length() > 0) previewString += labelSeparator; |
| 1606 previewString += option.getSublabel(); |
| 1607 } |
| 1608 |
| 1609 return previewString; |
| 1610 } |
| 1611 } |
1461 } | 1612 } |
OLD | NEW |