OSDN Git Service

Show phones and email addresses for read-only contacts.
authorJeff Hamilton <jham@android.com>
Sun, 11 Oct 2009 06:17:48 +0000 (01:17 -0500)
committerJeff Hamilton <jham@android.com>
Mon, 12 Oct 2009 18:52:22 +0000 (13:52 -0500)
Bug: 2180041
Change-Id: I686e5413bb3de4c9373da177673c485581c87bb9

res/layout/item_read_only_contact_editor.xml [new file with mode: 0644]
res/layout/item_read_only_field.xml [new file with mode: 0644]
src/com/android/contacts/ui/EditContactActivity.java
src/com/android/contacts/ui/widget/BaseContactEditorView.java [new file with mode: 0644]
src/com/android/contacts/ui/widget/ContactEditorView.java
src/com/android/contacts/ui/widget/ReadOnlyContactEditorView.java [new file with mode: 0644]

diff --git a/res/layout/item_read_only_contact_editor.xml b/res/layout/item_read_only_contact_editor.xml
new file mode 100644 (file)
index 0000000..370093c
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- placed inside act_edit as tabcontent -->
+<com.android.contacts.ui.widget.ReadOnlyContactEditorView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+>
+
+    <!-- Left side color bar -->
+    <ImageView
+        android:id="@+id/color_bar"
+        android:layout_width="4dip"
+        android:layout_height="fill_parent"
+    />
+
+    <!-- The content -->
+    <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical"
+    >
+
+        <!-- Account info header -->
+        <RelativeLayout android:id="@+id/header"
+            android:layout_height="64dip"
+            android:layout_width="fill_parent"
+        >
+
+            <ImageView android:id="@+id/header_color_bar"
+                android:layout_width="fill_parent"
+                android:layout_height="2dip"
+                android:layout_marginBottom="5dip"
+            />
+
+            <ImageView android:id="@+id/header_icon"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="7dip"
+                android:layout_marginRight="7dip"
+                android:layout_centerVertical="true"
+                android:layout_below="@id/header_color_bar"
+            />
+
+            <TextView android:id="@+id/header_account_type"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toRightOf="@+id/header_icon"
+                android:layout_alignTop="@id/header_icon"
+                android:layout_marginTop="-4dip"
+
+                android:textSize="24sp"
+                android:textColor="?android:attr/textColorPrimary"
+                android:singleLine="true"
+            />
+
+            <TextView android:id="@+id/header_account_name"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toRightOf="@+id/header_icon"
+                android:layout_alignBottom="@+id/header_icon"
+                android:layout_marginBottom="2dip"
+
+                android:textAppearance="?android:attr/textAppearanceSmall"
+                android:textColor="?android:attr/textColorPrimary"
+                android:singleLine="true"
+            />
+
+            <View
+                android:layout_width="fill_parent"
+                android:layout_height="1px"
+                android:layout_alignParentBottom="true"
+
+                android:background="?android:attr/listDivider"
+            />
+
+        </RelativeLayout>
+
+        <FrameLayout
+            android:id="@+id/stub_photo"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="12dip"
+            android:paddingTop="10dip">
+
+            <include
+                android:id="@+id/edit_photo"
+                layout="@layout/item_photo_editor" />
+
+        </FrameLayout>
+
+        <TextView android:id="@+id/read_only_name"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="6dip"
+            android:layout_marginBottom="6dip"
+            android:layout_marginLeft="10dip"
+
+            android:textAppearance="?android:attr/textAppearanceLarge"
+        />
+
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1px"
+            android:background="?android:attr/listDivider"
+        />
+
+        <TextView
+            android:id="@+id/read_only_warning"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="13dip"
+            android:layout_marginBottom="13dip"
+            android:layout_marginLeft="13dip"
+
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorPrimary"
+            android:drawableLeft="@android:drawable/ic_dialog_alert"
+            android:drawablePadding="10dip"
+        />
+
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1px"
+            android:background="?android:attr/listDivider"
+        />
+
+        <LinearLayout android:id="@+id/sect_general"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+        />
+    </LinearLayout>
+
+</com.android.contacts.ui.widget.ReadOnlyContactEditorView>
diff --git a/res/layout/item_read_only_field.xml b/res/layout/item_read_only_field.xml
new file mode 100644 (file)
index 0000000..a0b20c4
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="?android:attr/listPreferredItemHeight"
+
+    android:orientation="vertical"
+>
+
+    <TextView android:id="@+id/label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="10dip"
+        android:layout_marginTop="2dip"
+
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:singleLine="true"
+    />
+
+    <TextView android:id="@+id/data"
+        android:layout_width="wrap_content"
+        android:layout_height="0px"
+        android:layout_weight="1"
+        android:layout_marginLeft="10dip"
+        android:layout_marginBottom="4dip"
+
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:singleLine="true"
+    />
+
+    <View
+        android:layout_width="fill_parent"
+        android:layout_height="1px"
+
+        android:background="?android:attr/listDivider"
+    />
+
+</LinearLayout>
\ No newline at end of file
index 5621ef2..94b8020 100644 (file)
@@ -29,7 +29,7 @@ import com.android.contacts.model.Sources;
 import com.android.contacts.model.ContactsSource.EditType;
 import com.android.contacts.model.Editor.EditorListener;
 import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.ui.widget.ContactEditorView;
