ConversationPagerController.java revision f58e4c3c942033fce12b5f75f9e4d9e708c9ea6a
1632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang/* 2632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * Copyright (C) 2012 Google Inc. 3632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * Licensed to The Android Open Source Project. 4632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * 5632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * Licensed under the Apache License, Version 2.0 (the "License"); 6632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * you may not use this file except in compliance with the License. 7632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * You may obtain a copy of the License at 8632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * 9632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * http://www.apache.org/licenses/LICENSE-2.0 10632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * 11632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * Unless required by applicable law or agreed to in writing, software 12632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * distributed under the License is distributed on an "AS IS" BASIS, 13632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * See the License for the specific language governing permissions and 15632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * limitations under the License. 16632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang */ 17632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 18632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangpackage com.android.mail.browse; 19632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 20632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport android.app.FragmentManager; 21d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huangimport android.content.Context; 22d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huangimport android.content.res.TypedArray; 239d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huangimport android.database.DataSetObservable; 249d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huangimport android.database.DataSetObserver; 25d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huangimport android.graphics.drawable.Drawable; 26632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport android.support.v4.view.ViewPager; 2722ecc77345c86e0515c1f3c3447502c25c8c53d2Andy Huangimport android.view.View; 28632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 29632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport com.android.mail.R; 303213ffdac10adb0905cb5440c725345979d4eacfAndrew Sappersteinimport com.android.mail.graphics.PageMarginDrawable; 31632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport com.android.mail.providers.Account; 32632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport com.android.mail.providers.Conversation; 33632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport com.android.mail.providers.Folder; 34632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport com.android.mail.ui.AbstractActivityController; 355895f7b0e5fa921f6d46bbaf6d8c7b1a8ebc7804Andy Huangimport com.android.mail.ui.ActivityController; 36632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport com.android.mail.ui.RestrictedActivity; 37632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huangimport com.android.mail.utils.LogUtils; 38243c23618b066bcdcd0ab9e36d8c01f50db2cbd0Andy Huangimport com.android.mail.utils.Utils; 39632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 40632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang/** 41632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * A simple controller for a {@link ViewPager} of conversations. 42632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * <p> 43632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * Instead of placing a ViewPager in a Fragment that replaces the other app views, we leave a 44632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * ViewPager in the activity's view hierarchy at all times and have this controller manage it. 45632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * This allows the ViewPager to safely instantiate inner conversation fragments since it is not 46632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * itself contained in a Fragment (no nested fragments!). 47632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * <p> 48632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * This arrangement has pros and cons...<br> 49632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * pros: FragmentManager manages restoring conversation fragments, each conversation gets its own 50632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * LoaderManager<br> 51632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * cons: the activity's Controller has to specially handle show/hide conversation view, 52632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * conversation fragment transitions must be done manually 53632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * <p> 54632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * This controller is a small delegate of {@link AbstractActivityController} and shares its 55632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * lifetime. 56632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * 57632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang */ 587d64612104fd861474a09994f13768360f92041dAndy Huangpublic class ConversationPagerController { 59632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 6022ecc77345c86e0515c1f3c3447502c25c8c53d2Andy Huang private ViewPager mPager; 61632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang private ConversationPagerAdapter mPagerAdapter; 62632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang private FragmentManager mFragmentManager; 63090db1ec6fef366ab9e319040a00eca078ed41c3Andy Huang private ActivityController mActivityController; 64632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang private boolean mShown; 659d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang /** 669d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang * True when the initial conversation passed to show() is busy loading. We assume that the 6759ccec3db4710f2aea6a4a9a30160ad19331367dAndrew Sapperstein * first {@link #onConversationSeen()} callback is triggered by that initial 689d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang * conversation, and unset this flag when first signaled. Side-to-side paging will not re-enable 699d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang * this flag, since it's only needed for initial conversation load. 709d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang */ 719d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang private boolean mInitialConversationLoading; 729d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang private final DataSetObservable mLoadedObservable = new DataSetObservable(); 73632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 74d6ce2fef197dce0f294e5565d9753aac894979dbAndy Huang public static final String LOG_TAG = "ConvPager"; 75632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 76632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang /** 77632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * Enables an optimization to the PagerAdapter that causes ViewPager to initially load just the 78632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * target conversation, then when the conversation view signals that the conversation is loaded 79632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * and visible (via onConversationSeen), we switch to paged mode to load the left/right 80632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * adjacent conversations. 81632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * <p> 82632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * Should improve load times. It also works around an issue in ViewPager that always loads item 83632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang * zero (with the fragment visibility hint ON) when the adapter is initially set. 84632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang */ 8587cf662c9c6c87e7f40dab6545c41484a7e7bfd3Andy Huang private static final boolean ENABLE_SINGLETON_INITIAL_LOAD = false; 86632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 87632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang public ConversationPagerController(RestrictedActivity activity, 885895f7b0e5fa921f6d46bbaf6d8c7b1a8ebc7804Andy Huang ActivityController controller) { 89632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang mFragmentManager = activity.getFragmentManager(); 90f58e4c3c942033fce12b5f75f9e4d9e708c9ea6aAndy Huang mPager = (ViewPager) activity.findViewById(R.id.conversation_pager); 91090db1ec6fef366ab9e319040a00eca078ed41c3Andy Huang mActivityController = controller; 92d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang setupPageMargin(activity.getActivityContext()); 93632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 94632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 95a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang public void show(Account account, Folder folder, Conversation initialConversation, 96a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang boolean changeVisibility) { 979d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang mInitialConversationLoading = true; 989d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang 99632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang if (mShown) { 100632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang LogUtils.d(LOG_TAG, "IN CPC.show, but already shown"); 101b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang // optimize for the case where account+folder are the same, when we can just shift 102b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang // the existing pager to show the new conversation 10377fb5be70d76f22a64850aa7a40f6a9553960e4emindyp // If in detached mode, don't do this optimization 10477fb5be70d76f22a64850aa7a40f6a9553960e4emindyp if (mPagerAdapter != null && mPagerAdapter.matches(account, folder) 10577fb5be70d76f22a64850aa7a40f6a9553960e4emindyp && !mPagerAdapter.isDetached()) { 106b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang final int pos = mPagerAdapter.getConversationPosition(initialConversation); 107b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang if (pos >= 0) { 108b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang mPager.setCurrentItem(pos); 109b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang return; 110b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang } 111b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang } 112b373e3ec0e488914635345627f5734af0f0ef76bAndy Huang // unable to shift, destroy existing state and fall through to normal startup 113632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang cleanup(); 114632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 115632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 116a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang if (changeVisibility) { 117a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang mPager.setVisibility(View.VISIBLE); 118a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang } 11922ecc77345c86e0515c1f3c3447502c25c8c53d2Andy Huang 12022ecc77345c86e0515c1f3c3447502c25c8c53d2Andy Huang mPagerAdapter = new ConversationPagerAdapter(mPager.getResources(), mFragmentManager, 12122ecc77345c86e0515c1f3c3447502c25c8c53d2Andy Huang account, folder, initialConversation); 122632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang mPagerAdapter.setSingletonMode(ENABLE_SINGLETON_INITIAL_LOAD); 123090db1ec6fef366ab9e319040a00eca078ed41c3Andy Huang mPagerAdapter.setActivityController(mActivityController); 12422ecc77345c86e0515c1f3c3447502c25c8c53d2Andy Huang mPagerAdapter.setPager(mPager); 125632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang LogUtils.d(LOG_TAG, "IN CPC.show, adapter=%s", mPagerAdapter); 126632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 127243c23618b066bcdcd0ab9e36d8c01f50db2cbd0Andy Huang Utils.sConvLoadTimer.mark("pager init"); 128d6ce2fef197dce0f294e5565d9753aac894979dbAndy Huang LogUtils.d(LOG_TAG, "init pager adapter, count=%d initialConv=%s adapter=%s", 129d6ce2fef197dce0f294e5565d9753aac894979dbAndy Huang mPagerAdapter.getCount(), initialConversation, mPagerAdapter); 130632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang mPager.setAdapter(mPagerAdapter); 131632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 132632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang if (!ENABLE_SINGLETON_INITIAL_LOAD) { 133632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang // FIXME: unnecessary to do this on restore. setAdapter will restore current position 134632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang final int initialPos = mPagerAdapter.getConversationPosition(initialConversation); 1353825f3d2284b2b57fadcfe6a4ebd9992f3c5c7bbAndy Huang if (initialPos >= 0) { 1363825f3d2284b2b57fadcfe6a4ebd9992f3c5c7bbAndy Huang LogUtils.d(LOG_TAG, "*** pager fragment init pos=%d", initialPos); 1373825f3d2284b2b57fadcfe6a4ebd9992f3c5c7bbAndy Huang mPager.setCurrentItem(initialPos); 1383825f3d2284b2b57fadcfe6a4ebd9992f3c5c7bbAndy Huang } 139632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 140243c23618b066bcdcd0ab9e36d8c01f50db2cbd0Andy Huang Utils.sConvLoadTimer.mark("pager setAdapter"); 141632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 142632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang mShown = true; 143632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 144632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 145a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang public void hide(boolean changeVisibility) { 146632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang if (!mShown) { 147632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang LogUtils.d(LOG_TAG, "IN CPC.hide, but already hidden"); 148632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang return; 149632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 150632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang mShown = false; 151a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang if (changeVisibility) { 152a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang mPager.setVisibility(View.GONE); 153a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang } 154632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 155632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang LogUtils.d(LOG_TAG, "IN CPC.hide, clearing adapter and unregistering list observer"); 156632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang mPager.setAdapter(null); 157632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang cleanup(); 158632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 159632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 1609d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang public boolean isInitialConversationLoading() { 1619d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang return mInitialConversationLoading; 1629d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang } 1639d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang 164632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang public void onDestroy() { 165632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang // need to release resources before a configuration change kills the activity and controller 166632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang cleanup(); 167632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 168632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 169632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang private void cleanup() { 170632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang if (mPagerAdapter != null) { 171632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang // stop observing the conversation list 172090db1ec6fef366ab9e319040a00eca078ed41c3Andy Huang mPagerAdapter.setActivityController(null); 17322ecc77345c86e0515c1f3c3447502c25c8c53d2Andy Huang mPagerAdapter.setPager(null); 174632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang mPagerAdapter = null; 175632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 176632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 177632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang 1783b965d78774a42358ce6bbdcc43b4c8df130a60eScott Kennedy public void onConversationSeen() { 1799d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang if (mPagerAdapter == null) { 1809d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang return; 1819d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang } 1829d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang 183632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang // take the adapter out of singleton mode to begin loading the 184632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang // other non-visible conversations 1859d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang if (mPagerAdapter.isSingletonMode()) { 1863825f3d2284b2b57fadcfe6a4ebd9992f3c5c7bbAndy Huang LogUtils.i(LOG_TAG, "IN pager adapter, finished loading primary conversation," + 187632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang " switching to cursor mode to load other conversations"); 188632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang mPagerAdapter.setSingletonMode(false); 189632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 1909d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang 1919d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang if (mInitialConversationLoading) { 1929d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang mInitialConversationLoading = false; 1939d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang mLoadedObservable.notifyChanged(); 1949d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang } 1959d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang } 1969d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang 1979d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang public void registerConversationLoadedObserver(DataSetObserver observer) { 1989d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang mLoadedObservable.registerObserver(observer); 1999d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang } 2009d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang 2019d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang public void unregisterConversationLoadedObserver(DataSetObserver observer) { 2029d3fd92ed6091dbd0d38799222a1cf841f1c3f29Andy Huang mLoadedObservable.unregisterObserver(observer); 203632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang } 2045895f7b0e5fa921f6d46bbaf6d8c7b1a8ebc7804Andy Huang 205192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal /** 206192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal * Stops listening to changes to the adapter. This must be followed immediately by 207a3ed834c959ece3453c1b34953fabecb3b19c424Andy Huang * {@link #hide(boolean)}. 208192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal */ 209192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal public void stopListening() { 2102821aeaa8c06011d67344a0232079a69bd003ef8Andy Huang if (mPagerAdapter != null) { 2112821aeaa8c06011d67344a0232079a69bd003ef8Andy Huang mPagerAdapter.stopListening(); 2122821aeaa8c06011d67344a0232079a69bd003ef8Andy Huang } 213192fac189e6aed434556a4e37bd3c5c29ef02f29Vikram Aggarwal } 214d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang 215d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang private void setupPageMargin(Context c) { 216d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang final TypedArray a = c.obtainStyledAttributes(new int[] {android.R.attr.listDivider}); 217d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang final Drawable divider = a.getDrawable(0); 218d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang a.recycle(); 219d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang final int padding = c.getResources().getDimensionPixelOffset( 220d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang R.dimen.conversation_page_gutter); 2213213ffdac10adb0905cb5440c725345979d4eacfAndrew Sapperstein final Drawable gutterDrawable = new PageMarginDrawable(divider, padding, 0, padding, 0, 222eb58a092961773a8da67c0e0dd5770346381d938Andrew Sapperstein c.getResources().getColor(R.color.conversation_view_background_color)); 223d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang mPager.setPageMargin(gutterDrawable.getIntrinsicWidth() + 2 * padding); 224d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang mPager.setPageMarginDrawable(gutterDrawable); 225d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang } 226d00f346a1b0b1ea3a1029ed95c9beb693b418187Andy Huang 227632721e6b3a9ba8c476456f2e0fb1b564561e0b5Andy Huang} 228