TextFieldsEditorView.java revision 02bb1252aa990813fa9e86ad75c458acc15e6801
1392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann/* 2392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Copyright (C) 2010 The Android Open Source Project 3392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * 4392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License"); 5392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * you may not use this file except in compliance with the License. 6392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * You may obtain a copy of the License at 7392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * 8392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * http://www.apache.org/licenses/LICENSE-2.0 9392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * 10392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Unless required by applicable law or agreed to in writing, software 11392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS, 12392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * See the License for the specific language governing permissions and 14392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * limitations under the License. 15392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 16392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor; 18392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 19392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.ContactsUtils; 20392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.R; 214597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikovimport com.android.contacts.model.AccountType.DataKind; 224597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikovimport com.android.contacts.model.AccountType.EditField; 23392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.model.EntityDelta; 24392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.model.EntityDelta.ValuesDelta; 2579c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmannimport com.android.contacts.util.ThemeUtils; 26392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 27392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.Context; 28392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.Entity; 29915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmannimport android.content.res.Resources; 30392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.graphics.Rect; 31392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.os.Parcel; 32392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.os.Parcelable; 33392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.telephony.PhoneNumberFormattingTextWatcher; 34392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.text.Editable; 35392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.text.InputType; 36392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.text.TextWatcher; 37392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.util.AttributeSet; 38392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.view.Gravity; 39392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.view.View; 40392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.widget.EditText; 41392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.widget.ImageButton; 42392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.widget.LinearLayout; 43392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 44392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann/** 45392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Simple editor that handles labels and any {@link EditField} defined for 46392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * the entry. Uses {@link ValuesDelta} to read any existing 47392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * {@link Entity} values, and to correctly write any changes values. 48392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 49392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannpublic class TextFieldsEditorView extends LabeledEditorView { 50392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private EditText[] mFieldEditTexts = null; 51392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private ImageButton mMoreOrLess; 52392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private boolean mHideOptional = true; 53392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private boolean mHasShortAndLongForms; 54392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 55392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public TextFieldsEditorView(Context context) { 56392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super(context); 57392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 58392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 59392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public TextFieldsEditorView(Context context, AttributeSet attrs) { 60392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super(context, attrs); 61392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 62392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 63392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public TextFieldsEditorView(Context context, AttributeSet attrs, int defStyle) { 64392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super(context, attrs, defStyle); 65392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 66392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 67392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 68392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected void onLayout(boolean changed, int l, int t, int r, int b) { 69392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super.onLayout(changed, l, t, r, b); 70392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 71392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int l1 = getPaddingLeft(); 72392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int t1 = getPaddingTop(); 73392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int r1 = getMeasuredWidth() - getPaddingRight(); 74392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 75cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann if ((mMoreOrLess != null)) { 76392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mMoreOrLess.layout( 77cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann r1 - mMoreOrLess.getMeasuredWidth(), t1, 78cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann r1, t1 + mMoreOrLess.getMeasuredHeight()); 79392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 80392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 81cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann // Subtract buttons if necessary 82cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann final int labelWidth = (getLabel() != null) ? getLabel().getMeasuredWidth() : 0; 83cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann final int deleteWidth = (getDelete() != null) ? getDelete().getMeasuredWidth() : 0; 84cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann final int moreOrLessWidth = mMoreOrLess != null ? mMoreOrLess.getMeasuredWidth() : 0; 85cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann final int r2 = r1 - Math.max(deleteWidth, moreOrLessWidth) - labelWidth; 86cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann 87cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann // Layout text fields 88392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int y = t1; 89392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mFieldEditTexts != null) { 90392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (EditText editText : mFieldEditTexts) { 91392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (editText.getVisibility() != View.GONE) { 92392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int height = editText.getMeasuredHeight(); 93392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann editText.layout( 94cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann l1, t1 + y, 95392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann r2, t1 + y + height); 96392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann y += height; 97392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 98392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 99392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 100392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 101392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 102392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 103392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected int getEditorHeight() { 104392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int result = 0; 105392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // summarize the EditText heights 106392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mFieldEditTexts != null) { 107392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (EditText editText : mFieldEditTexts) { 108392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (editText.getVisibility() != View.GONE) { 109392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann result += editText.getMeasuredHeight(); 110392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 111392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 112392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 113cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann // Ensure there is enough space for the minus and more/less button 114cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann final int deleteHeight = (getDelete() != null) ? getDelete().getMeasuredHeight() : 0; 115cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann final int moreOrLessHeight = mMoreOrLess != null ? mMoreOrLess.getMeasuredHeight() : 0; 116cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann result = Math.max(deleteHeight + moreOrLessHeight, result); 117392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return result; 118392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 119392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 120392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 121392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void setEnabled(boolean enabled) { 122392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super.setEnabled(enabled); 123392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 124392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mFieldEditTexts != null) { 125392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (int index = 0; index < mFieldEditTexts.length; index++) { 12602bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov mFieldEditTexts[index].setEnabled(!isReadOnly() && enabled); 127392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 128392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 12902bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov if (mMoreOrLess != null) mMoreOrLess.setEnabled(!isReadOnly() && enabled); 130392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 131392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 132392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 133392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Creates or removes the type/label button. Doesn't do anything if already correctly configured 134392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 135392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private void setupMoreOrLessButton(boolean shouldExist, boolean collapsed) { 136392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (shouldExist) { 137392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mMoreOrLess == null) { 138915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann mMoreOrLess = new ImageButton(mContext); 13979c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann mMoreOrLess.setBackgroundResource( 14079c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann ThemeUtils.getSelectableItemBackground(mContext.getTheme())); 141915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann final Resources resources = mContext.getResources(); 142915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann mMoreOrLess.setPadding( 143915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann resources.getDimensionPixelOffset( 144915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann R.dimen.editor_round_button_padding_left), 145915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann resources.getDimensionPixelOffset( 146915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann R.dimen.editor_round_button_padding_top), 147915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann resources.getDimensionPixelOffset( 148915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann R.dimen.editor_round_button_padding_right), 149915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann resources.getDimensionPixelOffset( 150915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann R.dimen.editor_round_button_padding_bottom)); 151392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mMoreOrLess.setLayoutParams( 152392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 153392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mMoreOrLess.setOnClickListener(new OnClickListener() { 154392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 155392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void onClick(View v) { 156392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Save focus 157392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final View focusedChild = getFocusedChild(); 158392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final int focusedViewId = focusedChild == null ? -1 : focusedChild.getId(); 159392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 160392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Reconfigure GUI 161392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mHideOptional = !mHideOptional; 162392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann onOptionalFieldVisibilityChange(); 163392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann rebuildValues(); 164392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 165392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Restore focus 166392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann View newFocusView = findViewById(focusedViewId); 167392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (newFocusView == null || newFocusView.getVisibility() == GONE) { 168392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // find first visible child 169392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann newFocusView = TextFieldsEditorView.this; 170392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 171cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann newFocusView.requestFocus(); 172392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 173392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann }); 174392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann addView(mMoreOrLess); 175392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 176915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann mMoreOrLess.setImageResource(collapsed 177915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann ? R.drawable.ic_menu_expander_minimized_holo_light 178915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann : R.drawable.ic_menu_expander_maximized_holo_light); 179392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } else if (mMoreOrLess != null) { 180392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann removeView(mMoreOrLess); 181392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mMoreOrLess = null; 182392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 183392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 184392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 185392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 186392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected void requestFocusForFirstEditField() { 187392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mFieldEditTexts != null && mFieldEditTexts.length != 0) { 188392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann EditText firstField = null; 189392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann boolean anyFieldHasFocus = false; 190392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (EditText editText : mFieldEditTexts) { 191392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (firstField == null && editText.getVisibility() == View.VISIBLE) { 192392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann firstField = editText; 193392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 194392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (editText.hasFocus()) { 195392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann anyFieldHasFocus = true; 196392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann break; 197392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 198392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 199392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (!anyFieldHasFocus && firstField != null) { 200392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann firstField.requestFocus(); 201392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 202392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 203392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 204392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 205392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 206392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly, 207392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann ViewIdGenerator vig) { 208392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super.setValues(kind, entry, state, readOnly, vig); 209392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Remove edit texts that we currently have 210392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mFieldEditTexts != null) { 211392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (EditText fieldEditText : mFieldEditTexts) { 212392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann removeView(fieldEditText); 213392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 214392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 215392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann boolean hidePossible = false; 216392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 217392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int fieldCount = kind.fieldList.size(); 218392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mFieldEditTexts = new EditText[fieldCount]; 219392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (int index = 0; index < fieldCount; index++) { 220392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final EditField field = kind.fieldList.get(index); 221392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final EditText fieldView = new EditText(mContext); 222392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 223392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann LayoutParams.WRAP_CONTENT)); 224392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setGravity(Gravity.TOP); 225392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mFieldEditTexts[index] = fieldView; 226392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setId(vig.getId(state, kind, entry, index)); 227392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (field.titleRes > 0) { 228392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setHint(field.titleRes); 229392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 230392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int inputType = field.inputType; 231392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setInputType(inputType); 232392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (inputType == InputType.TYPE_CLASS_PHONE) { 233392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.addTextChangedListener(new PhoneNumberFormattingTextWatcher( 234392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann ContactsUtils.getCurrentCountryIso(mContext))); 235392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 236392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setMinLines(field.minLines); 237392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 238392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Read current value from state 239392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final String column = field.column; 240392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final String value = entry.getAsString(column); 241392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setText(value); 242392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 243392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Prepare listener for writing changes 244392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.addTextChangedListener(new TextWatcher() { 245392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 246392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void afterTextChanged(Editable s) { 247392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Trigger event for newly changed value 248392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann onFieldChanged(column, s.toString()); 249392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 250392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 251392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 252392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void beforeTextChanged(CharSequence s, int start, int count, int after) { 253392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 254392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 255392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 256392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void onTextChanged(CharSequence s, int start, int before, int count) { 257392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 258392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann }); 259392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 26002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov fieldView.setEnabled(isEnabled() && !readOnly); 261392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 262392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (field.shortForm) { 263392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann hidePossible = true; 264392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mHasShortAndLongForms = true; 265392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setVisibility(mHideOptional ? View.VISIBLE : View.GONE); 266392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } else if (field.longForm) { 267392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann hidePossible = true; 268392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mHasShortAndLongForms = true; 269392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setVisibility(mHideOptional ? View.GONE : View.VISIBLE); 270392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } else { 271392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Hide field when empty and optional value 272392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final boolean couldHide = (!ContactsUtils.isGraphic(value) && field.optional); 273392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final boolean willHide = (mHideOptional && couldHide); 274392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann fieldView.setVisibility(willHide ? View.GONE : View.VISIBLE); 275392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann hidePossible = hidePossible || couldHide; 276392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 277392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 278392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann addView(fieldView); 279392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 280392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 281392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // When hiding fields, place expandable 282392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann setupMoreOrLessButton(hidePossible, mHideOptional); 28302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov if (mMoreOrLess != null) mMoreOrLess.setEnabled(!readOnly && isEnabled()); 284392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 285392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 286392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 287392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Returns true if the editor is currently configured to show optional fields. 288392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 289392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public boolean areOptionalFieldsVisible() { 290392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return !mHideOptional; 291392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 292392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 293392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public boolean hasShortAndLongForms() { 294392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return mHasShortAndLongForms; 295392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 296392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 297392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 298392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Populates the bound rectangle with the bounds of the last editor field inside this view. 299392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 300392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void acquireEditorBounds(Rect bounds) { 301392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mFieldEditTexts != null) { 302392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (int i = mFieldEditTexts.length; --i >= 0;) { 303392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann EditText editText = mFieldEditTexts[i]; 304392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (editText.getVisibility() == View.VISIBLE) { 305392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann bounds.set(editText.getLeft(), editText.getTop(), editText.getRight(), 306392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann editText.getBottom()); 307392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return; 308392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 309392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 310392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 311392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 312392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 313392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 314392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Saves the visibility of the child EditTexts, and mHideOptional. 315392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 316392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 317392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected Parcelable onSaveInstanceState() { 318392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann Parcelable superState = super.onSaveInstanceState(); 319392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann SavedState ss = new SavedState(superState); 320392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 321392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann ss.mHideOptional = mHideOptional; 322392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 323392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final int numChildren = mFieldEditTexts.length; 324392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann ss.mVisibilities = new int[numChildren]; 325392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (int i = 0; i < numChildren; i++) { 326392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann ss.mVisibilities[i] = mFieldEditTexts[i].getVisibility(); 327392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 328392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 329392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return ss; 330392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 331392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 332392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 333392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Restores the visibility of the child EditTexts, and mHideOptional. 334392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 335392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 336392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected void onRestoreInstanceState(Parcelable state) { 337392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann SavedState ss = (SavedState) state; 338392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super.onRestoreInstanceState(ss.getSuperState()); 339392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 340392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mHideOptional = ss.mHideOptional; 341392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 342392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int numChildren = Math.min(mFieldEditTexts.length, ss.mVisibilities.length); 343392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann for (int i = 0; i < numChildren; i++) { 344392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mFieldEditTexts[i].setVisibility(ss.mVisibilities[i]); 345392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 346392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 347392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 348392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private static class SavedState extends BaseSavedState { 349392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public boolean mHideOptional; 350392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public int[] mVisibilities; 351392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 352392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann SavedState(Parcelable superState) { 353392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super(superState); 354392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 355392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 356392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private SavedState(Parcel in) { 357392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super(in); 358392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mVisibilities = new int[in.readInt()]; 359392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann in.readIntArray(mVisibilities); 360392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 361392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 362392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 363392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void writeToParcel(Parcel out, int flags) { 364392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super.writeToParcel(out, flags); 365392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann out.writeInt(mVisibilities.length); 366392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann out.writeIntArray(mVisibilities); 367392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 368392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 369cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann @SuppressWarnings({"unused", "hiding" }) 370392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public static final Parcelable.Creator<SavedState> CREATOR 371392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann = new Parcelable.Creator<SavedState>() { 372392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 373392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public SavedState createFromParcel(Parcel in) { 374392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return new SavedState(in); 375392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 376392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 377392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 378392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public SavedState[] newArray(int size) { 379392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return new SavedState[size]; 380392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 381392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann }; 382392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 383392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann} 384