Some minor improvements to Contact Editor design
- Can supply a custom editor class for a specific data kind
- Can have a field that fills up a row instead of leaving
whitespace at the bottom
- Convenience method isChanged that checks if a specific
field has been changed.
Change-Id: I7dcc4ba1a3100675362e1fc69b4afc3e6793f373
diff --git a/src/com/android/contacts/model/ContactsSource.java b/src/com/android/contacts/model/ContactsSource.java
index d498398..b417224 100644
--- a/src/com/android/contacts/model/ContactsSource.java
+++ b/src/com/android/contacts/model/ContactsSource.java
@@ -25,11 +25,12 @@
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.view.View;
import android.widget.EditText;
import java.util.ArrayList;
@@ -221,10 +222,17 @@
public ContentValues defaultValues;
+ public Class<? extends View> editorClass;
+
public DataKind() {
}
public DataKind(String mimeType, int titleRes, int iconRes, int weight, boolean editable) {
+ this(mimeType, titleRes, iconRes, weight, editable, null);
+ }
+
+ public DataKind(String mimeType, int titleRes, int iconRes, int weight, boolean editable,
+ Class<? extends View> editorClass) {
this.mimeType = mimeType;
this.titleRes = titleRes;
this.iconRes = iconRes;
@@ -232,6 +240,7 @@
this.editable = editable;
this.isList = true;
this.typeOverallMax = -1;
+ this.editorClass = editorClass;
}
}
@@ -324,6 +333,11 @@
this.longForm = longForm;
return this;
}
+
+ public EditField setMinLines(int minLines) {
+ this.minLines = minLines;
+ return this;
+ }
}
/**
diff --git a/src/com/android/contacts/model/Editor.java b/src/com/android/contacts/model/Editor.java
index 04e023b..c73839d 100644
--- a/src/com/android/contacts/model/Editor.java
+++ b/src/com/android/contacts/model/Editor.java
@@ -58,6 +58,8 @@
public void setValues(DataKind kind, ValuesDelta values, EntityDelta state, boolean readOnly,
ViewIdGenerator vig);
+ public void setDeletable(boolean deletable);
+
/**
* Add a specific {@link EditorListener} to this {@link Editor}.
*/
diff --git a/src/com/android/contacts/model/EntityDelta.java b/src/com/android/contacts/model/EntityDelta.java
index 4f018a9..e353d70 100644
--- a/src/com/android/contacts/model/EntityDelta.java
+++ b/src/com/android/contacts/model/EntityDelta.java
@@ -578,6 +578,21 @@
}
}
+ public boolean isChanged(String key) {
+ if (mAfter == null || !mAfter.containsKey(key)) {
+ return false;
+ }
+
+ Object newValue = mAfter.get(key);
+ Object oldValue = mBefore.get(key);
+
+ if (oldValue == null) {
+ return newValue != null;
+ }
+
+ return !oldValue.equals(newValue);
+ }
+
public String getMimetype() {
return getAsString(Data.MIMETYPE);
}
diff --git a/src/com/android/contacts/ui/widget/GenericEditorView.java b/src/com/android/contacts/ui/widget/GenericEditorView.java
index b5e0c4f..6be238f 100644
--- a/src/com/android/contacts/ui/widget/GenericEditorView.java
+++ b/src/com/android/contacts/ui/widget/GenericEditorView.java
@@ -43,6 +43,7 @@
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -164,13 +165,38 @@
// summarize the EditText heights
int totalHeight = 0;
+ int visibleFieldCount = 0;
+ EditText firstVisibleField = null;
if (mFieldEditTexts != null) {
for (EditText editText : mFieldEditTexts) {
if (editText.getVisibility() != View.GONE) {
+ visibleFieldCount ++;
+ if (firstVisibleField == null) {
+ firstVisibleField = editText;
+ }
totalHeight += editText.getMeasuredHeight();
}
}
}
+
+ int padding = getPaddingTop() + getPaddingBottom();
+ int minHeight = padding;
+
+ if (mMoreOrLess != null) {
+ minHeight += mMoreOrLess.getMeasuredHeight();
+ }
+
+ if (mDelete != null) {
+ minHeight += mDelete.getMeasuredHeight();
+ }
+
+ if (minHeight > totalHeight && visibleFieldCount == 1) {
+ firstVisibleField.measure(widthMeasureSpec,
+ MeasureSpec.makeMeasureSpec(minHeight - padding, MeasureSpec.EXACTLY));
+ }
+
+ totalHeight = Math.max(minHeight, totalHeight);
+
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
resolveSize(totalHeight, heightMeasureSpec));
}
@@ -259,9 +285,7 @@
// Reconfigure GUI
mHideOptional = !mHideOptional;
- if (mListener != null) {
- mListener.onRequest(EditorListener.EDITOR_FORM_CHANGED);
- }
+ onOptionalFieldVisibilityChange();
rebuildValues();
// Restore focus
@@ -285,6 +309,12 @@
}
}
+ protected void onOptionalFieldVisibilityChange() {
+ if (mListener != null) {
+ mListener.onRequest(EditorListener.EDITOR_FORM_CHANGED);
+ }
+ }
+
public void setEditorListener(EditorListener listener) {
mListener = listener;
}
@@ -398,6 +428,7 @@
final EditText fieldView = new EditText(mContext);
fieldView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
+ fieldView.setGravity(Gravity.TOP);
mFieldEditTexts[index] = fieldView;
fieldView.setId(vig.getId(state, kind, entry, index));
if (field.titleRes > 0) {
diff --git a/src/com/android/contacts/ui/widget/KindSectionView.java b/src/com/android/contacts/ui/widget/KindSectionView.java
index cb20566..cd0b6fb 100644
--- a/src/com/android/contacts/ui/widget/KindSectionView.java
+++ b/src/com/android/contacts/ui/widget/KindSectionView.java
@@ -17,12 +17,12 @@
package com.android.contacts.ui.widget;
import com.android.contacts.R;
-import com.android.contacts.model.Editor;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityModifier;
import com.android.contacts.model.ContactsSource.DataKind;
+import com.android.contacts.model.Editor;
import com.android.contacts.model.Editor.EditorListener;
+import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
+import com.android.contacts.model.EntityModifier;
import com.android.contacts.ui.ViewIdGenerator;
import android.content.Context;
@@ -137,13 +137,27 @@
if (!entry.isVisible()) continue;
if (isEmptyNoop(entry)) continue;
- final GenericEditorView editor = new GenericEditorView(mContext);
+ final View view;
+ if (mKind.editorClass == null) {
+ view = new GenericEditorView(mContext);
+ } else {
+ try {
+ view = mKind.editorClass.getConstructor(Context.class).newInstance(
+ mContext);
+ } catch (Exception e) {
+ throw new RuntimeException(
+ "Cannot allocate editor for " + mKind.editorClass);
+ }
+ }
- editor.setPadding(0, 0, getThemeScrollbarSize(mContext), 0);
- editor.setValues(mKind, entry, mState, mReadOnly, mViewIdGenerator);
- editor.setEditorListener(this);
- editor.setDeletable(true);
- mEditors.addView(editor);
+ view.setPadding(0, 0, getThemeScrollbarSize(mContext), 0);
+ if (view instanceof Editor) {
+ Editor editor = (Editor) view;
+ editor.setValues(mKind, entry, mState, mReadOnly, mViewIdGenerator);
+ editor.setEditorListener(this);
+ editor.setDeletable(true);
+ }
+ mEditors.addView(view);
entryIndex++;
}
}
diff --git a/src/com/android/contacts/ui/widget/PhotoEditorView.java b/src/com/android/contacts/ui/widget/PhotoEditorView.java
index eff39d0..da1be85 100644
--- a/src/com/android/contacts/ui/widget/PhotoEditorView.java
+++ b/src/com/android/contacts/ui/widget/PhotoEditorView.java
@@ -168,4 +168,9 @@
public void setEditorListener(EditorListener listener) {
mListener = listener;
}
+
+ @Override
+ public void setDeletable(boolean deletable) {
+ // Photo is not deletable
+ }
}