diff --git a/ui/build.gradle b/ui/build.gradle index 5abe22427..36e57ea3a 100644 --- a/ui/build.gradle +++ b/ui/build.gradle @@ -61,7 +61,7 @@ dependencies { androidTestImplementation "com.squareup.leakcanary:leakcanary-android-instrumentation:1.6.3" androidTestImplementation "com.squareup.leakcanary:leakcanary-support-fragment:1.6.3" - testImplementation group: 'org.mockito', name: 'mockito-core', version: "2.23.4" + testImplementation group: 'org.mockito', name: 'mockito-core', version: "2.25.0" testImplementation group: 'pl.pragmatists', name: 'JUnitParams', version: "1.1.1" testImplementation "org.robolectric:robolectric:4.1" testImplementation "com.squareup.okhttp3:mockwebserver:3.11.0" diff --git a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepository.java b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepository.java index 46d5ec781..de222ff69 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepository.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepository.java @@ -39,11 +39,11 @@ void createTransferMethod(@NonNull HyperwalletTransferMethod transferMethod, @NonNull LoadTransferMethodCallback callback); /** - * Load transfe methods available associated with current context + * Load transfer methods available associated with current context * * @param callback @see {@link LoadTransferMethodListCallback} */ - void loadTransferMethod(@NonNull LoadTransferMethodListCallback callback); + void loadTransferMethods(@NonNull LoadTransferMethodListCallback callback); /** * Deactivate transfer method specified. diff --git a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepositoryImpl.java b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepositoryImpl.java index 7bc72f0c9..4becad682 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepositoryImpl.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepositoryImpl.java @@ -65,7 +65,7 @@ public void createTransferMethod(@NonNull final HyperwalletTransferMethod transf } @Override - public void loadTransferMethod(@NonNull final LoadTransferMethodListCallback callback) { + public void loadTransferMethods(@NonNull final LoadTransferMethodListCallback callback) { getHyperwallet().listTransferMethods(null, new HyperwalletListener>() { @Override diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java index 827b03d61..d220ba52b 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java @@ -298,7 +298,6 @@ public void notifyTransferMethodAdded(@NonNull final HyperwalletTransferMethod t @Override public void showTransferMethodFields(@NonNull final List fields) { mDynamicContainer.removeAllViews(); - int previousView; try { Locale locale = new Locale.Builder().setRegion(mCountry).build(); @@ -309,23 +308,21 @@ public void showTransferMethodFields(@NonNull final List TextView sectionTitle = sectionHeader.findViewById(R.id.section_header_title); sectionTitle.setText(getSectionHeaderText(group, locale)); sectionHeader.setId(View.generateViewId()); - previousView = sectionHeader.getId(); mDynamicContainer.addView(sectionHeader); // group fields for (final HyperwalletField field : group.getFields()) { AbstractWidget widget = WidgetFactory - .newWidget(field, this, getContext(), - mWidgetInputStateHashMap.containsKey(field.getName()) ? + .newWidget(field, this, mWidgetInputStateHashMap.containsKey(field.getName()) ? mWidgetInputStateHashMap.get(field.getName()).getValue() : "", mCreateTransferMethodButton); if (mWidgetInputStateHashMap.isEmpty() || !mWidgetInputStateHashMap.containsKey(widget.getName())) { mWidgetInputStateHashMap.put(widget.getName(), widget.getWidgetInputState()); } - View widgetView = widget.getView(); + View widgetView = widget.getView(mDynamicContainer); widgetView.setTag(widget); - previousView = placeBelow(widgetView, previousView, true); + widgetView.setId(View.generateViewId()); final String error = mWidgetInputStateHashMap.get(widget.getName()).getErrorMessage(); widget.showValidationError(error); mDynamicContainer.addView(widgetView); @@ -444,7 +441,7 @@ public void showInputErrors(List errors) { AbstractWidget widget = (AbstractWidget) view.getTag(); if (widget.getName().equals(error.getFieldName())) { if (!focusSet) { - widget.getView().requestFocus(); + widget.getView(mDynamicContainer).requestFocus(); focusSet = true; } widget.showValidationError(error.getMessage()); @@ -550,25 +547,6 @@ private void setVisibleAndDisableFields() { mCreateTransferMethodButton.setBackgroundColor(getResources().getColor(R.color.colorSecondaryDark)); } - private int placeBelow(View v, int previousId, boolean matchParentWidth) { - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( - matchParentWidth ? ViewGroup.LayoutParams.MATCH_PARENT : ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - - if (previousId != 0) { - params.addRule(RelativeLayout.BELOW, previousId); - } - - int margin = (int) (getContext().getResources().getDimension(R.dimen.default_margin) - / getContext().getResources().getDisplayMetrics().density); - - params.setMargins(margin, margin, margin, margin); - v.setId(View.generateViewId()); - v.setLayoutParams(params); - - return v.getId(); - } - private boolean performValidation(boolean bypassFocusCheck) { boolean valid = true; // this is added since some phones triggers the create button but the widgets are not yet initialized diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/ListTransferMethodPresenter.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/ListTransferMethodPresenter.java index ece9b89d9..5480e0a2e 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/ListTransferMethodPresenter.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/ListTransferMethodPresenter.java @@ -38,7 +38,7 @@ public ListTransferMethodPresenter(TransferMethodRepository repository, ListTran @Override public void loadTransferMethods() { mView.showProgressBar(); - mTransferMethodRepository.loadTransferMethod(new TransferMethodRepository.LoadTransferMethodListCallback() { + mTransferMethodRepository.loadTransferMethods(new TransferMethodRepository.LoadTransferMethodListCallback() { @Override public void onTransferMethodListLoaded(List transferMethods) { if (!mView.isActive()) { diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/AbstractWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/AbstractWidget.java index 65d644144..211e120c6 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/AbstractWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/AbstractWidget.java @@ -16,8 +16,6 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; -import android.os.Build; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; @@ -26,14 +24,12 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.hyperwallet.android.hyperwallet_ui.R; import com.hyperwallet.android.model.meta.field.HyperwalletField; public abstract class AbstractWidget { private static final String LABEL_SUFFIX = "Label"; - protected final Context mContext; protected final View mDefaultFocusView; protected final String mDefaultValue; protected final HyperwalletField mField; @@ -42,16 +38,15 @@ public abstract class AbstractWidget { protected WidgetInputState mWidgetInputState; public AbstractWidget(@Nullable HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View defaultFocusView) { + @Nullable String defaultValue, @NonNull View defaultFocusView) { mField = field; mListener = listener; - mContext = context; mDefaultValue = defaultValue; mDefaultFocusView = defaultFocusView; mWidgetInputState = new WidgetInputState(getName()); } - public abstract View getView(); + public abstract View getView(@NonNull final ViewGroup viewGroup); public String getName() { return mField == null ? "" : mField.getName(); @@ -128,17 +123,6 @@ protected void appendLayout(View v, boolean matchParentWidth) { params.addRule(RelativeLayout.BELOW, mBottomViewId); } - int default_margin = (int) (mContext.getResources().getDimension(R.dimen.default_margin) - / mContext.getResources().getDisplayMetrics().density); - int widget_margin_offset = (int) (mContext.getResources().getDimension(R.dimen.widget_left_margin_offset) - / mContext.getResources().getDisplayMetrics().density); - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { - params.setMargins(default_margin, default_margin, default_margin, default_margin); - } else { - params.setMargins(widget_margin_offset, default_margin, default_margin, default_margin); - } - v.setLayoutParams(params); mBottomViewId = v.getId(); } @@ -148,7 +132,7 @@ protected void setIdFromFieldName(View view) { if (fieldName.isEmpty()) { view.setId(View.generateViewId()); } else { - view.setId(getIdByResourceName(fieldName)); + view.setId(getIdByResourceName(fieldName, view)); } } @@ -157,17 +141,15 @@ protected void setIdFromFieldLabel(View view) { if (fieldName.isEmpty()) { view.setId(View.generateViewId()); } else { - view.setId(getIdByResourceName(fieldName + LABEL_SUFFIX)); + view.setId(getIdByResourceName(fieldName + LABEL_SUFFIX, view)); } } - private int getIdByResourceName(@NonNull final String fieldName) { - int id; - final int idFromResource = mContext.getResources().getIdentifier(fieldName, "id", - mContext.getPackageName()); - // Returns 0 if no such resource was found. - id = idFromResource == 0 ? View.generateViewId() : idFromResource; - return id; + private int getIdByResourceName(@NonNull final String fieldName, @NonNull final View view) { + final int idFromResource = view.getContext().getResources().getIdentifier(fieldName, "id", + view.getContext().getPackageName()); + + return idFromResource == 0 ? View.generateViewId() : idFromResource; } protected class DefaultKeyListener implements View.OnKeyListener { diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java index f0580262d..e4f4edc44 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java @@ -16,16 +16,16 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -37,24 +37,29 @@ public class DateWidget extends AbstractWidget { private ViewGroup mContainer; - private String mValue = ""; + private String mValue; private TextInputLayout mTextInputLayout; - public DateWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @NonNull Context context, + public DateWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + // input control + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + + editText.setEnabled(mField.isEditable()); setIdFromFieldName(editText); mTextInputLayout.setHint(mField.getLabel()); mTextInputLayout.addView(editText); @@ -88,10 +93,10 @@ public void afterTextChanged(Editable s) { } }); + editText.setText(TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue); editText.setInputType(InputType.TYPE_CLASS_DATETIME); editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); - editText.setText(mDefaultValue); appendLayout(mTextInputLayout, true); mContainer.addView(mTextInputLayout); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DefaultAccountWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DefaultAccountWidget.java index fc1e66687..9463f308f 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DefaultAccountWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DefaultAccountWidget.java @@ -2,7 +2,6 @@ import static com.hyperwallet.android.model.HyperwalletTransferMethod.TransferMethodFields.IS_DEFAULT_TRANSFER_METHOD; -import android.content.Context; import android.graphics.Typeface; import android.view.View; import android.view.ViewGroup; @@ -21,9 +20,9 @@ public class DefaultAccountWidget extends AbstractWidget { private ViewGroup mContainer; private String mValue; - public DefaultAccountWidget(@NonNull WidgetEventListener listener, @NonNull Context context, + public DefaultAccountWidget(@NonNull WidgetEventListener listener, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(null, listener, context, defaultValue, defaultFocusView); + super(null, listener, defaultValue, defaultFocusView); } @Override @@ -32,26 +31,26 @@ public String getName() { } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = new RelativeLayout(viewGroup.getContext()); // label - TextView label = new TextView(mContext); - label.setText(mContext.getResources().getText(R.string.default_account_label)); + TextView label = new TextView(viewGroup.getContext()); + label.setText(viewGroup.getContext().getResources().getText(R.string.default_account_label)); - label.setTextSize(mContext.getResources().getDimension(R.dimen.font_subtitle2)); + label.setTextSize(viewGroup.getContext().getResources().getDimension(R.dimen.font_subtitle2)); setIdFromFieldLabel(label); label.setTypeface(null, Typeface.BOLD); - label.setTextColor(mContext.getResources().getColor(R.color.colorPrimary)); + label.setTextColor(viewGroup.getContext().getResources().getColor(R.color.colorPrimary)); appendLayout(label, true); mContainer.addView(label); // switch control - Switch toggle = new Switch(mContext); + Switch toggle = new Switch(viewGroup.getContext()); setIdFromFieldName(toggle); - toggle.setText(mContext.getResources().getText(R.string.default_account_sub_label)); - toggle.setTextSize(mContext.getResources().getDimension(R.dimen.font_subtitle2)); + toggle.setText(viewGroup.getContext().getResources().getText(R.string.default_account_sub_label)); + toggle.setTextSize(viewGroup.getContext().getResources().getDimension(R.dimen.font_subtitle2)); if (mDefaultValue == null) { toggle.setChecked(true); // initial state mValue = Boolean.TRUE.toString(); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/ExpiryDateWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/ExpiryDateWidget.java index 69c48bea4..9777f2153 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/ExpiryDateWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/ExpiryDateWidget.java @@ -27,12 +27,12 @@ import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -46,24 +46,36 @@ public class ExpiryDateWidget extends AbstractWidget { private final ExpireDateUtil mExpireDateUtil; private TextInputLayout mTextInputLayout; private String mValue; + private String mMessageInvalidDateLength; + private String mMessageInvalidDate; public ExpiryDateWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + @Nullable String defaultValue, @NonNull View defaultFocusView) { + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; mExpireDateUtil = new ExpireDateUtil(); } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + + // initialize messaging + mMessageInvalidDateLength = viewGroup.getContext().getResources() + .getString(R.string.error_exact_length_field, MAX_INPUT_LENGTH); + mMessageInvalidDate = viewGroup.getContext().getResources() + .getString(R.string.error_invalid_expiry_date, mField.getLabel()); // input control - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + + editText.setEnabled(mField.isEditable()); setIdFromFieldLabel(mTextInputLayout); setIdFromFieldName(editText); editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @@ -75,10 +87,10 @@ public void onFocusChange(View v, boolean hasFocus) { } else { mListener.widgetFocused(ExpiryDateWidget.this.getName()); editText.setHint(editText.getText().toString().trim().isEmpty() ? - mContext.getResources().getString(R.string.api_expiry_date_format) : ""); + viewGroup.getContext().getResources().getString(R.string.api_expiry_date_format) : ""); InputMethodManager imm = (InputMethodManager) - mContext.getSystemService(Context.INPUT_METHOD_SERVICE); + viewGroup.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); } } @@ -170,8 +182,9 @@ public void afterTextChanged(Editable s) { editText.setInputType(InputType.TYPE_CLASS_DATETIME); editText.setHint(mField.getLabel()); - editText.setText(TextUtils.isEmpty(mDefaultValue) ? "" : - mExpireDateUtil.convertDateFromServerFormat(mDefaultValue)); + editText.setText(mExpireDateUtil.convertDateFromServerFormat( + TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue)); + editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); @@ -203,11 +216,11 @@ public String getErrorMessage() { } if (isInvalidLength()) { - return mContext.getResources().getString(R.string.error_exact_length_field, MAX_INPUT_LENGTH); + return mMessageInvalidDateLength; } if (mExpireDateUtil.isInvalidDate(mValue)) { - return mContext.getResources().getString(R.string.error_invalid_expiry_date, mField.getLabel()); + return mMessageInvalidDate; } return null; diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/NumberWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/NumberWidget.java index 15836dddb..39dcc7eed 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/NumberWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/NumberWidget.java @@ -16,16 +16,16 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -37,24 +37,29 @@ public class NumberWidget extends AbstractWidget { private ViewGroup mContainer; private TextInputLayout mTextInputLayout; - private String mValue = ""; + private String mValue; public NumberWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + @Nullable String defaultValue, @NonNull View defaultFocusView) { + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + // number input text - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); mTextInputLayout.setHint(mField.getLabel()); + final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + editText.setEnabled(mField.isEditable()); setIdFromFieldLabel(mTextInputLayout); setIdFromFieldName(editText); @@ -87,9 +92,9 @@ public void afterTextChanged(Editable s) { } }); + editText.setText(TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue); editText.setInputType(InputType.TYPE_CLASS_NUMBER); editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); - editText.setText(mDefaultValue); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); mTextInputLayout.addView(editText); appendLayout(mTextInputLayout, true); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/PhoneWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/PhoneWidget.java index ccded629d..f8254aaa1 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/PhoneWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/PhoneWidget.java @@ -16,16 +16,16 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -39,21 +39,27 @@ public class PhoneWidget extends AbstractWidget { private String mValue = ""; private TextInputLayout mTextInputLayout; - public PhoneWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @NonNull Context context, + public PhoneWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); + // input control final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + editText.setEnabled(mField.isEditable()); + mTextInputLayout.addView(editText); mTextInputLayout.setHint(mField.getLabel()); setIdFromFieldName(editText); @@ -87,10 +93,10 @@ public void afterTextChanged(Editable s) { } }); + editText.setText(TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue); editText.setInputType(InputType.TYPE_CLASS_PHONE); editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); - editText.setText(mDefaultValue); appendLayout(mTextInputLayout, true); mContainer.addView(mTextInputLayout); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/SelectionWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/SelectionWidget.java index 24a1a34ea..146de1b65 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/SelectionWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/SelectionWidget.java @@ -17,15 +17,14 @@ package com.hyperwallet.android.ui.view.widget; import android.app.Activity; -import android.content.Context; import android.text.TextUtils; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -37,7 +36,6 @@ import com.hyperwallet.android.model.meta.field.HyperwalletFieldSelectionOption; import com.hyperwallet.android.ui.view.WidgetSelectionDialogFragment; -import java.util.Locale; import java.util.Set; import java.util.TreeMap; @@ -50,41 +48,43 @@ public class SelectionWidget extends AbstractWidget implements WidgetSelectionDi private String mValue; public SelectionWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + @Nullable String defaultValue, @NonNull View defaultFocusView) { + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; mSelectionNameValueMap = new TreeMap<>(); - for (HyperwalletFieldSelectionOption option : field.getFieldSelectionOptions()) { - if (!TextUtils.isEmpty(option.getLabel())) { - String label = option.getLabel().substring(1).toLowerCase(Locale.ROOT); - label = option.getLabel().substring(0, 1) + label; - mSelectionNameValueMap.put(label, option.getValue()); + if (field.getFieldSelectionOptions() != null) { + for (HyperwalletFieldSelectionOption option : field.getFieldSelectionOptions()) { + if (!TextUtils.isEmpty(option.getLabel())) { + mSelectionNameValueMap.put(option.getLabel(), option.getValue()); + } } } } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + setIdFromFieldLabel(mContainer); mContainer.setFocusable(true); mContainer.setFocusableInTouchMode(true); - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); mEditText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); - if (!TextUtils.isEmpty(mDefaultValue)) { - mEditText.setText(getKeyFromValue(mDefaultValue)); - } + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + mEditText.setText( + getKeyFromValue(TextUtils.isEmpty(mDefaultValue) ? mValue = mField.getValue() : mDefaultValue)); setIdFromFieldLabel(mTextInputLayout); setIdFromFieldName(mEditText); mEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); mEditText.setKeyListener(null); mEditText.setCompoundDrawablesWithIntrinsicBounds(null, null, - ContextCompat.getDrawable(mContext, R.drawable.ic_keyboard_arrow_down_12dp), null); + ContextCompat.getDrawable(viewGroup.getContext(), R.drawable.ic_keyboard_arrow_down_12dp), null); mEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override @@ -104,13 +104,17 @@ public void onFocusChange(View v, boolean hasFocus) { } }); - mEditText.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - hideSoftKey(v); - showSelectionFragmentDialog(); - } - }); + if (mField.isEditable()) { + mEditText.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + hideSoftKey(v); + showSelectionFragmentDialog(); + } + }); + } else { + mEditText.setEnabled(false); + } mTextInputLayout.setHint(mField.getLabel()); mTextInputLayout.addView(mEditText); @@ -145,7 +149,8 @@ private void hideSoftKey(@NonNull View focusedView) { private void showSelectionFragmentDialog() { String defaultSelected = TextUtils.isEmpty(mValue) ? - TextUtils.isEmpty(mDefaultValue) ? "" : getKeyFromValue(mDefaultValue) : getKeyFromValue(mValue); + TextUtils.isEmpty(mDefaultValue) ? getKeyFromValue(mField.getValue()) : + getKeyFromValue(mDefaultValue) : getKeyFromValue(mValue); mListener.openWidgetSelectionFragmentDialog(mSelectionNameValueMap, defaultSelected, mField.getLabel(), mField.getName()); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/TextWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/TextWidget.java index afcb674f6..f16fd51c0 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/TextWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/TextWidget.java @@ -16,16 +16,16 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -36,26 +36,31 @@ public class TextWidget extends AbstractWidget { private ViewGroup mContainer; - private String mValue = ""; + private String mValue; private TextInputLayout mTextInputLayout; - public TextWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @NonNull Context context, + public TextWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); mContainer.setTag(mField.getName()); - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); + final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); - mTextInputLayout.setHint(mField.getLabel()); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + editText.setEnabled(mField.isEditable()); + mTextInputLayout.setHint(mField.getLabel()); setIdFromFieldLabel(mTextInputLayout); setIdFromFieldName(editText); editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @@ -87,10 +92,10 @@ public void afterTextChanged(Editable s) { } }); + editText.setText(TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue); editText.setInputType(InputType.TYPE_CLASS_TEXT); editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); - editText.setText(mDefaultValue); mTextInputLayout.addView(editText); appendLayout(mTextInputLayout, true); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetFactory.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetFactory.java index 2e96db97f..18bd507ca 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetFactory.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetFactory.java @@ -16,7 +16,6 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.view.View; import androidx.annotation.NonNull; @@ -31,7 +30,6 @@ public class WidgetFactory { - private static final String TAG = AbstractWidget.class.getName(); private static final HashMap WIDGET_MAP_DEFINITION = new HashMap() {{ put(EDataType.TEXT, TextWidget.class); put(EDataType.SELECTION, SelectionWidget.class); @@ -43,18 +41,17 @@ public class WidgetFactory { @SuppressWarnings("unchecked") public static AbstractWidget newWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View view) throws HyperwalletException { + @Nullable String defaultValue, @NonNull View view) throws HyperwalletException { try { if (WIDGET_MAP_DEFINITION.containsKey(field.getDataType())) { return (AbstractWidget) WIDGET_MAP_DEFINITION.get(field.getDataType()) - .getConstructor(HyperwalletField.class, WidgetEventListener.class, - Context.class, String.class, View.class) - .newInstance(field, listener, context, defaultValue, view); + .getConstructor(HyperwalletField.class, WidgetEventListener.class, String.class, View.class) + .newInstance(field, listener, defaultValue, view); } } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { throw new HyperwalletException(e); } - return new TextWidget(field, listener, context, defaultValue, view); + return new TextWidget(field, listener, defaultValue, view); } } diff --git a/ui/src/main/res/layout/item_widget_layout.xml b/ui/src/main/res/layout/item_widget_layout.xml new file mode 100644 index 000000000..11ff1150a --- /dev/null +++ b/ui/src/main/res/layout/item_widget_layout.xml @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/ui/src/main/res/values/dimens.xml b/ui/src/main/res/values/dimens.xml index af96abda6..1a3f3fb32 100644 --- a/ui/src/main/res/values/dimens.xml +++ b/ui/src/main/res/values/dimens.xml @@ -47,6 +47,10 @@ 32dp 330dp + + 8dp + 12dp + 136dp 1dp diff --git a/ui/src/main/res/values/ids.xml b/ui/src/main/res/values/ids.xml index df6202824..ed5803f80 100644 --- a/ui/src/main/res/values/ids.xml +++ b/ui/src/main/res/values/ids.xml @@ -14,4 +14,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ui/src/main/res/values/styles.xml b/ui/src/main/res/values/styles.xml index b61828efc..887a6de77 100644 --- a/ui/src/main/res/values/styles.xml +++ b/ui/src/main/res/values/styles.xml @@ -106,6 +106,10 @@ @color/colorSecondaryDark + + + +