+import com.android.contacts.ui.widget.BaseContactEditorView;
 import com.android.contacts.ui.widget.PhotoEditorView;
 import com.android.contacts.util.EmptyService;
 import com.android.contacts.util.WeakAsyncTask;
@@ -83,7 +83,6 @@ import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.List;
 
 /**
  * Activity for editing or inserting a contact.
@@ -345,8 +344,14 @@ public final class EditContactActivity extends Activity
                     ContactsSource.LEVEL_CONSTRAINTS);
             final long rawContactId = values.getAsLong(RawContacts._ID);
 
-            ContactEditorView editor = (ContactEditorView) inflater.inflate(
-                    R.layout.item_contact_editor, mContent, false);
+            BaseContactEditorView editor;
+            if (!source.readOnly) {
+                editor = (BaseContactEditorView) inflater.inflate(R.layout.item_contact_editor,
+                        mContent, false);
+            } else {
+                editor = (BaseContactEditorView) inflater.inflate(
+                        R.layout.item_read_only_contact_editor, mContent, false);
+            }
             PhotoEditorView photoEditor = editor.getPhotoEditor();
             photoEditor.setEditorListener(new PhotoListener(rawContactId, source.readOnly,
                     photoEditor));
@@ -437,8 +442,8 @@ public final class EditContactActivity extends Activity
                     int count = mContent.getChildCount();
                     for (int i = 0; i < count; i++) {
                         View childView = mContent.getChildAt(i);
-                        if (childView instanceof ContactEditorView) {
-                            ContactEditorView editor = (ContactEditorView) childView;
+                        if (childView instanceof BaseContactEditorView) {
+                            BaseContactEditorView editor = (BaseContactEditorView) childView;
                             PhotoEditorView photoEditor = editor.getPhotoEditor();
                             if (!photoEditor.equals(mEditor)) {
                                 photoEditor.setSuperPrimary(false);
@@ -486,11 +491,11 @@ public final class EditContactActivity extends Activity
 
         switch (requestCode) {
             case PHOTO_PICKED_WITH_DATA: {
-                ContactEditorView requestingEditor = null;
+                BaseContactEditorView requestingEditor = null;
                 for (int i = 0; i < mContent.getChildCount(); i++) {
                     View childView = mContent.getChildAt(i);
-                    if (childView instanceof ContactEditorView) {
-                        ContactEditorView editor = (ContactEditorView) childView;
+                    if (childView instanceof BaseContactEditorView) {
+                        BaseContactEditorView editor = (BaseContactEditorView) childView;
                         if (editor.getRawContactId() == mRawContactIdRequestingPhoto) {
                             requestingEditor = editor;
                             break;
diff --git a/src/com/android/contacts/ui/widget/BaseContactEditorView.java b/src/com/android/contacts/ui/widget/BaseContactEditorView.java
new file mode 100644 (file)
index 0000000..189e2d5
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.ui.widget;
+
+import com.android.contacts.model.ContactsSource;
+import com.android.contacts.model.EntityDelta;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.model.ContactsSource.EditType;
+import com.android.contacts.model.Editor.EditorListener;
+import com.android.contacts.model.EntityDelta.ValuesDelta;
+
+import android.content.Context;
+import android.content.Entity;
+import android.graphics.Bitmap;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.LinearLayout;
+
+/**
+ * Base view that provides common code for the editor interaction for a specific
+ * RawContact represented through an {@link EntityDelta}. Callers can
+ * reuse this view and quickly rebuild its contents through
+ * {@link #setState(EntityDelta, ContactsSource)}.
+ * <p>
+ * Internal updates are performed against {@link ValuesDelta} so that the
+ * source {@link Entity} can be swapped out. Any state-based changes, such as
+ * adding {@link Data} rows or changing {@link EditType}, are performed through
+ * {@link EntityModifier} to ensure that {@link ContactsSource} are enforced.
+ */
+public abstract class BaseContactEditorView extends LinearLayout {
+    protected LayoutInflater mInflater;
+
+    protected PhotoEditorView mPhoto;
+    protected boolean mHasPhotoEditor = false;
+
+    public BaseContactEditorView(Context context) {
+        super(context);
+    }
+
+    public BaseContactEditorView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Assign the given {@link Bitmap} to the internal {@link PhotoEditorView}
+     * for the {@link EntityDelta} currently being edited.
+     */
+    public void setPhotoBitmap(Bitmap bitmap) {
+        mPhoto.setPhotoBitmap(bitmap);
+    }
+
+    /**
+     * Return true if the current {@link RawContacts} supports {@link Photo},
+     * which means that {@link PhotoEditorView} is enabled.
+     */
+    public boolean hasPhotoEditor() {
+        return mHasPhotoEditor;
+    }
+
+    /**
+     * Return true if internal {@link PhotoEditorView} has a {@link Photo} set.
+     */
+    public boolean hasSetPhoto() {
+        return mPhoto.hasSetPhoto();
+    }
+
+    public PhotoEditorView getPhotoEditor() {
+        return mPhoto;
+    }
+
+    /**
+     * @return the RawContact ID that this editor is editing.
+     */
+    public abstract long getRawContactId();
+
+    /**
+     * Set the internal state for this view, given a current
+     * {@link EntityDelta} state and the {@link ContactsSource} that
+     * apply to that state.
+     */
+    public abstract void setState(EntityDelta state, ContactsSource source);
+
+    /**
+     * Sets the {@link EditorListener} on the name field
+     */
+    public abstract void setNameEditorListener(EditorListener listener);
+}
index 53d1faf..d266edf 100644 (file)
@@ -28,7 +28,6 @@ import com.android.contacts.model.EntityDelta.ValuesDelta;
 import android.content.Context;
 import android.content.Entity;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
