| 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 |