Index: chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java |
index c673af740649ccbb9b9e4a44069c9611e93b8ed2..122012f826be0cafc50d45babf977862292d50eb 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java |
@@ -24,16 +24,20 @@ import android.view.View.OnClickListener; |
import android.view.ViewGroup; |
import android.view.accessibility.AccessibilityEvent; |
import android.view.inputmethod.EditorInfo; |
+import android.widget.AdapterView; |
+import android.widget.AdapterView.OnItemSelectedListener; |
import android.widget.ArrayAdapter; |
import android.widget.AutoCompleteTextView; |
import android.widget.Button; |
import android.widget.LinearLayout; |
+import android.widget.Spinner; |
import android.widget.TextView; |
import org.chromium.base.ApiCompatibilityUtils; |
import org.chromium.chrome.R; |
import org.chromium.chrome.browser.EmbedContentViewActivity; |
import org.chromium.chrome.browser.payments.ui.PaymentRequestUI.PaymentRequestObserverForTest; |
+import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.SpinnerKeyValue; |
import org.chromium.chrome.browser.widget.AlwaysDismissedDialog; |
import org.chromium.chrome.browser.widget.DualControlLayout; |
import org.chromium.chrome.browser.widget.FadingShadow; |
@@ -61,14 +65,15 @@ public class EditorView extends AlwaysDismissedDialog |
private static final String HELP_URL = "https://support.google.com/chrome/answer/142893?hl=en"; |
/** Handles validation and display of one field from the {@link EditorFieldModel}. */ |
- private final class EditorFieldView extends TextInputLayout { |
+ private final class TextFieldView extends TextInputLayout { |
private final EditorFieldModel mEditorFieldModel; |
private final AutoCompleteTextView mInput; |
private boolean mHasFocusedAtLeastOnce; |
- public EditorFieldView(Context context, final EditorFieldModel fieldModel) { |
+ public TextFieldView(Context context, final EditorFieldModel fieldModel) { |
super(context); |
mEditorFieldModel = fieldModel; |
+ assert !fieldModel.isSpinner(); |
// Build up the label. Required fields are indicated by appending a '*'. |
CharSequence label = fieldModel.getLabel(); |
@@ -117,14 +122,42 @@ public class EditorView extends AlwaysDismissedDialog |
mInput.setThreshold(0); |
} |
- if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_PHONE) { |
- mInput.setId(R.id.payments_edit_phone_input); |
- mInput.setInputType(InputType.TYPE_CLASS_PHONE); |
- mInput.addTextChangedListener(getPhoneFormatter()); |
- } else if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_EMAIL) { |
- mInput.setId(R.id.payments_edit_email_input); |
- mInput.setInputType( |
- InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); |
+ switch (fieldModel.getInputTypeHint()) { |
+ case EditorFieldModel.INPUT_TYPE_HINT_PHONE: |
+ mInput.setInputType(InputType.TYPE_CLASS_PHONE); |
+ mInput.addTextChangedListener(getPhoneFormatter()); |
+ break; |
+ case EditorFieldModel.INPUT_TYPE_HINT_EMAIL: |
+ mInput.setInputType(InputType.TYPE_CLASS_TEXT |
+ | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); |
+ break; |
+ case EditorFieldModel.INPUT_TYPE_HINT_STREET_LINES: |
+ // TODO(rouslan): Provide a hint to the keyboard that the street lines are |
+ // likely to have numbers. |
+ mInput.setInputType(InputType.TYPE_CLASS_TEXT |
+ | InputType.TYPE_TEXT_FLAG_CAP_WORDS |
+ | InputType.TYPE_TEXT_FLAG_MULTI_LINE |
+ | InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS); |
+ break; |
+ case EditorFieldModel.INPUT_TYPE_HINT_PERSON_NAME: |
+ mInput.setInputType(InputType.TYPE_CLASS_TEXT |
+ | InputType.TYPE_TEXT_FLAG_CAP_WORDS |
+ | InputType.TYPE_TEXT_VARIATION_PERSON_NAME); |
+ break; |
+ case EditorFieldModel.INPUT_TYPE_HINT_REGION: |
+ mInput.setInputType(InputType.TYPE_CLASS_TEXT |
+ | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS |
+ | InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS); |
+ break; |
+ case EditorFieldModel.INPUT_TYPE_HINT_ALPHA_NUMERIC: |
+ // Intentionally fall through. |
+ // TODO(rouslan): Provide a hint to the keyboard that postal code and sorting |
+ // code are likely to have numbers. |
+ default: |
+ mInput.setInputType(InputType.TYPE_CLASS_TEXT |
+ | InputType.TYPE_TEXT_FLAG_CAP_WORDS |
+ | InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS); |
+ break; |
} |
} |
@@ -148,6 +181,77 @@ public class EditorView extends AlwaysDismissedDialog |
} |
} |
+ /** |
+ * Helper class for creating a spinner view with a label. |
+ */ |
+ private final class SpinnerView { |
+ private final EditorFieldModel mFieldModel; |
+ private final TextView mLabel; |
+ private final Spinner mSpinner; |
+ private int mSelectedIndex; |
+ |
+ /** |
+ * Builds a spinner view. |
+ * |
+ * @param context The application context to use when creating widgets. |
+ * @param fieldModel The data model of the spinner. |
+ * @param changedCallback The callback to invoke after user's spinner item selection has |
+ * been processed. |
+ */ |
+ public SpinnerView(Context context, final EditorFieldModel fieldModel, |
+ final Runnable changedCallback) { |
+ mFieldModel = fieldModel; |
+ |
+ mLabel = new TextView(context); |
+ mLabel.setText(mFieldModel.getLabel()); |
+ |
+ final List<SpinnerKeyValue> spinnerKeyValues = mFieldModel.getSpinnerKeyValues(); |
+ for (int j = 0; j < spinnerKeyValues.size(); j++) { |
+ if (spinnerKeyValues.get(j).getKey().equals(mFieldModel.getValue())) { |
+ mSelectedIndex = j; |
+ break; |
+ } |
+ } |
+ |
+ ArrayAdapter<SpinnerKeyValue> adapter = new ArrayAdapter<SpinnerKeyValue>( |
+ context, android.R.layout.simple_spinner_item, spinnerKeyValues); |
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); |
+ |
+ mSpinner = new Spinner(context); |
+ mSpinner.setAdapter(adapter); |
+ mSpinner.setSelection(mSelectedIndex); |
+ mSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { |
+ @Override |
+ public void onItemSelected( |
+ AdapterView<?> parent, View view, int position, long id) { |
+ if (mSelectedIndex != position) { |
+ mSelectedIndex = position; |
+ mFieldModel.setSpinnerKey( |
+ spinnerKeyValues.get(position).getKey(), changedCallback); |
+ } |
+ } |
+ |
+ @Override |
+ public void onNothingSelected(AdapterView<?> parent) {} |
+ }); |
+ } |
+ |
+ /** @return The EditorFieldModel that the SpinnerView represents. */ |
+ public EditorFieldModel getFieldModel() { |
+ return mFieldModel; |
+ } |
+ |
+ /** @return The label view for the spinner. */ |
+ public View getLabel() { |
+ return mLabel; |
+ } |
+ |
+ /** @return The spinner view itself. */ |
+ public View getSpinner() { |
+ return mSpinner; |
+ } |
+ } |
+ |
private final Context mContext; |
private final PaymentRequestObserverForTest mObserverForTest; |
private final Handler mHandler; |
@@ -251,7 +355,7 @@ public class EditorView extends AlwaysDismissedDialog |
* @return Whether all fields contain valid information. |
*/ |
private boolean validateForm() { |
- final List<EditorFieldView> invalidViews = getViewsWithInvalidInformation(); |
+ final List<TextFieldView> invalidViews = getViewsWithInvalidInformation(); |
if (invalidViews.isEmpty()) return true; |
// Focus the first field that's invalid. |
@@ -261,8 +365,8 @@ public class EditorView extends AlwaysDismissedDialog |
// to clear existing errors on any newly valid fields. |
ViewGroup dataView = (ViewGroup) mLayout.findViewById(R.id.contents); |
for (int i = 0; i < dataView.getChildCount(); i++) { |
- if (!(dataView.getChildAt(i) instanceof EditorFieldView)) continue; |
- EditorFieldView fieldView = (EditorFieldView) dataView.getChildAt(i); |
+ if (!(dataView.getChildAt(i) instanceof TextFieldView)) continue; |
+ TextFieldView fieldView = (TextFieldView) dataView.getChildAt(i); |
fieldView.updateDisplayedError(invalidViews.contains(fieldView)); |
} |
@@ -302,20 +406,40 @@ public class EditorView extends AlwaysDismissedDialog |
buttonBar.setAlignment(DualControlLayout.ALIGN_END); |
} |
- /** Create the visual representation of the EditorModel. */ |
+ /** |
+ * Create the visual representation of the EditorModel. |
gone
2016/06/28 17:30:29
* Create the visual representation of the EditorMo
please use gerrit instead
2016/06/29 00:28:45
Done.
|
+ * TODO(rouslan): Put views side by side if !fieldModel.isFullLine(); |
+ */ |
private void prepareEditor() { |
- ViewGroup dataView = (ViewGroup) mLayout.findViewById(R.id.contents); |
+ final ViewGroup dataView = (ViewGroup) mLayout.findViewById(R.id.contents); |
for (int i = 0; i < mEditorModel.getFields().size(); i++) { |
final EditorFieldModel fieldModel = mEditorModel.getFields().get(i); |
- EditorFieldView inputLayout = new EditorFieldView(mContext, fieldModel); |
+ if (fieldModel.isSpinner()) { |
+ SpinnerView spinnerView = new SpinnerView(mContext, fieldModel, new Runnable() { |
+ @Override |
+ public void run() { |
+ // Do not remove the "* indicates required field" label at the bottom. |
+ dataView.removeViews(0, dataView.getChildCount() - 1); |
+ prepareEditor(); |
+ if (mObserverForTest != null) { |
+ mObserverForTest.onPaymentRequestReadyToEdit(); |
+ } |
+ } |
+ }); |
- final AutoCompleteTextView input = inputLayout.getTextView(); |
- if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_PHONE) { |
- assert mPhoneInput == null; |
- mPhoneInput = input; |
- } |
+ dataView.addView(spinnerView.getLabel(), dataView.getChildCount() - 1); |
+ dataView.addView(spinnerView.getSpinner(), dataView.getChildCount() - 1); |
+ } else { |
+ TextFieldView inputLayout = new TextFieldView(mContext, fieldModel); |
+ |
+ final AutoCompleteTextView input = inputLayout.getTextView(); |
+ if (fieldModel.getInputTypeHint() == EditorFieldModel.INPUT_TYPE_HINT_PHONE) { |
+ assert mPhoneInput == null; |
+ mPhoneInput = input; |
+ } |
- dataView.addView(inputLayout, dataView.getChildCount() - 1); |
+ dataView.addView(inputLayout, dataView.getChildCount() - 1); |
+ } |
} |
} |
@@ -337,7 +461,7 @@ public class EditorView extends AlwaysDismissedDialog |
show(); |
// Immediately focus the first invalid field to make it faster to edit. |
- final List<EditorFieldView> invalidViews = getViewsWithInvalidInformation(); |
+ final List<TextFieldView> invalidViews = getViewsWithInvalidInformation(); |
if (!invalidViews.isEmpty()) { |
mHandler.post(new Runnable() { |
@Override |
@@ -365,15 +489,15 @@ public class EditorView extends AlwaysDismissedDialog |
} |
} |
- private List<EditorFieldView> getViewsWithInvalidInformation() { |
+ private List<TextFieldView> getViewsWithInvalidInformation() { |
ViewGroup container = (ViewGroup) findViewById(R.id.contents); |
- List<EditorFieldView> invalidViews = new ArrayList<>(); |
+ List<TextFieldView> invalidViews = new ArrayList<>(); |
for (int i = 0; i < container.getChildCount(); i++) { |
View layout = container.getChildAt(i); |
- if (!(layout instanceof EditorFieldView)) continue; |
+ if (!(layout instanceof TextFieldView)) continue; |
- EditorFieldView fieldView = (EditorFieldView) layout; |
+ TextFieldView fieldView = (TextFieldView) layout; |
if (!fieldView.getFieldModel().isValid()) invalidViews.add(fieldView); |
} |
return invalidViews; |