@@ -42,7 +41,6 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.TextView;
 
 /**
@@ -56,18 +54,13 @@ import android.widget.TextView;
  * adding {@link Data} rows or changing {@link EditType}, are performed through
  * {@link EntityModifier} to ensure that {@link ContactsSource} are enforced.
  */
-public class ContactEditorView extends LinearLayout implements OnClickListener {
-    private LayoutInflater mInflater;
-
+public class ContactEditorView extends BaseContactEditorView implements OnClickListener {
     private TextView mReadOnly;
     private TextView mReadOnlyName;
 
-    private PhotoEditorView mPhoto;
     private View mPhotoStub;
     private GenericEditorView mName;
 
-    private boolean mHasPhotoEditor = false;
-
     private ViewGroup mGeneral;
     private ViewGroup mSecondary;
     private boolean mSecondaryVisible;
@@ -133,33 +126,6 @@ public class ContactEditorView extends LinearLayout implements OnClickListener {
         this.setSecondaryVisible(false);
     }
 
-    /**
-     * Assign the given {@link Bitmap} to the internal {@link PhotoEditorView}
-     * for the {@link EntityDelta} currently being edited.
-     */
-    public void setPhotoBitmap(Bitmap bitmap) {
-        mPhoto.setPhotoBitmap(bitmap);
-    }
-
-    /**
-     * Return true if the current {@link RawContacts} supports {@link Photo},
-     * which means that {@link PhotoEditorView} is enabled.
-     */
-    public boolean hasPhotoEditor() {
-        return mHasPhotoEditor;
-    }
-
-    /**
-     * Return true if internal {@link PhotoEditorView} has a {@link Photo} set.
-     */
-    public boolean hasSetPhoto() {
-        return mPhoto.hasSetPhoto();
-    }
-
-    public PhotoEditorView getPhotoEditor() {
-        return mPhoto;
-    }
-
     /** {@inheritDoc} */
     public void onClick(View v) {
         // Toggle visibility of secondary kinds
@@ -182,6 +148,7 @@ public class ContactEditorView extends LinearLayout implements OnClickListener {
      * {@link EntityDelta} state and the {@link ContactsSource} that
      * apply to that state.
      */
+    @Override
     public void setState(EntityDelta state, ContactsSource source) {
         // Remove any existing sections
         mGeneral.removeAllViews();
@@ -287,10 +254,12 @@ public class ContactEditorView extends LinearLayout implements OnClickListener {
     /**
      * Sets the {@link EditorListener} on the name field
      */
+    @Override
     public void setNameEditorListener(EditorListener listener) {
         mName.setEditorListener(listener);
     }
 
+    @Override
     public long getRawContactId() {
         return mRawContactId;
     }
diff --git a/src/com/android/contacts/ui/widget/ReadOnlyContactEditorView.java b/src/com/android/contacts/ui/widget/ReadOnlyContactEditorView.java
new file mode 100644 (file)
index 0000000..745b061
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.ui.widget;
+
+import com.android.contacts.R;
+import com.android.contacts.model.ContactsSource;
+import com.android.contacts.model.EntityDelta;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.model.ContactsSource.DataKind;
+import com.android.contacts.model.ContactsSource.EditType;
+import com.android.contacts.model.Editor.EditorListener;
+import com.android.contacts.model.EntityDelta.ValuesDelta;
+
+import android.content.Context;
+import android.content.Entity;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Custom view that displays read-only contacts in the edit screen.
+ */
+class ReadOnlyContactEditorView extends BaseContactEditorView {
+
+    private View mPhotoStub;
+    private TextView mName;
+    private TextView mReadOnlyWarning;
+    private ViewGroup mGeneral;
+
+    private View mHeaderColorBar;
+    private View mSideBar;
+    private ImageView mHeaderIcon;
+    private TextView mHeaderAccountType;
+    private TextView mHeaderAccountName;
+
+    private long mRawContactId = -1;
+
+    public ReadOnlyContactEditorView(Context context) {
+        super(context);
+    }
+
+    public ReadOnlyContactEditorView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        mInflater = (LayoutInflater)getContext().getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+
+        mPhoto = (PhotoEditorView)findViewById(R.id.edit_photo);
+        mPhotoStub = findViewById(R.id.stub_photo);
+
+        mName = (TextView) findViewById(R.id.read_only_name);
+        mReadOnlyWarning = (TextView) findViewById(R.id.read_only_warning);
+        mGeneral = (ViewGroup)findViewById(R.id.sect_general);
+
+        mHeaderColorBar = findViewById(R.id.header_color_bar);
+        mSideBar = findViewById(R.id.color_bar);
+        mHeaderIcon = (ImageView) findViewById(R.id.header_icon);
+        mHeaderAccountType = (TextView) findViewById(R.id.header_account_type);
+        mHeaderAccountName = (TextView) findViewById(R.id.header_account_name);
+    }
+
+    /**
+     * Set the internal state for this view, given a current
+     * {@link EntityDelta} state and the {@link ContactsSource} that
+     * apply to that state.
+     *
+     * TODO: make this more generic using data from the source
+     */
+    @Override
+    public void setState(EntityDelta state, ContactsSource source) {
+        // Remove any existing sections
+        mGeneral.removeAllViews();
+
+        // Bail if invalid state or source
+        if (state == null || source == null) return;
+
+        // Make sure we have StructuredName
+        EntityModifier.ensureKindExists(state, source, StructuredName.CONTENT_ITEM_TYPE);
+
+        // Fill in the header info
+        mHeaderColorBar.setBackgroundColor(source.getHeaderColor(mContext));
+        mSideBar.setBackgroundColor(source.getSideBarColor(mContext));
+        ValuesDelta values = state.getValues();
+        String accountName = values.getAsString(RawContacts.ACCOUNT_NAME);
+        CharSequence accountType = source.getDisplayLabel(mContext);
+        if (TextUtils.isEmpty(accountType)) {
+            accountType = mContext.getString(R.string.account_phone);
+        }
+        if (!TextUtils.isEmpty(accountName)) {
+            mHeaderAccountName.setText(
+                    mContext.getString(R.string.from_account_format, accountName));
+        }
+        mHeaderAccountType.setText(mContext.getString(R.string.account_type_format, accountType));
+        mHeaderIcon.setImageDrawable(source.getDisplayIcon(mContext));
+
+        mRawContactId = values.getAsLong(RawContacts._ID);
+
+        ValuesDelta primary;
+
+        // Photo
+        DataKind kind = source.getKindForMimetype(Photo.CONTENT_ITEM_TYPE);
+        if (kind != null) {
+            EntityModifier.ensureKindExists(state, source, Photo.CONTENT_ITEM_TYPE);
+            mHasPhotoEditor = (source.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null);
+            primary = state.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
+            mPhoto.setValues(kind, primary, state, source.readOnly);
+            if (!mHasPhotoEditor || !mPhoto.hasSetPhoto()) {
+                mPhotoStub.setVisibility(View.GONE);
+            } else {
+                mPhotoStub.setVisibility(View.VISIBLE);
+            }
+        } else {
+            mPhotoStub.setVisibility(View.VISIBLE);
+        }
+
+        // Name
+        primary = state.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
+        mName.setText(primary.getAsString(StructuredName.DISPLAY_NAME));
+
+        // Read only warning
+        mReadOnlyWarning.setText(mContext.getString(R.string.contact_read_only, accountType));
+
+        // Phones
+        ArrayList<ValuesDelta> phones = state.getMimeEntries(Phone.CONTENT_ITEM_TYPE);
+        if (phones != null) {
+            for (ValuesDelta phone : phones) {
+                View field = mInflater.inflate(
+                        R.layout.item_read_only_field, mGeneral, false);
+                TextView v;
+                v = (TextView) field.findViewById(R.id.label);
+                v.setText(mContext.getText(R.string.phoneLabelsGroup));
+                v = (TextView) field.findViewById(R.id.data);
+                v.setText(PhoneNumberUtils.formatNumber(phone.getAsString(Phone.NUMBER)));
+                mGeneral.addView(field);
+            }
+        }
+
+        // Emails
+        ArrayList<ValuesDelta> emails = state.getMimeEntries(Email.CONTENT_ITEM_TYPE);
+        if (emails != null) {
+            for (ValuesDelta email : emails) {
+                View field = mInflater.inflate(
+                        R.layout.item_read_only_field, mGeneral, false);
+                TextView v;
+                v = (TextView) field.findViewById(R.id.label);
+                v.setText(mContext.getText(R.string.emailLabelsGroup));
+                v = (TextView) field.findViewById(R.id.data);
+                v.setText(email.getAsString(Email.DATA));
+                mGeneral.addView(field);
+            }
+        }
+
+        // Hide mGeneral if it's empty
+        if (mGeneral.getChildCount() > 0) {
+            mGeneral.setVisibility(View.VISIBLE);
+        } else {
+            mGeneral.setVisibility(View.GONE);
+        }
+    }
+
+    /**
+     * Sets the {@link EditorListener} on the name field
+     */
+    @Override
+    public void setNameEditorListener(EditorListener listener) {
+        // do nothing
+    }
+
+    @Override
+    public long getRawContactId() {
+        return mRawContactId;
+    }
+}