Merge "Put OK button on the right"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5a645a0..9d5381a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -40,9 +40,6 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
- <!-- TODO: get rid of READ_WRITE_OWN_VOICEMAIL permission when voicemail provider has been
- modified to support ADD_VOICEMAIL -->
- <uses-permission android:name="com.android.voicemail.permission.READ_WRITE_OWN_VOICEMAIL" />
<uses-permission android:name="com.android.voicemail.permission.READ_WRITE_ALL_VOICEMAIL" />
<!-- allow broadcasting secret code intents that reboot the phone -->
<uses-permission android:name="android.permission.REBOOT" />
@@ -476,7 +473,6 @@
<activity android:name="CallDetailActivity"
android:label="@string/callDetailTitle"
android:theme="@style/CallDetailActivityTheme"
- android:uiOptions="splitActionBarWhenNarrow"
android:screenOrientation="nosensor"
android:icon="@mipmap/ic_launcher_phone"
android:taskAffinity="android.task.contacts.phone"
diff --git a/res/drawable/seek_bar_thumb.xml b/res/drawable/seek_bar_thumb.xml
index 04ba0fa..61884bb 100644
--- a/res/drawable/seek_bar_thumb.xml
+++ b/res/drawable/seek_bar_thumb.xml
@@ -6,8 +6,8 @@
android:shape="oval"
>
<size
- android:width="15dip"
- android:height="15dip"
+ android:width="16dip"
+ android:height="16dip"
/>
<solid
android:color="@color/voicemail_playback_seek_bar_yet_to_play"
diff --git a/res/layout-sw580dp-w1000dp/contact_detail_container.xml b/res/layout-sw580dp-w1000dp/contact_detail_container.xml
index be91296..1d4ea35 100644
--- a/res/layout-sw580dp-w1000dp/contact_detail_container.xml
+++ b/res/layout-sw580dp-w1000dp/contact_detail_container.xml
@@ -16,7 +16,7 @@
<!--
Two-column layout for a contact with social updates. If the contact does not
- have social updates, then the second fragment view will just be hidden.
+ have social updates, then the second fragment container will just be hidden.
-->
<LinearLayout
@@ -26,14 +26,24 @@
android:scrollbars="none"
android:orientation="horizontal">
- <fragment class="com.android.contacts.detail.ContactDetailFragment"
- android:id="@+id/about_fragment"
+ <!--
+ Container for the "About" fragment on the contact card for a contact
+ with social updates. This view ID must match with a view ID in the layout
+ that is used after an orientation change.
+ -->
+ <FrameLayout
+ android:id="@+id/about_fragment_container"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1" />
- <fragment class="com.android.contacts.detail.ContactDetailUpdatesFragment"
- android:id="@+id/updates_fragment"
+ <!--
+ Container for the "Updates" fragment on the contact card for a contact
+ with social updates. This view ID must match with a view ID in the layout
+ that is used after an orientation change.
+ -->
+ <FrameLayout
+ android:id="@+id/updates_fragment_container"
android:layout_width="306dip"
android:layout_height="match_parent" />
diff --git a/res/layout-sw580dp/people_activity.xml b/res/layout-sw580dp/people_activity.xml
index 13adfa9..1d02042 100644
--- a/res/layout-sw580dp/people_activity.xml
+++ b/res/layout-sw580dp/people_activity.xml
@@ -83,6 +83,7 @@
<!-- This layout includes all possible views needed for a contact detail page -->
<include
+ android:id="@+id/contact_detail_container"
layout="@layout/contact_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
diff --git a/res/layout/call_detail.xml b/res/layout/call_detail.xml
index 441cc6c..ece2f64 100644
--- a/res/layout/call_detail.xml
+++ b/res/layout/call_detail.xml
@@ -52,10 +52,17 @@
/>
</view>
<LinearLayout
+ android:id="@+id/blue_separator"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:background="@android:color/holo_blue_light"
+ android:layout_below="@+id/contact_background_sizer"
+ />
+ <LinearLayout
android:id="@+id/voicemail_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/contact_background_sizer"
+ android:layout_below="@id/blue_separator"
>
<!-- The voicemail fragment will be put here. -->
</LinearLayout>
diff --git a/res/layout/contact_detail_container.xml b/res/layout/contact_detail_container.xml
index 3991e5c..9204b62 100644
--- a/res/layout/contact_detail_container.xml
+++ b/res/layout/contact_detail_container.xml
@@ -43,12 +43,7 @@
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
-
- <fragment
- android:id="@+id/contact_detail_fragment"
- class="com.android.contacts.detail.ContactDetailFragment"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_height="wrap_content"
+ android:visibility="gone"/>
</RelativeLayout>
\ No newline at end of file
diff --git a/res/layout/playback_layout.xml b/res/layout/playback_layout.xml
index 020c017..45e7ad9 100644
--- a/res/layout/playback_layout.xml
+++ b/res/layout/playback_layout.xml
@@ -19,75 +19,90 @@
android:layout_alignParentTop="true"
>
<ImageButton
- android:id="@+id/playback_speakerphone"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="5px"
- android:layout_marginTop="4dip"
- android:layout_marginLeft="4dip"
- android:background="@drawable/dialpad_background"
- android:src="@drawable/ic_sound_holo_dark"
- android:layout_weight="1"
- />
- <ImageButton
android:id="@+id/playback_start_stop"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="5px"
- android:layout_marginTop="4dip"
- android:layout_marginLeft="4dip"
+ android:layout_height="58dip"
+ android:layout_marginRight="2dip"
android:background="@drawable/dialpad_background"
android:src="@drawable/ic_hold_pause_holo_dark"
android:layout_weight="1"
/>
+ <ImageButton
+ android:id="@+id/playback_speakerphone"
+ android:layout_width="wrap_content"
+ android:layout_height="58dip"
+ android:layout_marginLeft="2dip"
+ android:background="@drawable/dialpad_background"
+ android:src="@drawable/ic_sound_holo_dark"
+ android:layout_weight="1"
+ />
</LinearLayout>
- <SeekBar
- android:id="@+id/playback_seek"
+ <RelativeLayout
+ android:id="@+id/seek_container"
android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:progressDrawable="@drawable/seekbar_drawable"
- android:thumb="@drawable/seek_bar_thumb"
- android:thumbOffset="0dip"
+ android:layout_height="80dip"
android:background="@drawable/dialpad_background"
- android:paddingLeft="50dip"
- android:paddingRight="50dip"
- android:paddingTop="10dip"
- android:paddingBottom="20dip"
- android:layout_margin="4dip"
- android:progress="20"
- android:max="50"
android:layout_below="@id/buttons_linear_layout"
- />
- <TextView
- android:id="@+id/playback_position_text"
- android:text="@string/voicemail_initial_time"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:paddingBottom="5dip"
- android:layout_alignBottom="@id/playback_seek"
- android:layout_centerHorizontal="true"
- />
- <ImageButton
- android:id="@+id/rate_decrease_button"
- android:src="@drawable/ic_minus_holo_dark"
- android:layout_width="30dip"
- android:layout_height="wrap_content"
- android:background="@android:color/transparent"
- android:paddingTop="10dip"
- android:paddingBottom="15dip"
- android:layout_alignLeft="@id/playback_seek"
- android:layout_alignBottom="@id/playback_seek"
- />
- <ImageButton
- android:id="@+id/rate_increase_button"
- android:src="@drawable/ic_plus_holo_dark"
- android:layout_width="30dip"
- android:layout_height="wrap_content"
- android:background="@android:color/transparent"
- android:paddingTop="10dip"
- android:paddingBottom="15dip"
- android:layout_alignRight="@id/playback_seek"
- android:layout_alignBottom="@id/playback_seek"
- />
+ android:layout_marginTop="4dip"
+ >
+ <!-- SeekBar left-right margin decreased from redlines 72dip by 8dip to account for
+ half thumb width (thumb is 16dip).
+ Vertically, SeekBar and rate buttons should be below centre, position achieved by
+ making them centred but giving a difference between top and bottom padding,
+ difference is currently 10dip. -->
+ <SeekBar
+ android:id="@+id/playback_seek"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:progressDrawable="@drawable/seekbar_drawable"
+ android:thumb="@drawable/seek_bar_thumb"
+ android:thumbOffset="8dip"
+ android:progress="20"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip"
+ android:paddingTop="30dip"
+ android:paddingBottom="20dip"
+ android:layout_marginRight="64dip"
+ android:layout_marginLeft="64dip"
+ android:max="50"
+ android:layout_centerVertical="true"
+ />
+ <TextView
+ android:id="@+id/playback_position_text"
+ android:text="@string/voicemail_initial_time"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:textSize="14sp"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:layout_marginTop="10dip"
+ />
+ <ImageButton
+ android:id="@+id/rate_decrease_button"
+ android:src="@drawable/ic_minus_holo_dark"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@android:color/transparent"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingBottom="16dip"
+ android:paddingTop="26dip"
+ android:layout_alignParentLeft="true"
+ android:layout_centerVertical="true"
+ />
+ <ImageButton
+ android:id="@+id/rate_increase_button"
+ android:src="@drawable/ic_plus_holo_dark"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@android:color/transparent"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingBottom="16dip"
+ android:paddingTop="26dip"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ />
+ </RelativeLayout>
</RelativeLayout>
</LinearLayout>
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index 3dffd71..d888dbe 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -75,8 +75,6 @@
private static final String KEY_CONTACT_HAS_UPDATES = "contactHasUpdates";
private static final String KEY_CURRENT_PAGE_INDEX = "currentPageIndex";
- private static final String KEY_DETAIL_FRAGMENT_TAG = "detailFragTag";
- private static final String KEY_UPDATES_FRAGMENT_TAG = "updatesFragTag";
public static final int FRAGMENT_COUNT = 2;
@@ -273,11 +271,6 @@
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_CONTACT_HAS_UPDATES, mContactHasUpdates);
outState.putInt(KEY_CURRENT_PAGE_INDEX, getCurrentPage());
- if (mViewPager != null) {
- outState.putString(KEY_DETAIL_FRAGMENT_TAG, mDetailFragment.getTag());
- outState.putString(KEY_UPDATES_FRAGMENT_TAG, mUpdatesFragment.getTag());
- return;
- }
}
private final ContactLoaderFragmentListener mLoaderFragmentListener =
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 48fd49d..282e0b3 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -122,8 +122,6 @@
private ContactDetailFragment mContactDetailFragment;
private ContactDetailUpdatesFragment mContactDetailUpdatesFragment;
- private final ContactDetailFragmentListener mContactDetailFragmentListener =
- new ContactDetailFragmentListener();
private ContactLoaderFragment mContactDetailLoaderFragment;
private final ContactDetailLoaderFragmentListener mContactDetailLoaderFragmentListener =
@@ -226,7 +224,6 @@
public void onAttachFragment(Fragment fragment) {
if (fragment instanceof ContactDetailFragment) {
mContactDetailFragment = (ContactDetailFragment) fragment;
- mContactDetailFragment.setListener(mContactDetailFragmentListener);
} else if (fragment instanceof ContactDetailUpdatesFragment) {
mContactDetailUpdatesFragment = (ContactDetailUpdatesFragment) fragment;
} else if (fragment instanceof ContactsUnavailableFragment) {
@@ -379,21 +376,21 @@
mContactDetailLoaderFragment = getFragment(R.id.contact_detail_loader_fragment);
mContactDetailLoaderFragment.setListener(mContactDetailLoaderFragmentListener);
+ mContactDetailLoaderFragment.setRetainInstance(true);
mGroupDetailFragment = getFragment(R.id.group_detail_fragment);
mGroupDetailFragment.setListener(mGroupDetailFragmentListener);
mGroupDetailFragment.setQuickContact(true);
- transaction.hide(mContactDetailFragment);
+ if (mContactDetailFragment != null) {
+ transaction.hide(mContactDetailFragment);
+ }
transaction.hide(mGroupDetailFragment);
// Configure contact details
- ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
- ContactDetailTabCarousel tabCarousel = (ContactDetailTabCarousel)
- findViewById(R.id.tab_carousel);
- mContactDetailLayoutController = new ContactDetailLayoutController(
- getFragmentManager(), viewPager, tabCarousel,
- mContactDetailFragmentListener);
+ mContactDetailLayoutController = new ContactDetailLayoutController(this, savedState,
+ getFragmentManager(), findViewById(R.id.contact_detail_container),
+ new ContactDetailFragmentListener());
}
transaction.commit();
fragmentManager.executePendingTransactions();
@@ -1066,13 +1063,6 @@
if (isFinishing()) {
return;
}
- if (!mContactDetailLayoutController.isInitialized()) {
- mContactDetailLayoutController.setContactDetailFragment(
- mContactDetailFragment);
- mContactDetailLayoutController.setContactDetailUpdatesFragment(
- mContactDetailUpdatesFragment);
- mContactDetailLayoutController.initialize();
- }
mContactDetailLayoutController.setContactData(result);
}
});
@@ -1570,14 +1560,6 @@
}
@Override
- protected void onRestoreInstanceState(Bundle inState) {
- super.onRestoreInstanceState(inState);
- if (mContactDetailLayoutController != null) {
- mContactDetailLayoutController.onRestoreInstanceState(inState);
- }
- }
-
- @Override
public DialogManager getDialogManager() {
return mDialogManager;
}
diff --git a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
index eb1d1f0..561d44e 100644
--- a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
+++ b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
@@ -66,7 +66,6 @@
private static final float MAX_ALPHA = 0.5f;
private final Handler mHandler = new Handler();
- private boolean mAttachedToWindow;
public ContactDetailFragmentCarousel(Context context) {
this(context, null);
@@ -105,7 +104,8 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- if (mAttachedToWindow && mAboutFragment != null && mUpdatesFragment != null) {
+ if (isAttachedToWindow() && mAboutFragment != null &&
+ mUpdatesFragment != null) {
snapToEdge();
}
}
@@ -116,7 +116,7 @@
public void setCurrentPage(int pageIndex) {
if (mCurrentPage != pageIndex) {
mCurrentPage = pageIndex;
- if (mAttachedToWindow && mAboutFragment != null && mUpdatesFragment != null) {
+ if (isAttachedToWindow() && mAboutFragment != null && mUpdatesFragment != null) {
snapToEdge();
}
}
@@ -223,15 +223,7 @@
return false;
}
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mAttachedToWindow = true;
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mAttachedToWindow = false;
+ private boolean isAttachedToWindow() {
+ return getWindowToken() != null;
}
}
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index 9b56dde..3fc4c31 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -17,16 +17,18 @@
package com.android.contacts.detail;
import com.android.contacts.ContactLoader;
+import com.android.contacts.R;
import com.android.contacts.activities.PeopleActivity.ContactDetailFragmentListener;
-import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
+import android.content.Context;
import android.os.Bundle;
-import android.support.v13.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
@@ -37,94 +39,145 @@
public static final int FRAGMENT_COUNT = 2;
- private static final String KEY_DETAIL_FRAGMENT_TAG = "detailFragTag";
- private static final String KEY_UPDATES_FRAGMENT_TAG = "updatesFragTag";
-
- private String mDetailFragmentTag;
- private String mUpdatesFragmentTag;
+ private static final String KEY_CONTACT_HAS_UPDATES = "contactHasUpdates";
private enum LayoutMode {
TWO_COLUMN, VIEW_PAGER_AND_CAROUSEL,
}
+ private final LayoutInflater mLayoutInflater;
private final FragmentManager mFragmentManager;
- private ContactDetailFragment mContactDetailFragment;
- private ContactDetailUpdatesFragment mContactDetailUpdatesFragment;
+ private ContactDetailFragment mDetailFragment;
+ private ContactDetailUpdatesFragment mUpdatesFragment;
+
+ private View mDetailFragmentView;
+ private View mUpdatesFragmentView;
private final ViewPager mViewPager;
private final ContactDetailTabCarousel mTabCarousel;
- private ContactDetailFragment mPagerContactDetailFragment;
- private ContactDetailUpdatesFragment mPagerContactDetailUpdatesFragment;
+ private ContactDetailViewPagerAdapter mViewPagerAdapter;
private ContactDetailFragmentListener mContactDetailFragmentListener;
private ContactLoader.Result mContactData;
- private boolean mIsInitialized;
+ private boolean mContactHasUpdates;
private LayoutMode mLayoutMode;
- public ContactDetailLayoutController(FragmentManager fragmentManager, ViewPager viewPager,
- ContactDetailTabCarousel tabCarousel, ContactDetailFragmentListener
+ public ContactDetailLayoutController(Context context, Bundle savedState,
+ FragmentManager fragmentManager, View viewContainer, ContactDetailFragmentListener
contactDetailFragmentListener) {
+
if (fragmentManager == null) {
throw new IllegalStateException("Cannot initialize a ContactDetailLayoutController "
+ "without a non-null FragmentManager");
}
+ mLayoutInflater = (LayoutInflater) context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
mFragmentManager = fragmentManager;
- mViewPager = viewPager;
- mTabCarousel = tabCarousel;
mContactDetailFragmentListener = contactDetailFragmentListener;
- // Determine the layout based on whether the {@link ViewPager} is null or not. If the
+ // Retrieve views in case this is view pager and carousel mode
+ mViewPager = (ViewPager) viewContainer.findViewById(R.id.pager);
+ mTabCarousel = (ContactDetailTabCarousel) viewContainer.findViewById(R.id.tab_carousel);
+
+ // Retrieve views in case this is 2-column layout mode
+ mDetailFragmentView = viewContainer.findViewById(R.id.about_fragment_container);
+ mUpdatesFragmentView = viewContainer.findViewById(R.id.updates_fragment_container);
+
+ // Determine the layout mode based on whether the {@link ViewPager} is null or not. If the
// {@link ViewPager} is null, then this is a wide screen and the content can be displayed
// in 2 columns side by side. If the {@link ViewPager} is non-null, then this is a narrow
// screen and the user will need to swipe to see all the data.
mLayoutMode = (mViewPager == null) ? LayoutMode.TWO_COLUMN :
LayoutMode.VIEW_PAGER_AND_CAROUSEL;
+ initialize(savedState);
}
- public boolean isInitialized() {
- return mIsInitialized;
- }
+ private void initialize(Bundle savedState) {
+ boolean fragmentsAddedToFragmentManager = true;
+ mDetailFragment = (ContactDetailFragment) mFragmentManager.findFragmentByTag(
+ ContactDetailViewPagerAdapter.ABOUT_FRAGMENT_TAG);
+ mUpdatesFragment = (ContactDetailUpdatesFragment) mFragmentManager.findFragmentByTag(
+ ContactDetailViewPagerAdapter.UPDTES_FRAGMENT_TAG);
- public void initialize() {
- mIsInitialized = true;
- if (mDetailFragmentTag != null || mUpdatesFragmentTag != null) {
- // Manually remove any {@link ViewPager} fragments if there was an orientation change
- ContactDetailFragment oldDetailFragment = (ContactDetailFragment) mFragmentManager.
- findFragmentByTag(mDetailFragmentTag);
- ContactDetailUpdatesFragment oldUpdatesFragment = (ContactDetailUpdatesFragment)
- mFragmentManager.findFragmentByTag(mUpdatesFragmentTag);
+ // If the detail fragment was found in the {@link FragmentManager} then we don't need to add
+ // it again. Otherwise, create the fragments dynamically and remember to add them to the
+ // {@link FragmentManager}.
+ if (mDetailFragment == null) {
+ mDetailFragment = new ContactDetailFragment();
+ mUpdatesFragment = new ContactDetailUpdatesFragment();
+ fragmentsAddedToFragmentManager = false;
+ }
- if (oldDetailFragment != null && oldUpdatesFragment != null) {
- FragmentTransaction ft = mFragmentManager.beginTransaction();
- ft.remove(oldDetailFragment);
- ft.remove(oldUpdatesFragment);
- ft.commitAllowingStateLoss();
+ mDetailFragment.setListener(mContactDetailFragmentListener);
+ mDetailFragment.setVerticalScrollListener(mVerticalScrollListener);
+
+ switch (mLayoutMode) {
+ case VIEW_PAGER_AND_CAROUSEL: {
+ mTabCarousel.setListener(mTabCarouselListener);
+ // Inflate 2 view containers to pass in as children to the {@link ViewPager},
+ // which will in turn be the parents to the mDetailFragment and mUpdatesFragment
+ // since the fragments must have the same parent view IDs in both landscape and
+ // portrait layouts.
+ ViewGroup detailContainer = (ViewGroup) mLayoutInflater.inflate(
+ R.layout.contact_detail_about_fragment_container, mViewPager, false);
+ ViewGroup updatesContainer = (ViewGroup) mLayoutInflater.inflate(
+ R.layout.contact_detail_updates_fragment_container, mViewPager, false);
+
+ mViewPagerAdapter = new ContactDetailViewPagerAdapter();
+ mViewPagerAdapter.setAboutFragmentView(detailContainer);
+ mViewPagerAdapter.setUpdatesFragmentView(updatesContainer);
+
+ mViewPager.addView(detailContainer);
+ mViewPager.addView(updatesContainer);
+ mViewPager.setAdapter(mViewPagerAdapter);
+ mViewPager.setOnPageChangeListener(mOnPageChangeListener);
+
+ FragmentTransaction transaction = mFragmentManager.beginTransaction();
+ if (!fragmentsAddedToFragmentManager) {
+ transaction.add(R.id.about_fragment_container, mDetailFragment,
+ ContactDetailViewPagerAdapter.ABOUT_FRAGMENT_TAG);
+ transaction.add(R.id.updates_fragment_container, mUpdatesFragment,
+ ContactDetailViewPagerAdapter.UPDTES_FRAGMENT_TAG);
+ } else {
+ transaction.show(mDetailFragment);
+ transaction.show(mUpdatesFragment);
+ }
+ transaction.commit();
+ mFragmentManager.executePendingTransactions();
+ break;
+ }
+ case TWO_COLUMN: {
+ if (!fragmentsAddedToFragmentManager) {
+ FragmentTransaction transaction = mFragmentManager.beginTransaction();
+ transaction.add(R.id.about_fragment_container, mDetailFragment,
+ ContactDetailViewPagerAdapter.ABOUT_FRAGMENT_TAG);
+ transaction.add(R.id.updates_fragment_container, mUpdatesFragment,
+ ContactDetailViewPagerAdapter.UPDTES_FRAGMENT_TAG);
+ transaction.commit();
+ mFragmentManager.executePendingTransactions();
+ }
}
}
- if (mViewPager != null) {
- mViewPager.setAdapter(new ViewPagerAdapter(mFragmentManager));
- mViewPager.setOnPageChangeListener(mOnPageChangeListener);
- mTabCarousel.setListener(mTabCarouselListener);
+
+ if (savedState != null) {
+ if (savedState.getBoolean(KEY_CONTACT_HAS_UPDATES)) {
+ showContactWithUpdates();
+ } else {
+ showContactWithoutUpdates();
+ }
}
}
- public void setContactDetailFragment(ContactDetailFragment contactDetailFragment) {
- mContactDetailFragment = contactDetailFragment;
- }
-
- public void setContactDetailUpdatesFragment(ContactDetailUpdatesFragment updatesFragment) {
- mContactDetailUpdatesFragment = updatesFragment;
- }
-
public void setContactData(ContactLoader.Result data) {
mContactData = data;
- if (!data.getStreamItems().isEmpty()) {
+ mContactHasUpdates = !data.getStreamItems().isEmpty();
+ if (mContactHasUpdates) {
showContactWithUpdates();
} else {
showContactWithoutUpdates();
@@ -132,117 +185,59 @@
}
private void showContactWithUpdates() {
- FragmentTransaction ft = mFragmentManager.beginTransaction();
-
switch (mLayoutMode) {
case TWO_COLUMN: {
// Set the contact data (hide the static photo because the photo will already be in
// the header that scrolls with contact details).
- mContactDetailFragment.setShowStaticPhoto(false);
- mContactDetailFragment.setData(mContactData.getLookupUri(), mContactData);
- mContactDetailUpdatesFragment.setData(mContactData.getLookupUri(), mContactData);
-
- // Update fragment visibility
- ft.show(mContactDetailUpdatesFragment);
+ mDetailFragment.setShowStaticPhoto(false);
+ // Show the updates fragment
+ mUpdatesFragmentView.setVisibility(View.VISIBLE);
break;
}
case VIEW_PAGER_AND_CAROUSEL: {
- // Set the contact data
+ // Update and show the tab carousel
mTabCarousel.loadData(mContactData);
- mPagerContactDetailFragment.setData(mContactData.getLookupUri(), mContactData);
- mPagerContactDetailUpdatesFragment.setData(mContactData.getLookupUri(),
- mContactData);
-
- // Update fragment and view visibility
- mViewPager.setVisibility(View.VISIBLE);
mTabCarousel.setVisibility(View.VISIBLE);
- ft.hide(mContactDetailFragment);
+ // Update ViewPager so that it has the max # of tabs (to show updates)
+ mViewPagerAdapter.setFragmentViewCount(FRAGMENT_COUNT);
break;
}
default:
throw new IllegalStateException("Invalid LayoutMode " + mLayoutMode);
}
- // If the activity has already saved its state, then allow this fragment
- // transaction to be dropped because there's nothing else we can do to update the UI.
- // The fact that the contact URI has already been saved by the activity means we can
- // restore this later.
- ft.commitAllowingStateLoss();
+ if (mContactData != null) {
+ mDetailFragment.setData(mContactData.getLookupUri(), mContactData);
+ mUpdatesFragment.setData(mContactData.getLookupUri(), mContactData);
+ }
}
private void showContactWithoutUpdates() {
- FragmentTransaction ft = mFragmentManager.beginTransaction();
-
switch (mLayoutMode) {
case TWO_COLUMN:
- mContactDetailFragment.setShowStaticPhoto(true);
- mContactDetailFragment.setData(mContactData.getLookupUri(), mContactData);
- ft.hide(mContactDetailUpdatesFragment);
+ // Show the static photo which is next to the list of scrolling contact details
+ mDetailFragment.setShowStaticPhoto(true);
+ // Hide the updates fragment
+ mUpdatesFragmentView.setVisibility(View.GONE);
break;
case VIEW_PAGER_AND_CAROUSEL:
- mContactDetailFragment.setData(mContactData.getLookupUri(), mContactData);
- ft.show(mContactDetailFragment);
- mViewPager.setVisibility(View.GONE);
+ // Hide the tab carousel
mTabCarousel.setVisibility(View.GONE);
+ // Update ViewPager so that it only has 1 tab and switch to the first indexed tab
+ mViewPagerAdapter.setFragmentViewCount(1);
+ mViewPager.setCurrentItem(0);
break;
default:
throw new IllegalStateException("Invalid LayoutMode " + mLayoutMode);
}
- // If the activity has already saved its state, then allow this fragment
- // transaction to be dropped because there's nothing else we can do to update the UI.
- // The fact that the contact URI has already been saved by the activity means we can
- // restore this later.
- ft.commitAllowingStateLoss();
+ if (mContactData != null) {
+ mDetailFragment.setData(mContactData.getLookupUri(), mContactData);
+ }
}
public void onSaveInstanceState(Bundle outState) {
- if (mPagerContactDetailFragment != null) {
- outState.putString(KEY_DETAIL_FRAGMENT_TAG,
- mPagerContactDetailFragment.getTag());
- outState.putString(KEY_UPDATES_FRAGMENT_TAG,
- mPagerContactDetailUpdatesFragment.getTag());
- }
- }
-
- public void onRestoreInstanceState(Bundle savedState) {
- mDetailFragmentTag = savedState.getString(KEY_DETAIL_FRAGMENT_TAG);
- mUpdatesFragmentTag = savedState.getString(KEY_UPDATES_FRAGMENT_TAG);
- }
-
- public class ViewPagerAdapter extends FragmentPagerAdapter{
-
- public ViewPagerAdapter(FragmentManager fm) {
- super(fm);
- }
-
- @Override
- public Fragment getItem(int position) {
- switch (position) {
- case 0:
- mPagerContactDetailFragment = new ContactDetailFragment();
- if (mContactData != null) {
- mPagerContactDetailFragment.setData(mContactData.getLookupUri(),
- mContactData);
- }
- mPagerContactDetailFragment.setListener(mContactDetailFragmentListener);
- mPagerContactDetailFragment.setVerticalScrollListener(mVerticalScrollListener);
- return mPagerContactDetailFragment;
- case 1:
- mPagerContactDetailUpdatesFragment = new ContactDetailUpdatesFragment();
- if (mContactData != null) {
- mPagerContactDetailUpdatesFragment.setData(mContactData.getLookupUri(),
- mContactData);
- }
- return mPagerContactDetailUpdatesFragment;
- }
- throw new IllegalStateException("No fragment at position " + position);
- }
-
- @Override
- public int getCount() {
- return FRAGMENT_COUNT;
- }
+ outState.putBoolean(KEY_CONTACT_HAS_UPDATES, mContactHasUpdates);
}
private OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener() {
diff --git a/src/com/android/contacts/detail/ContactDetailViewPagerAdapter.java b/src/com/android/contacts/detail/ContactDetailViewPagerAdapter.java
index 39544df..d7f2743 100644
--- a/src/com/android/contacts/detail/ContactDetailViewPagerAdapter.java
+++ b/src/com/android/contacts/detail/ContactDetailViewPagerAdapter.java
@@ -29,11 +29,13 @@
public static final String ABOUT_FRAGMENT_TAG = "view-pager-about-fragment";
public static final String UPDTES_FRAGMENT_TAG = "view-pager-updates-fragment";
- private static final int FRAGMENT_COUNT = 2;
-
private static final int INDEX_ABOUT_FRAGMENT = 0;
private static final int INDEX_UPDATES_FRAGMENT = 1;
+ private static final int MAX_FRAGMENT_VIEW_COUNT = 2;
+
+ private int mFragmentViewCount = MAX_FRAGMENT_VIEW_COUNT;
+
private ViewGroup mAboutFragmentView;
private ViewGroup mUpdatesFragmentView;
@@ -48,9 +50,18 @@
mUpdatesFragmentView = view;
}
+ public void setFragmentViewCount(int viewCount) {
+ if (viewCount < 0 || viewCount > MAX_FRAGMENT_VIEW_COUNT) {
+ throw new IllegalStateException("The view count in the ViewPager adapter must not be"
+ + "less than 0 or exceed " + MAX_FRAGMENT_VIEW_COUNT);
+ }
+ mFragmentViewCount = viewCount;
+ notifyDataSetChanged();
+ }
+
@Override
public int getCount() {
- return FRAGMENT_COUNT;
+ return mFragmentViewCount;
}
/** Gets called when the number of items changes. */