Loading src/com/android/contacts/editor/CompactKindSectionView.java +148 −98 Original line number Diff line number Diff line Loading @@ -17,8 +17,9 @@ package com.android.contacts.editor; import android.content.Context; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Nickname; import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.text.TextUtils; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; Loading @@ -35,8 +36,6 @@ import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.editor.Editor.EditorListener; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** Loading @@ -44,26 +43,6 @@ import java.util.List; */ public class CompactKindSectionView extends LinearLayout implements EditorListener { /** Sorts google account types before others. */ private static final class KindSectionComparator implements Comparator<KindSectionData> { private RawContactDeltaComparator mRawContactDeltaComparator; private KindSectionComparator(Context context) { mRawContactDeltaComparator = new RawContactDeltaComparator(context); } @Override public int compare(KindSectionData kindSectionData1, KindSectionData kindSectionData2) { if (kindSectionData1 == kindSectionData2) return 0; if (kindSectionData1 == null) return -1; if (kindSectionData2 == null) return 1; return mRawContactDeltaComparator.compare(kindSectionData1.getRawContactDelta(), kindSectionData2.getRawContactDelta()); } } /** * Marks a name as super primary when it is changed. * Loading @@ -74,7 +53,7 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen * Should only be set when a super primary name does not already exist since we only show * one name field. */ static final class NameEditorListener implements Editor.EditorListener { private static final class NameEditorListener implements Editor.EditorListener { private final ValuesDelta mValuesDelta; private final long mRawContactId; Loading @@ -101,13 +80,23 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen @Override public void onDeleteRequested(Editor editor) { editor.clearAllFields(); } } private ViewGroup mEditors; private ImageView mIcon; private static final class NicknameEditorListener implements Editor.EditorListener { @Override public void onRequest(int request) { } @Override public void onDeleteRequested(Editor editor) { editor.clearAllFields(); } } private List<KindSectionData> mKindSectionDatas; private List<KindSectionData> mKindSectionDataList; private boolean mReadOnly; private ViewIdGenerator mViewIdGenerator; private CompactRawContactsEditorView.Listener mListener; Loading @@ -117,6 +106,8 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen private boolean mHideIfEmpty = true; private LayoutInflater mInflater; private ViewGroup mEditors; private ImageView mIcon; public CompactKindSectionView(Context context) { this(context, /* attrs =*/ null); Loading @@ -135,8 +126,6 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen mEditors.getChildAt(i).setEnabled(enabled); } } // TODO: why is this necessary? updateEmptyEditors(/* shouldAnimate = */ true); } /** {@inheritDoc} */ Loading Loading @@ -172,8 +161,9 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen } /** * @param showOneEmptyEditor If true, we will always show one empty, otherwise an empty editor * will not be shown until the user enters a value. * @param showOneEmptyEditor If true, we will always show one empty editor, otherwise an empty * editor will not be shown until the user enters a value. Note, this has no effect * on name editors since the policy is to always show names. */ public void setShowOneEmptyEditor(boolean showOneEmptyEditor) { mShowOneEmptyEditor = showOneEmptyEditor; Loading @@ -181,23 +171,23 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen /** * @param hideWhenEmpty If true, the entire section will be hidden if all inputs are empty, * otherwise one empty input will always be displayed. * otherwise one empty input will always be displayed. Note, this has no effect * on name editors since the policy is to always show names. */ public void setHideWhenEmpty(boolean hideWhenEmpty) { mHideIfEmpty = hideWhenEmpty; } public void setState(List<KindSectionData> kindSectionDatas, boolean readOnly, public void setState(List<KindSectionData> kindSectionDataList, boolean readOnly, ViewIdGenerator viewIdGenerator, CompactRawContactsEditorView.Listener listener) { mKindSectionDatas = kindSectionDatas; Collections.sort(mKindSectionDatas, new KindSectionComparator(getContext())); mKindSectionDataList = kindSectionDataList; mReadOnly = readOnly; mViewIdGenerator = viewIdGenerator; mListener = listener; // Set the icon using the first DataKind (all DataKinds should be the same type) final DataKind dataKind = mKindSectionDatas.isEmpty() ? null : mKindSectionDatas.get(0).getDataKind(); final DataKind dataKind = mKindSectionDataList.isEmpty() ? null : mKindSectionDataList.get(0).getDataKind(); if (dataKind != null) { mIcon.setContentDescription(dataKind.titleRes == -1 || dataKind.titleRes == 0 ? "" : getResources().getString(dataKind.titleRes)); Loading @@ -217,20 +207,10 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen private void rebuildFromState() { mEditors.removeAllViews(); // Check if we are displaying anything here boolean hasValuesDeltas = false; for (KindSectionData kindSectionData : mKindSectionDatas) { if (kindSectionData.hasValuesDeltas()) { hasValuesDeltas = true; break; } } if (!hasValuesDeltas) return; for (KindSectionData kindSectionData : mKindSectionDatas) { for (KindSectionData kindSectionData : mKindSectionDataList) { if (StructuredName.CONTENT_ITEM_TYPE.equals(kindSectionData.getDataKind().mimeType)) { for (ValuesDelta valuesDelta : kindSectionData.getValuesDeltas()) { createStructuredNameEditorView(kindSectionData.getAccountType(), createNameEditorViews(kindSectionData.getAccountType(), valuesDelta, kindSectionData.getRawContactDelta()); } } else { Loading @@ -242,21 +222,41 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen } } private void createStructuredNameEditorView(AccountType accountType, private void createNameEditorViews(AccountType accountType, ValuesDelta valuesDelta, RawContactDelta rawContactDelta) { final StructuredNameEditorView view = (StructuredNameEditorView) mInflater.inflate( final boolean readOnly = !accountType.areContactsWritable(); // Structured name final StructuredNameEditorView nameView = (StructuredNameEditorView) mInflater.inflate( R.layout.structured_name_editor_view, mEditors, /* attachToRoot =*/ false); view.setEditorListener(new NameEditorListener(valuesDelta, nameView.setEditorListener(new NameEditorListener(valuesDelta, rawContactDelta.getRawContactId(), mListener)); view.findViewById(R.id.kind_icon).setVisibility(View.GONE); view.setDeletable(false); final boolean readOnly = !accountType.areContactsWritable(); view.setValues(accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME), nameView.setDeletable(false); nameView.setValues( accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME), valuesDelta, rawContactDelta, readOnly, mViewIdGenerator); if (readOnly) { view.setAccountType(accountType); } mEditors.addView(view); if (readOnly) nameView.setAccountType(accountType); // Correct start margin since there is another icon in the structured name layout nameView.findViewById(R.id.kind_icon).setVisibility(View.GONE); mEditors.addView(nameView); // Phonetic name if (readOnly) return; final PhoneticNameEditorView phoneticNameView = (PhoneticNameEditorView) mInflater.inflate( R.layout.phonetic_name_editor_view, mEditors, /* attachToRoot =*/ false); phoneticNameView.setDeletable(false); phoneticNameView.setValues( accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME), valuesDelta, rawContactDelta, readOnly, mViewIdGenerator); // Fix the start margin for phonetic name views final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(0, 0, 0, 0); phoneticNameView.setLayoutParams(layoutParams); mEditors.addView(phoneticNameView); } /** Loading @@ -281,21 +281,18 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen ((LabeledEditorView) view).setHideTypeInitially(true); } // Fix the start margin for phonetic name views if (view instanceof PhoneticNameEditorView) { final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(0, 0, 0, 0); view.setLayoutParams(layoutParams); } // Set whether the editor is enabled view.setEnabled(isEnabled()); if (view instanceof Editor) { final Editor editor = (Editor) view; editor.setDeletable(true); // TODO: it's awkward to be doing something special for nicknames here if (Nickname.CONTENT_ITEM_TYPE.equals(dataKind.mimeType)) { editor.setEditorListener(new NicknameEditorListener()); } else { editor.setEditorListener(this); } editor.setValues(dataKind, valuesDelta, rawContactDelta, !dataKind.editable, mViewIdGenerator); } Loading @@ -310,10 +307,46 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen * then the entire section is hidden. */ public void updateEmptyEditors(boolean shouldAnimate) { if (mKindSectionDatas.isEmpty()) return; final DataKind dataKind = mKindSectionDatas.get(0).getDataKind(); final RawContactDelta rawContactDelta = mKindSectionDatas.get(0).getRawContactDelta(); if (mKindSectionDataList.get(0).isNameDataKind()) { updateEmptyNameEditors(shouldAnimate); } else { updateEmptyNonNameEditors(shouldAnimate); } } private void updateEmptyNameEditors(boolean shouldAnimate) { boolean isEmptyNameEditorVisible = false; for (int i = 0; i < mEditors.getChildCount(); i++) { final View view = mEditors.getChildAt(i); final Editor editor = (Editor) view; if (view instanceof StructuredNameEditorView) { // We always show one empty structured name view if (editor.isEmpty()) { if (isEmptyNameEditorVisible) { // If we're already showing an empty editor then hide any other empties if (mHideIfEmpty) { view.setVisibility(View.GONE); } } else { isEmptyNameEditorVisible = true; } } else { showView(view, shouldAnimate); isEmptyNameEditorVisible = true; } } else { // For phonetic names and nicknames, which can't be added, just show or hide them if (mHideIfEmpty && editor.isEmpty()) { hideView(view, shouldAnimate); } else { showView(view, shouldAnimate); } } } } private void updateEmptyNonNameEditors(boolean shouldAnimate) { // Update whether the entire section is visible or not final int editorCount = getEditorCount(); final List<View> emptyEditors = getEmptyEditors(); Loading @@ -323,36 +356,28 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen } setVisibility(VISIBLE); // Update the number of empty editors // Prune excess empty editors if (emptyEditors.size() > 1) { // If there is more than 1 empty editor, then remove it from the list of editors. int deleted = 0; for (final View emptyEditorView : emptyEditors) { for (final View view : emptyEditors) { // If no child {@link View}s are being focused on within this {@link View}, then // remove this empty editor. We can assume that at least one empty editor has focus. // One way to get two empty editors is by deleting characters from a non-empty // editor, in which case this editor has focus. Another way is if there is more // values delta so we must also count number of editors deleted. // TODO: we must not delete the editor for the "primary" account. It's working // because the primary account is always the last one when the account is changed // in the editor but it is a bit brittle to rely on that (though that is what is // happening in LMP). if (emptyEditorView.findFocus() == null) { final Editor editor = (Editor) emptyEditorView; if (shouldAnimate) { editor.deleteEditor(); } else { mEditors.removeView(emptyEditorView); } // remove this empty editor. We can assume that at least one empty editor has // focus. One way to get two empty editors is by deleting characters from a // non-empty editor, in which case this editor has focus. Another way is if // there is more values delta so we must also count number of editors deleted. if (view.findFocus() == null) { deleteView(view, shouldAnimate); deleted++; if (deleted == emptyEditors.size() - 1) break; } } return; } if (dataKind == null // There is nothing we can do. || mReadOnly // We don't show empty editors for read only data kinds. // Determine if we should add a new empty editor final DataKind dataKind = mKindSectionDataList.get(0).getDataKind(); if (mReadOnly // We don't show empty editors for read only data kinds. || dataKind == null // There is nothing we can do. // We have already reached the maximum number of editors, don't add any more. || (dataKind.typeOverallMax == editorCount && dataKind.typeOverallMax != 0) // We have already reached the maximum number of empty editors, don't add any more. Loading @@ -361,12 +386,37 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen } // Add a new empty editor if (mShowOneEmptyEditor) { final RawContactDelta rawContactDelta = mKindSectionDataList.get(0).getRawContactDelta(); final ValuesDelta values = RawContactModifier.insertChild(rawContactDelta, dataKind); final View editorView = createEditorView(rawContactDelta, dataKind, values); final View view = createEditorView(rawContactDelta, dataKind, values); showView(view, shouldAnimate); } } private void hideView(View view, boolean shouldAnimate) { if (shouldAnimate) { editorView.setVisibility(View.GONE); EditorAnimator.getInstance().showFieldFooter(editorView); EditorAnimator.getInstance().hideEditorView(view); } else { view.setVisibility(View.GONE); } } private void deleteView(View view, boolean shouldAnimate) { if (shouldAnimate) { final Editor editor = (Editor) view; editor.deleteEditor(); } else { mEditors.removeView(view); } } private void showView(View view, boolean shouldAnimate) { if (shouldAnimate) { view.setVisibility(View.GONE); // TODO: still need this since we have animateLayoutChanges="true" on the parent layout? EditorAnimator.getInstance().showFieldFooter(view); } else { view.setVisibility(View.VISIBLE); } } Loading src/com/android/contacts/editor/CompactRawContactsEditorView.java +181 −58 File changed.Preview size limit exceeded, changes collapsed. Show changes src/com/android/contacts/editor/KindSectionData.java +8 −13 Original line number Diff line number Diff line Loading @@ -22,10 +22,10 @@ import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountType.EditField; import com.android.contacts.common.model.dataitem.DataKind; import android.provider.ContactsContract.CommonDataKinds.Nickname; import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.text.TextUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; Loading @@ -44,23 +44,13 @@ public final class KindSectionData { mAccountType = accountType; mDataKind = dataKind; mRawContactDelta = rawContactDelta; // Note that for phonetic names we use the structured name mime type to look up values final String mimeType = DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(dataKind.mimeType) ? StructuredName.CONTENT_ITEM_TYPE : dataKind.mimeType; mValuesDeltas = mRawContactDelta.hasMimeEntries(mimeType) ? mRawContactDelta.getMimeEntries(mimeType) : Collections.EMPTY_LIST; mValuesDeltas = mRawContactDelta.getMimeEntries(dataKind.mimeType, /* lazyCreate= */ true); } public AccountType getAccountType() { return mAccountType; } public boolean hasValuesDeltas() { return !mValuesDeltas.isEmpty(); } public List<ValuesDelta> getValuesDeltas() { return mValuesDeltas; } Loading Loading @@ -107,6 +97,11 @@ public final class KindSectionData { return mDataKind; } public boolean isNameDataKind() { return StructuredName.CONTENT_ITEM_TYPE.equals(mDataKind.mimeType) || Nickname.CONTENT_ITEM_TYPE.equals(mDataKind.mimeType); } public RawContactDelta getRawContactDelta() { return mRawContactDelta; } Loading @@ -116,6 +111,6 @@ public final class KindSectionData { KindSectionData.class.getSimpleName(), mAccountType.accountType, mAccountType.dataSet, hasValuesDeltas() ? getValuesDeltas().size() : "null"); getValuesDeltas().size()); } } No newline at end of file Loading
src/com/android/contacts/editor/CompactKindSectionView.java +148 −98 Original line number Diff line number Diff line Loading @@ -17,8 +17,9 @@ package com.android.contacts.editor; import android.content.Context; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Nickname; import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.text.TextUtils; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; Loading @@ -35,8 +36,6 @@ import com.android.contacts.common.model.dataitem.DataKind; import com.android.contacts.editor.Editor.EditorListener; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** Loading @@ -44,26 +43,6 @@ import java.util.List; */ public class CompactKindSectionView extends LinearLayout implements EditorListener { /** Sorts google account types before others. */ private static final class KindSectionComparator implements Comparator<KindSectionData> { private RawContactDeltaComparator mRawContactDeltaComparator; private KindSectionComparator(Context context) { mRawContactDeltaComparator = new RawContactDeltaComparator(context); } @Override public int compare(KindSectionData kindSectionData1, KindSectionData kindSectionData2) { if (kindSectionData1 == kindSectionData2) return 0; if (kindSectionData1 == null) return -1; if (kindSectionData2 == null) return 1; return mRawContactDeltaComparator.compare(kindSectionData1.getRawContactDelta(), kindSectionData2.getRawContactDelta()); } } /** * Marks a name as super primary when it is changed. * Loading @@ -74,7 +53,7 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen * Should only be set when a super primary name does not already exist since we only show * one name field. */ static final class NameEditorListener implements Editor.EditorListener { private static final class NameEditorListener implements Editor.EditorListener { private final ValuesDelta mValuesDelta; private final long mRawContactId; Loading @@ -101,13 +80,23 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen @Override public void onDeleteRequested(Editor editor) { editor.clearAllFields(); } } private ViewGroup mEditors; private ImageView mIcon; private static final class NicknameEditorListener implements Editor.EditorListener { @Override public void onRequest(int request) { } @Override public void onDeleteRequested(Editor editor) { editor.clearAllFields(); } } private List<KindSectionData> mKindSectionDatas; private List<KindSectionData> mKindSectionDataList; private boolean mReadOnly; private ViewIdGenerator mViewIdGenerator; private CompactRawContactsEditorView.Listener mListener; Loading @@ -117,6 +106,8 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen private boolean mHideIfEmpty = true; private LayoutInflater mInflater; private ViewGroup mEditors; private ImageView mIcon; public CompactKindSectionView(Context context) { this(context, /* attrs =*/ null); Loading @@ -135,8 +126,6 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen mEditors.getChildAt(i).setEnabled(enabled); } } // TODO: why is this necessary? updateEmptyEditors(/* shouldAnimate = */ true); } /** {@inheritDoc} */ Loading Loading @@ -172,8 +161,9 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen } /** * @param showOneEmptyEditor If true, we will always show one empty, otherwise an empty editor * will not be shown until the user enters a value. * @param showOneEmptyEditor If true, we will always show one empty editor, otherwise an empty * editor will not be shown until the user enters a value. Note, this has no effect * on name editors since the policy is to always show names. */ public void setShowOneEmptyEditor(boolean showOneEmptyEditor) { mShowOneEmptyEditor = showOneEmptyEditor; Loading @@ -181,23 +171,23 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen /** * @param hideWhenEmpty If true, the entire section will be hidden if all inputs are empty, * otherwise one empty input will always be displayed. * otherwise one empty input will always be displayed. Note, this has no effect * on name editors since the policy is to always show names. */ public void setHideWhenEmpty(boolean hideWhenEmpty) { mHideIfEmpty = hideWhenEmpty; } public void setState(List<KindSectionData> kindSectionDatas, boolean readOnly, public void setState(List<KindSectionData> kindSectionDataList, boolean readOnly, ViewIdGenerator viewIdGenerator, CompactRawContactsEditorView.Listener listener) { mKindSectionDatas = kindSectionDatas; Collections.sort(mKindSectionDatas, new KindSectionComparator(getContext())); mKindSectionDataList = kindSectionDataList; mReadOnly = readOnly; mViewIdGenerator = viewIdGenerator; mListener = listener; // Set the icon using the first DataKind (all DataKinds should be the same type) final DataKind dataKind = mKindSectionDatas.isEmpty() ? null : mKindSectionDatas.get(0).getDataKind(); final DataKind dataKind = mKindSectionDataList.isEmpty() ? null : mKindSectionDataList.get(0).getDataKind(); if (dataKind != null) { mIcon.setContentDescription(dataKind.titleRes == -1 || dataKind.titleRes == 0 ? "" : getResources().getString(dataKind.titleRes)); Loading @@ -217,20 +207,10 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen private void rebuildFromState() { mEditors.removeAllViews(); // Check if we are displaying anything here boolean hasValuesDeltas = false; for (KindSectionData kindSectionData : mKindSectionDatas) { if (kindSectionData.hasValuesDeltas()) { hasValuesDeltas = true; break; } } if (!hasValuesDeltas) return; for (KindSectionData kindSectionData : mKindSectionDatas) { for (KindSectionData kindSectionData : mKindSectionDataList) { if (StructuredName.CONTENT_ITEM_TYPE.equals(kindSectionData.getDataKind().mimeType)) { for (ValuesDelta valuesDelta : kindSectionData.getValuesDeltas()) { createStructuredNameEditorView(kindSectionData.getAccountType(), createNameEditorViews(kindSectionData.getAccountType(), valuesDelta, kindSectionData.getRawContactDelta()); } } else { Loading @@ -242,21 +222,41 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen } } private void createStructuredNameEditorView(AccountType accountType, private void createNameEditorViews(AccountType accountType, ValuesDelta valuesDelta, RawContactDelta rawContactDelta) { final StructuredNameEditorView view = (StructuredNameEditorView) mInflater.inflate( final boolean readOnly = !accountType.areContactsWritable(); // Structured name final StructuredNameEditorView nameView = (StructuredNameEditorView) mInflater.inflate( R.layout.structured_name_editor_view, mEditors, /* attachToRoot =*/ false); view.setEditorListener(new NameEditorListener(valuesDelta, nameView.setEditorListener(new NameEditorListener(valuesDelta, rawContactDelta.getRawContactId(), mListener)); view.findViewById(R.id.kind_icon).setVisibility(View.GONE); view.setDeletable(false); final boolean readOnly = !accountType.areContactsWritable(); view.setValues(accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME), nameView.setDeletable(false); nameView.setValues( accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME), valuesDelta, rawContactDelta, readOnly, mViewIdGenerator); if (readOnly) { view.setAccountType(accountType); } mEditors.addView(view); if (readOnly) nameView.setAccountType(accountType); // Correct start margin since there is another icon in the structured name layout nameView.findViewById(R.id.kind_icon).setVisibility(View.GONE); mEditors.addView(nameView); // Phonetic name if (readOnly) return; final PhoneticNameEditorView phoneticNameView = (PhoneticNameEditorView) mInflater.inflate( R.layout.phonetic_name_editor_view, mEditors, /* attachToRoot =*/ false); phoneticNameView.setDeletable(false); phoneticNameView.setValues( accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME), valuesDelta, rawContactDelta, readOnly, mViewIdGenerator); // Fix the start margin for phonetic name views final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(0, 0, 0, 0); phoneticNameView.setLayoutParams(layoutParams); mEditors.addView(phoneticNameView); } /** Loading @@ -281,21 +281,18 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen ((LabeledEditorView) view).setHideTypeInitially(true); } // Fix the start margin for phonetic name views if (view instanceof PhoneticNameEditorView) { final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); layoutParams.setMargins(0, 0, 0, 0); view.setLayoutParams(layoutParams); } // Set whether the editor is enabled view.setEnabled(isEnabled()); if (view instanceof Editor) { final Editor editor = (Editor) view; editor.setDeletable(true); // TODO: it's awkward to be doing something special for nicknames here if (Nickname.CONTENT_ITEM_TYPE.equals(dataKind.mimeType)) { editor.setEditorListener(new NicknameEditorListener()); } else { editor.setEditorListener(this); } editor.setValues(dataKind, valuesDelta, rawContactDelta, !dataKind.editable, mViewIdGenerator); } Loading @@ -310,10 +307,46 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen * then the entire section is hidden. */ public void updateEmptyEditors(boolean shouldAnimate) { if (mKindSectionDatas.isEmpty()) return; final DataKind dataKind = mKindSectionDatas.get(0).getDataKind(); final RawContactDelta rawContactDelta = mKindSectionDatas.get(0).getRawContactDelta(); if (mKindSectionDataList.get(0).isNameDataKind()) { updateEmptyNameEditors(shouldAnimate); } else { updateEmptyNonNameEditors(shouldAnimate); } } private void updateEmptyNameEditors(boolean shouldAnimate) { boolean isEmptyNameEditorVisible = false; for (int i = 0; i < mEditors.getChildCount(); i++) { final View view = mEditors.getChildAt(i); final Editor editor = (Editor) view; if (view instanceof StructuredNameEditorView) { // We always show one empty structured name view if (editor.isEmpty()) { if (isEmptyNameEditorVisible) { // If we're already showing an empty editor then hide any other empties if (mHideIfEmpty) { view.setVisibility(View.GONE); } } else { isEmptyNameEditorVisible = true; } } else { showView(view, shouldAnimate); isEmptyNameEditorVisible = true; } } else { // For phonetic names and nicknames, which can't be added, just show or hide them if (mHideIfEmpty && editor.isEmpty()) { hideView(view, shouldAnimate); } else { showView(view, shouldAnimate); } } } } private void updateEmptyNonNameEditors(boolean shouldAnimate) { // Update whether the entire section is visible or not final int editorCount = getEditorCount(); final List<View> emptyEditors = getEmptyEditors(); Loading @@ -323,36 +356,28 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen } setVisibility(VISIBLE); // Update the number of empty editors // Prune excess empty editors if (emptyEditors.size() > 1) { // If there is more than 1 empty editor, then remove it from the list of editors. int deleted = 0; for (final View emptyEditorView : emptyEditors) { for (final View view : emptyEditors) { // If no child {@link View}s are being focused on within this {@link View}, then // remove this empty editor. We can assume that at least one empty editor has focus. // One way to get two empty editors is by deleting characters from a non-empty // editor, in which case this editor has focus. Another way is if there is more // values delta so we must also count number of editors deleted. // TODO: we must not delete the editor for the "primary" account. It's working // because the primary account is always the last one when the account is changed // in the editor but it is a bit brittle to rely on that (though that is what is // happening in LMP). if (emptyEditorView.findFocus() == null) { final Editor editor = (Editor) emptyEditorView; if (shouldAnimate) { editor.deleteEditor(); } else { mEditors.removeView(emptyEditorView); } // remove this empty editor. We can assume that at least one empty editor has // focus. One way to get two empty editors is by deleting characters from a // non-empty editor, in which case this editor has focus. Another way is if // there is more values delta so we must also count number of editors deleted. if (view.findFocus() == null) { deleteView(view, shouldAnimate); deleted++; if (deleted == emptyEditors.size() - 1) break; } } return; } if (dataKind == null // There is nothing we can do. || mReadOnly // We don't show empty editors for read only data kinds. // Determine if we should add a new empty editor final DataKind dataKind = mKindSectionDataList.get(0).getDataKind(); if (mReadOnly // We don't show empty editors for read only data kinds. || dataKind == null // There is nothing we can do. // We have already reached the maximum number of editors, don't add any more. || (dataKind.typeOverallMax == editorCount && dataKind.typeOverallMax != 0) // We have already reached the maximum number of empty editors, don't add any more. Loading @@ -361,12 +386,37 @@ public class CompactKindSectionView extends LinearLayout implements EditorListen } // Add a new empty editor if (mShowOneEmptyEditor) { final RawContactDelta rawContactDelta = mKindSectionDataList.get(0).getRawContactDelta(); final ValuesDelta values = RawContactModifier.insertChild(rawContactDelta, dataKind); final View editorView = createEditorView(rawContactDelta, dataKind, values); final View view = createEditorView(rawContactDelta, dataKind, values); showView(view, shouldAnimate); } } private void hideView(View view, boolean shouldAnimate) { if (shouldAnimate) { editorView.setVisibility(View.GONE); EditorAnimator.getInstance().showFieldFooter(editorView); EditorAnimator.getInstance().hideEditorView(view); } else { view.setVisibility(View.GONE); } } private void deleteView(View view, boolean shouldAnimate) { if (shouldAnimate) { final Editor editor = (Editor) view; editor.deleteEditor(); } else { mEditors.removeView(view); } } private void showView(View view, boolean shouldAnimate) { if (shouldAnimate) { view.setVisibility(View.GONE); // TODO: still need this since we have animateLayoutChanges="true" on the parent layout? EditorAnimator.getInstance().showFieldFooter(view); } else { view.setVisibility(View.VISIBLE); } } Loading
src/com/android/contacts/editor/CompactRawContactsEditorView.java +181 −58 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/com/android/contacts/editor/KindSectionData.java +8 −13 Original line number Diff line number Diff line Loading @@ -22,10 +22,10 @@ import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountType.EditField; import com.android.contacts.common.model.dataitem.DataKind; import android.provider.ContactsContract.CommonDataKinds.Nickname; import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.text.TextUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; Loading @@ -44,23 +44,13 @@ public final class KindSectionData { mAccountType = accountType; mDataKind = dataKind; mRawContactDelta = rawContactDelta; // Note that for phonetic names we use the structured name mime type to look up values final String mimeType = DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(dataKind.mimeType) ? StructuredName.CONTENT_ITEM_TYPE : dataKind.mimeType; mValuesDeltas = mRawContactDelta.hasMimeEntries(mimeType) ? mRawContactDelta.getMimeEntries(mimeType) : Collections.EMPTY_LIST; mValuesDeltas = mRawContactDelta.getMimeEntries(dataKind.mimeType, /* lazyCreate= */ true); } public AccountType getAccountType() { return mAccountType; } public boolean hasValuesDeltas() { return !mValuesDeltas.isEmpty(); } public List<ValuesDelta> getValuesDeltas() { return mValuesDeltas; } Loading Loading @@ -107,6 +97,11 @@ public final class KindSectionData { return mDataKind; } public boolean isNameDataKind() { return StructuredName.CONTENT_ITEM_TYPE.equals(mDataKind.mimeType) || Nickname.CONTENT_ITEM_TYPE.equals(mDataKind.mimeType); } public RawContactDelta getRawContactDelta() { return mRawContactDelta; } Loading @@ -116,6 +111,6 @@ public final class KindSectionData { KindSectionData.class.getSimpleName(), mAccountType.accountType, mAccountType.dataSet, hasValuesDeltas() ? getValuesDeltas().size() : "null"); getValuesDeltas().size()); } } No newline at end of file