Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java

Issue 872023002: Use floating labels for preference forms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Actually commit AddressField.java Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
index ce69ae098bcdd9bfb081506686314d6ed4f8658c..59ee521000b0896cb7809f0a0ac6f125abde1a7c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
@@ -9,24 +9,27 @@ import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
+import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
-import com.android.i18n.addressinput.AddressData;
-import com.android.i18n.addressinput.AddressField;
-import com.android.i18n.addressinput.AddressWidget;
-import com.android.i18n.addressinput.FormOptions;
-import com.android.i18n.addressinput.SimpleClientCacheManager;
-
import org.chromium.chrome.R;
import org.chromium.chrome.browser.autofill.PersonalDataManager;
import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
+import org.chromium.chrome.browser.widget.FloatLabelLayout;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
/**
* Provides the Java-ui for editing a Profile autofill entry.
@@ -37,11 +40,18 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
// May be the empty string if creating a new profile.
private String mGUID;
- private AddressWidget mAddressWidget;
private boolean mNoCountryItemIsSelected;
+ private LayoutInflater mInflater;
private EditText mPhoneText;
+ private FloatLabelLayout mPhoneLabel;
private EditText mEmailText;
+ private FloatLabelLayout mEmailLabel;
private String mLanguageCodeString;
+ private List<String> mCountryCodes;
+ private int mCurrentCountryPos;
+ private Spinner mCountriesSpinner;
+ private ViewGroup mWidgetRoot;
+ private FloatLabelLayout[] mAddressFields;
@Override
public void onCreate(Bundle savedState) {
@@ -53,11 +63,6 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- View v = inflater.inflate(R.layout.autofill_profile_editor, container, false);
-
- mPhoneText = (EditText) v.findViewById(R.id.autofill_profile_editor_phone_number_edit);
- mEmailText = (EditText) v.findViewById(R.id.autofill_profile_editor_email_address_edit);
-
// We know which profile to edit based on the GUID stuffed in
// our extras by AutofillPreferences.
Bundle extras = getArguments();
@@ -71,8 +76,23 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
getActivity().setTitle(R.string.autofill_edit_profile);
}
- addProfileDataToEditFields(v);
+ mInflater = inflater;
+ mAddressFields = new FloatLabelLayout[AddressField.class.getDeclaredFields().length];
newt (away) 2015/01/28 20:20:19 Avoid reflection at all costs please :O (Why? One
Theresa 2015/01/29 05:22:13 Done.
+ View v = mInflater.inflate(R.layout.autofill_profile_editor, container, false);
+
+ mPhoneText = (EditText) v.findViewById(R.id.autofill_profile_editor_phone_number_edit);
+ mPhoneLabel =
+ (FloatLabelLayout) v.findViewById(R.id.autofill_profile_editor_phone_number_label);
+ mEmailText = (EditText) v.findViewById(R.id.autofill_profile_editor_email_address_edit);
+ mEmailLabel =
+ (FloatLabelLayout) v.findViewById(R.id.autofill_profile_editor_email_address_label);
+ mWidgetRoot = (ViewGroup) v.findViewById(R.id.autofill_profile_widget_root);
+ mCountriesSpinner = (Spinner) v.findViewById(R.id.countries);
+
+ populateCountriesSpinner();
+ createAndPopulateEditFields(v);
hookupSaveCancelDeleteButtons(v);
+
return v;
}
@@ -84,78 +104,183 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
- enableSaveButton();
+ boolean empty = mNoCountryItemIsSelected && TextUtils.isEmpty(s) && allFieldsEmpty();
+ setSaveButtonEnabled(!empty);
+ }
+
+ private boolean allFieldsEmpty() {
+ if (!TextUtils.isEmpty(mPhoneText.getText())
+ || !TextUtils.isEmpty(mEmailText.getText())) {
+ return false;
+ }
+ for (FloatLabelLayout field : mAddressFields) {
+ if (field != null && !TextUtils.isEmpty(field.getEditText().getText())) {
+ return false;
+ }
+ }
+
+ return true;
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- mAddressWidget.onItemSelected(parent, view, position, id);
-
- if (mNoCountryItemIsSelected) {
+ if (position != mCurrentCountryPos) {
+ mCurrentCountryPos = position;
+ resetFormFields(position, true);
mNoCountryItemIsSelected = false;
- return;
+ setSaveButtonEnabled(true);
}
-
- enableSaveButton();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
- private void addProfileDataToEditFields(View v) {
- AddressData.Builder address = new AddressData.Builder();
+ private void populateCountriesSpinner() {
+ List<String> countryCodes = AutofillProfileBridge.getAvailableCountries();
+ List<String> countryNames = new ArrayList<String>();
+ HashMap<String, String> countryNamesToCodes = new HashMap<String, String>();
+
+ for (String countryCode : countryCodes) {
+ String countryName = new Locale("", countryCode).getDisplayCountry(Locale.getDefault());
+ countryNames.add(countryName);
+ countryNamesToCodes.put(countryName, countryCode);
+ }
+
+ // Use a collator to perform localized sorting of country names.
+ Collator collator = Collator.getInstance(Locale.getDefault());
+ java.util.Collections.sort(countryNames, collator);
+
+ // Store country codes in the same order they will appear in the spinner (alphabetically
+ // by display name).
+ mCountryCodes = new ArrayList<String>();
+ for (String key : countryNames) {
+ mCountryCodes.add(countryNamesToCodes.get(key));
+ }
+
+ ArrayAdapter<String> countriesAdapter = new ArrayAdapter<String>(getActivity(),
+ android.R.layout.simple_spinner_item, countryNames);
+ countriesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mCountriesSpinner.setAdapter(countriesAdapter);
+ }
+
+ private void createAndPopulateEditFields(View v) {
AutofillProfile profile = PersonalDataManager.getInstance().getProfile(mGUID);
if (profile != null) {
- mPhoneText.setText(profile.getPhoneNumber());
- mEmailText.setText(profile.getEmailAddress());
+ if (!TextUtils.isEmpty(profile.getPhoneNumber())) {
+ // FloatLabelLayout animates showing the field label when the EditText text changes;
+ // to avoid this animation, manually set the label to be visible.
+ mPhoneLabel.getLabel().setVisibility(View.VISIBLE);
+ mPhoneText.setText(profile.getPhoneNumber());
+ mPhoneText.setHint(null);
+ }
+
+ if (!TextUtils.isEmpty(profile.getEmailAddress())) {
+ mEmailLabel.getLabel().setVisibility(View.VISIBLE);
+ mEmailText.setText(profile.getEmailAddress());
+ mEmailText.setHint(null);
+ }
+
mLanguageCodeString = profile.getLanguageCode();
- address.setAdminArea(profile.getRegion());
- address.setLocality(profile.getLocality());
- address.setRecipient(profile.getFullName());
- address.setOrganization(profile.getCompanyName());
- address.setDependentLocality(profile.getDependentLocality());
- address.setPostalCode(profile.getPostalCode());
- address.setSortingCode(profile.getSortingCode());
- address.setAddress(profile.getStreetAddress());
- address.setCountry(profile.getCountryCode());
+ mCurrentCountryPos = mCountryCodes.indexOf(profile.getCountryCode());
+ if (mCurrentCountryPos == -1) {
+ mCurrentCountryPos = mCountryCodes.indexOf(Locale.getDefault().getCountry());
+ }
+ resetFormFields(mCurrentCountryPos, false);
+
+ setFieldText(AddressField.ADMIN_AREA, profile.getRegion());
+ setFieldText(AddressField.LOCALITY, profile.getLocality());
+ setFieldText(AddressField.DEPENDENT_LOCALITY, profile.getDependentLocality());
+ setFieldText(AddressField.SORTING_CODE, profile.getSortingCode());
+ setFieldText(AddressField.POSTAL_CODE, profile.getPostalCode());
+ setFieldText(AddressField.STREET_ADDRESS, profile.getStreetAddress());
+ setFieldText(AddressField.ORGANIZATION, profile.getCompanyName());
+ setFieldText(AddressField.RECIPIENT, profile.getFullName());
+ } else {
+ mCurrentCountryPos = mCountryCodes.indexOf(Locale.getDefault().getCountry());
+ resetFormFields(mCurrentCountryPos, true);
+ }
+ }
+
+ private void resetFormFields(int countryCodeIndex, boolean autoFocusFirstField) {
+ mWidgetRoot.removeAllViews();
+ for (int i = 0; i < mAddressFields.length; i++) {
+ mAddressFields[i] = null;
}
- ViewGroup widgetRoot = (ViewGroup) v.findViewById(R.id.autofill_profile_widget_root);
- mAddressWidget = new AddressWidget(getActivity(), widgetRoot,
- (new FormOptions.Builder()).build(),
- new SimpleClientCacheManager(),
- address.build(),
- new ChromeAddressWidgetUiComponentProvider(getActivity()));
+ mCountriesSpinner.setSelection(countryCodeIndex);
+ List<Pair<Integer, String>> fields = AutofillProfileBridge.getAddressUiComponents(
+ mCountryCodes.get(countryCodeIndex), Locale.getDefault().toString());
+
+ boolean firstField = true;
+
+ for (Pair<Integer, String> field : fields) {
+ Integer fieldId = field.first;
+ String fieldLabel = field.second;
+ FloatLabelLayout fieldFloatLabel = (FloatLabelLayout) mInflater.inflate(
+ R.layout.preference_float_label_layout, mWidgetRoot, false);
+ fieldFloatLabel.setHint(fieldLabel);
- if (profile == null) {
- widgetRoot.requestFocus();
+ EditText fieldEditText =
+ (EditText) fieldFloatLabel.findViewById(R.id.address_edit_text);
+ fieldEditText.setHint(fieldLabel);
+ fieldEditText.setContentDescription(fieldLabel);
+ fieldEditText.addTextChangedListener(this);
+
+ mAddressFields[fieldId] = fieldFloatLabel;
+ mWidgetRoot.addView(fieldFloatLabel);
+
+ if (firstField && autoFocusFirstField) {
+ // FloatLabelLayout animates showing the field label when the EditText is focused;
+ // to avoid this animation, manually set the label to be visible and the EditText
+ // hint to null and request focus on the EditText field.
+ fieldFloatLabel.getLabel().setVisibility(View.VISIBLE);
+ fieldEditText.setHint(null);
+ fieldEditText.requestFocus();
+ firstField = false;
+ }
}
}
// Read edited data; save in the associated Chrome profile.
// Ignore empty fields.
private void saveProfile() {
- AddressData input = mAddressWidget.getAddressData();
AutofillProfile profile = new PersonalDataManager.AutofillProfile(
mGUID,
AutofillPreferences.SETTINGS_ORIGIN,
- input.getRecipient(),
- input.getOrganization(),
- TextUtils.join("\n", input.getAddressLines()),
- input.getAdministrativeArea(),
- input.getLocality(),
- input.getDependentLocality(),
- input.getPostalCode(),
- input.getSortingCode(),
- input.getPostalCountry(),
+ getFieldText(AddressField.RECIPIENT),
+ getFieldText(AddressField.ORGANIZATION),
+ getFieldText(AddressField.STREET_ADDRESS),
+ getFieldText(AddressField.ADMIN_AREA),
+ getFieldText(AddressField.LOCALITY),
+ getFieldText(AddressField.DEPENDENT_LOCALITY),
+ getFieldText(AddressField.POSTAL_CODE),
+ getFieldText(AddressField.SORTING_CODE),
+ mCountryCodes.get(mCurrentCountryPos),
mPhoneText.getText().toString(),
mEmailText.getText().toString(),
mLanguageCodeString);
PersonalDataManager.getInstance().setProfile(profile);
}
+ private String getFieldText(Integer fieldId) {
+ if (mAddressFields[fieldId] != null) {
+ return mAddressFields[fieldId].getEditText().getText().toString();
+ }
+ return null;
+ }
+
+ private void setFieldText(Integer fieldId, String text) {
+ if (mAddressFields[fieldId] != null && !TextUtils.isEmpty(text)) {
+ // FloatLabelLayout animates showing the field label when the EditText text changes;
+ // to avoid this animation, manually set the label to be visible.
+ mAddressFields[fieldId].getLabel().setVisibility(View.VISIBLE);
+ mAddressFields[fieldId].getEditText().setText(text);
+ mAddressFields[fieldId].getEditText().setHint(null);
+ }
+ }
+
private void deleteProfile() {
if (AutofillProfileEditor.this.mGUID != null) {
PersonalDataManager.getInstance().deleteProfile(mGUID);
@@ -196,20 +321,14 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
// Listen for changes to inputs. Enable the save button after something has changed.
mPhoneText.addTextChangedListener(this);
mEmailText.addTextChangedListener(this);
+ mCountriesSpinner.setOnItemSelectedListener(this);
mNoCountryItemIsSelected = true;
-
- for (AddressField field : AddressField.values()) {
- View input = mAddressWidget.getViewForField(field);
- if (input instanceof EditText) {
- ((EditText) input).addTextChangedListener(this);
- } else if (input instanceof Spinner) {
- ((Spinner) input).setOnItemSelectedListener(this);
- }
- }
}
- private void enableSaveButton() {
- Button button = (Button) getView().findViewById(R.id.autofill_profile_save);
- button.setEnabled(true);
+ private void setSaveButtonEnabled(boolean enabled) {
+ if (getView() != null) {
+ Button button = (Button) getView().findViewById(R.id.autofill_profile_save);
+ button.setEnabled(enabled);
+ }
}
}

Powered by Google App Engine
This is Rietveld 408576698