PhotoViewActivity.java revision 7b2d2778159adf9d01e5e7fc5371e49850b2e084
1f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein/* 2f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Copyright (C) 2011 Google Inc. 3f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Licensed to The Android Open Source Project. 4f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 5f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License"); 6f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * you may not use this file except in compliance with the License. 7f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * You may obtain a copy of the License at 8f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 9f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * http://www.apache.org/licenses/LICENSE-2.0 10f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 11f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Unless required by applicable law or agreed to in writing, software 12f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS, 13f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * See the License for the specific language governing permissions and 15f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * limitations under the License. 16f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 17f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 18f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinpackage com.android.ex.photo; 19f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 20f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.app.ActionBar; 21150e623129eef49467f1d6f67649e4636a4513f2Andrew Sappersteinimport android.app.ActionBar.OnMenuVisibilityListener; 22f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.app.Activity; 23f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.app.ActivityManager; 24d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrookimport android.content.Context; 25f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.content.Intent; 2629e47d946fd19443c12ebad9f94e83741c7d9120Paul Westbrookimport android.content.res.Resources; 27f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.database.Cursor; 28f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.net.Uri; 291abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sappersteinimport android.os.Build; 30f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.os.Bundle; 31f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.os.Handler; 328746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.app.Fragment; 338746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.app.FragmentActivity; 348746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.app.LoaderManager; 358746927a945358bb9e515985a37cac7807261026Martin Hibdonimport android.support.v4.content.Loader; 36f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.support.v4.view.ViewPager.OnPageChangeListener; 37d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrookimport android.text.TextUtils; 38bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Coppimport android.view.MenuItem; 39f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.view.View; 40f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 41f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.PhotoViewPager.InterceptType; 42f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.PhotoViewPager.OnInterceptTouchListener; 43f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.adapters.PhotoPagerAdapter; 440c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sappersteinimport com.android.ex.photo.fragments.PhotoViewFragment; 45f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.loaders.PhotoPagerLoader; 46f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.provider.PhotoContract; 47f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 4879bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Weiimport java.util.HashMap; 49f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport java.util.HashSet; 5079bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Weiimport java.util.Map; 51f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport java.util.Set; 52f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 53f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein/** 54f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Activity to view the contents of an album. 55f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 568746927a945358bb9e515985a37cac7807261026Martin Hibdonpublic class PhotoViewActivity extends FragmentActivity implements 578746927a945358bb9e515985a37cac7807261026Martin Hibdon LoaderManager.LoaderCallbacks<Cursor>, OnPageChangeListener, OnInterceptTouchListener, 58399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon OnMenuVisibilityListener, PhotoViewCallbacks { 590c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 60f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private final static String STATE_ITEM_KEY = 61f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein "com.google.android.apps.plus.PhotoViewFragment.ITEM"; 62f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private final static String STATE_FULLSCREEN_KEY = 63f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein "com.google.android.apps.plus.PhotoViewFragment.FULLSCREEN"; 647b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal private final static String STATE_ACTIONBARTITLE_KEY = 657b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal "com.google.android.apps.plus.PhotoViewFragment.ACTIONBARTITLE"; 667b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal private final static String STATE_ACTIONBARSUBTITLE_KEY = 677b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal "com.google.android.apps.plus.PhotoViewFragment.ACTIONBARSUBTITLE"; 68f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 69f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private static final int LOADER_PHOTO_LIST = 1; 70f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 71f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Count used when the real photo count is unknown [but, may be determined] */ 72f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static final int ALBUM_COUNT_UNKNOWN = -1; 73f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 74f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Argument key for the dialog message */ 75f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static final String KEY_MESSAGE = "dialog_message"; 76f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 77f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static int sMemoryClass; 78f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 79f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The URI of the photos we're viewing; may be {@code null} */ 80f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private String mPhotosUri; 81d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook /** The URI of the initial photo to display */ 82d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook private String mInitialPhotoUri; 83f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The index of the currently viewed photo */ 84f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private int mPhotoIndex; 85f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The query projection to use; may be {@code null} */ 86f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private String[] mProjection; 87f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The total number of photos; only valid if {@link #mIsEmpty} is {@code false}. */ 88f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private int mAlbumCount = ALBUM_COUNT_UNKNOWN; 89f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** {@code true} if the view is empty. Otherwise, {@code false}. */ 90f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private boolean mIsEmpty; 91d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook /** the main root view */ 92d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook protected View mRootView; 93f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The main pager; provides left/right swipe between photos */ 94d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook protected PhotoViewPager mViewPager; 95f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Adapter to create pager views */ 96d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook protected PhotoPagerAdapter mAdapter; 97f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Whether or not we're in "full screen" mode */ 98f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private boolean mFullScreen; 9979bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei /** The listeners wanting full screen state for each screen position */ 10079bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei private Map<Integer, OnScreenListener> 10179bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei mScreenListeners = new HashMap<Integer, OnScreenListener>(); 1020c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein /** The set of listeners wanting full screen state */ 1030c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein private Set<CursorChangedListener> mCursorListeners = new HashSet<CursorChangedListener>(); 104f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** When {@code true}, restart the loader when the activity becomes active */ 105f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private boolean mRestartLoader; 106f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Whether or not this activity is paused */ 107f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private boolean mIsPaused = true; 10891dbfd25cc234de393ae22fc39a832a6335e1bc2Adam Copp /** The maximum scale factor applied to images when they are initially displayed */ 10991dbfd25cc234de393ae22fc39a832a6335e1bc2Adam Copp private float mMaxInitialScale; 1107b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal /** The title in the actionbar */ 1117b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal private String mActionBarTitle; 1127b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal /** The subtitle in the actionbar */ 1137b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal private String mActionBarSubtitle; 1147b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal 115e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook private final Handler mHandler = new Handler(); 116f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // TODO Find a better way to do this. We basically want the activity to display the 117f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // "loading..." progress until the fragment takes over and shows it's own "loading..." 118f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // progress [located in photo_header_view.xml]. We could potentially have all status displayed 119f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // by the activity, but, that gets tricky when it comes to screen rotation. For now, we 120f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // track the loading by this variable which is fragile and may cause phantom "loading..." 121f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // text. 12240a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook private long mEnterFullScreenDelayTime; 123f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 124d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook protected PhotoPagerAdapter createPhotoPagerAdapter(Context context, 125d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook android.support.v4.app.FragmentManager fm, Cursor c, float maxScale) { 126d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook return new PhotoPagerAdapter(context, fm, c, maxScale); 127d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook } 128d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook 129f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 130f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein protected void onCreate(Bundle savedInstanceState) { 131f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onCreate(savedInstanceState); 132f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 133f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final ActivityManager mgr = (ActivityManager) getApplicationContext(). 134f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein getSystemService(Activity.ACTIVITY_SERVICE); 135f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein sMemoryClass = mgr.getMemoryClass(); 136f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 137f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein Intent mIntent = getIntent(); 138f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 139f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein int currentItem = -1; 140f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (savedInstanceState != null) { 141f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein currentItem = savedInstanceState.getInt(STATE_ITEM_KEY, -1); 142f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mFullScreen = savedInstanceState.getBoolean(STATE_FULLSCREEN_KEY, false); 1437b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal mActionBarTitle = savedInstanceState.getString(STATE_ACTIONBARTITLE_KEY); 1447b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal mActionBarSubtitle = savedInstanceState.getString(STATE_ACTIONBARSUBTITLE_KEY); 145f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 146f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 147f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // uri of the photos to view; optional 148f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIntent.hasExtra(Intents.EXTRA_PHOTOS_URI)) { 149f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotosUri = mIntent.getStringExtra(Intents.EXTRA_PHOTOS_URI); 150f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 151f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 152f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // projection for the query; optional 153f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // I.f not set, the default projection is used. 154f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // This projection must include the columns from the default projection. 155f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIntent.hasExtra(Intents.EXTRA_PROJECTION)) { 156f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mProjection = mIntent.getStringArrayExtra(Intents.EXTRA_PROJECTION); 157f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 158f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mProjection = null; 159f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 160f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 161f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Set the current item from the intent if wasn't in the saved instance 162f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIntent.hasExtra(Intents.EXTRA_PHOTO_INDEX) && currentItem < 0) { 163f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein currentItem = mIntent.getIntExtra(Intents.EXTRA_PHOTO_INDEX, -1); 164f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 165d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook if (mIntent.hasExtra(Intents.EXTRA_INITIAL_PHOTO_URI) && currentItem < 0) { 166d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook mInitialPhotoUri = mIntent.getStringExtra(Intents.EXTRA_INITIAL_PHOTO_URI); 167d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook } 16891dbfd25cc234de393ae22fc39a832a6335e1bc2Adam Copp 16991dbfd25cc234de393ae22fc39a832a6335e1bc2Adam Copp // Set the max initial scale, defaulting to 1x 17091dbfd25cc234de393ae22fc39a832a6335e1bc2Adam Copp mMaxInitialScale = mIntent.getFloatExtra(Intents.EXTRA_MAX_INITIAL_SCALE, 1.0f); 17191dbfd25cc234de393ae22fc39a832a6335e1bc2Adam Copp 172f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoIndex = currentItem; 17379bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei mIsEmpty = true; 174f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 175f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setContentView(R.layout.photo_activity_view); 176f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 177f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Create the adapter and add the view pager 178d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook mAdapter = createPhotoPagerAdapter(this, getSupportFragmentManager(), 179d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook null, mMaxInitialScale); 180fd925449925f3eb6e2ab6e1c50203c4a4bc165b2Paul Westbrook final Resources resources = getResources(); 181d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook mRootView = findViewById(R.id.photo_activity_root_view); 182f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mViewPager = (PhotoViewPager) findViewById(R.id.photo_view_pager); 183f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mViewPager.setOnPageChangeListener(this); 184f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mViewPager.setOnInterceptTouchListener(this); 185fd925449925f3eb6e2ab6e1c50203c4a4bc165b2Paul Westbrook mViewPager.setPageMargin(resources.getDimensionPixelSize(R.dimen.photo_page_margin)); 186f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 187f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Kick off the loader 1888746927a945358bb9e515985a37cac7807261026Martin Hibdon getSupportLoaderManager().initLoader(LOADER_PHOTO_LIST, null, this); 189f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 19040a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook mEnterFullScreenDelayTime = 19140a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook resources.getInteger(R.integer.reenter_fullscreen_delay_time_in_millis); 19240a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook 193f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final ActionBar actionBar = getActionBar(); 194d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook if (actionBar != null) { 195d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook actionBar.setDisplayHomeAsUpEnabled(true); 196d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook actionBar.addOnMenuVisibilityListener(this); 1977b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal final int showTitle = ActionBar.DISPLAY_SHOW_TITLE; 1987b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal actionBar.setDisplayOptions(showTitle, showTitle); 1997b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal setActionBarTitles(actionBar); 200d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook } 201f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 202f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 203f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 204f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein protected void onResume() { 205f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onResume(); 206f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setFullScreen(mFullScreen, false); 207f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 208f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mIsPaused = false; 209f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mRestartLoader) { 210f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mRestartLoader = false; 2118746927a945358bb9e515985a37cac7807261026Martin Hibdon getSupportLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this); 212f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 213f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 214f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 215f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 216f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein protected void onPause() { 217f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mIsPaused = true; 218f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 219f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onPause(); 220f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 221f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 222f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 223f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onBackPressed() { 224f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // If in full screen mode, toggle mode & eat the 'back' 225f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mFullScreen) { 226f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein toggleFullScreen(); 227f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 228f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onBackPressed(); 229f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 230f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 231f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 232f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 233f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onSaveInstanceState(Bundle outState) { 234f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onSaveInstanceState(outState); 235f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 236f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein outState.putInt(STATE_ITEM_KEY, mViewPager.getCurrentItem()); 237f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein outState.putBoolean(STATE_FULLSCREEN_KEY, mFullScreen); 2387b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal outState.putString(STATE_ACTIONBARTITLE_KEY, mActionBarTitle); 2397b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal outState.putString(STATE_ACTIONBARSUBTITLE_KEY, mActionBarSubtitle); 240f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 241f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 242bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp @Override 243bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp public boolean onOptionsItemSelected(MenuItem item) { 244bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp switch (item.getItemId()) { 245bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp case android.R.id.home: 246bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp finish(); 247bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp default: 248bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp return super.onOptionsItemSelected(item); 249bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp } 250bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp } 251bd8b47b147f29f196f37d66ccb561d40414ab5b6Adam Copp 252399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon @Override 25379bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei public void addScreenListener(int position, OnScreenListener listener) { 25479bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei mScreenListeners.put(position, listener); 255f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 256f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 257399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon @Override 25879bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei public void removeScreenListener(int position) { 25979bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei mScreenListeners.remove(position); 260f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 261f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 262399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon @Override 2630c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public synchronized void addCursorListener(CursorChangedListener listener) { 2640c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mCursorListeners.add(listener); 2650c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 2660c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 267399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon @Override 2680c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public synchronized void removeCursorListener(CursorChangedListener listener) { 2690c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mCursorListeners.remove(listener); 2700c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 2710c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 272399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon @Override 273f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean isFragmentFullScreen(Fragment fragment) { 274f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mViewPager == null || mAdapter == null || mAdapter.getCount() == 0) { 275f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return mFullScreen; 276f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 277f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return mFullScreen || (mViewPager.getCurrentItem() != mAdapter.getItemPosition(fragment)); 278f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 279f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 280399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon @Override 281f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void toggleFullScreen() { 282f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setFullScreen(!mFullScreen, true); 283f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 284f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 285f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPhotoRemoved(long photoId) { 286f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final Cursor data = mAdapter.getCursor(); 287f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (data == null) { 288f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Huh?! How would this happen? 289f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return; 290f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 291f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 292f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int dataCount = data.getCount(); 293f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (dataCount <= 1) { 294f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein finish(); 295f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return; 296f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 297f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 2988746927a945358bb9e515985a37cac7807261026Martin Hibdon getSupportLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this); 299f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 300f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 301f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 302f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public Loader<Cursor> onCreateLoader(int id, Bundle args) { 303f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (id == LOADER_PHOTO_LIST) { 304f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return new PhotoPagerLoader(this, Uri.parse(mPhotosUri), mProjection); 305f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 306f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return null; 307f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 308f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 309f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 3108746927a945358bb9e515985a37cac7807261026Martin Hibdon public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 311f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int id = loader.getId(); 312f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (id == LOADER_PHOTO_LIST) { 313f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (data == null || data.getCount() == 0) { 314f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mIsEmpty = true; 315f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 316f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mAlbumCount = data.getCount(); 317f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 318d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook if (mInitialPhotoUri != null) { 319d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook int index = 0; 320d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook int uriIndex = data.getColumnIndex(PhotoContract.PhotoViewColumns.URI); 321d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook while (data.moveToNext()) { 322d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook String uri = data.getString(uriIndex); 323d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook if (TextUtils.equals(uri, mInitialPhotoUri)) { 324d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook mInitialPhotoUri = null; 325d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook mPhotoIndex = index; 326d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook break; 327d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook } 328d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook index++; 329d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook } 330d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook } 331d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook 332e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // We're paused; don't do anything now, we'll get re-invoked 333e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // when the activity becomes active again 334e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // TODO(pwestbro): This shouldn't be necessary, as the loader manager should 335e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // restart the loader 336e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook if (mIsPaused) { 337e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mRestartLoader = true; 338e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook return; 339e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook } 34079bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei boolean wasEmpty = mIsEmpty; 341e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mIsEmpty = false; 342e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook 3434a6a7183e0740dfb305a16676c867e182aced7aaAdam Copp mAdapter.swapCursor(data); 344d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook if (mViewPager.getAdapter() == null) { 345d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook mViewPager.setAdapter(mAdapter); 346d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook } 3474a6a7183e0740dfb305a16676c867e182aced7aaAdam Copp notifyCursorListeners(data); 3484a6a7183e0740dfb305a16676c867e182aced7aaAdam Copp 349e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // set the selected photo 350e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook int itemIndex = mPhotoIndex; 351e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook 352e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // Use an index of 0 if the index wasn't specified or couldn't be found 353e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook if (itemIndex < 0) { 354e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook itemIndex = 0; 355e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook } 356e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook 357e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mViewPager.setCurrentItem(itemIndex, false); 35879bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei if (wasEmpty) { 35979bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei setViewActivated(itemIndex); 36079bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei } 361f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 3622989cf0c8e4b0aee4c9ac2b5384a392fd74cd6a9Paul Westbrook // Update the any action items 3632989cf0c8e4b0aee4c9ac2b5384a392fd74cd6a9Paul Westbrook updateActionItems(); 364f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 365f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 366f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 3678746927a945358bb9e515985a37cac7807261026Martin Hibdon @Override 3688746927a945358bb9e515985a37cac7807261026Martin Hibdon public void onLoaderReset(android.support.v4.content.Loader<Cursor> loader) { 3698746927a945358bb9e515985a37cac7807261026Martin Hibdon // If the loader is reset, remove the reference in the adapter to this cursor 3708746927a945358bb9e515985a37cac7807261026Martin Hibdon // TODO(pwestbro): reenable this when b/7075236 is fixed 3718746927a945358bb9e515985a37cac7807261026Martin Hibdon // mAdapter.swapCursor(null); 3728746927a945358bb9e515985a37cac7807261026Martin Hibdon } 3738746927a945358bb9e515985a37cac7807261026Martin Hibdon 3742989cf0c8e4b0aee4c9ac2b5384a392fd74cd6a9Paul Westbrook protected void updateActionItems() { 3752989cf0c8e4b0aee4c9ac2b5384a392fd74cd6a9Paul Westbrook // Do nothing, but allow extending classes to do work 3762989cf0c8e4b0aee4c9ac2b5384a392fd74cd6a9Paul Westbrook } 3772989cf0c8e4b0aee4c9ac2b5384a392fd74cd6a9Paul Westbrook 3780c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein private synchronized void notifyCursorListeners(Cursor data) { 3790c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein // tell all of the objects listening for cursor changes 3800c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein // that the cursor has changed 3810c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein for (CursorChangedListener listener : mCursorListeners) { 3820c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein listener.onCursorChanged(data); 3830c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 3840c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 3850c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 386f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 387f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 388f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 389f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 390f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 391f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPageSelected(int position) { 392f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoIndex = position; 39379bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei setViewActivated(position); 394f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 395f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 396f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 397f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPageScrollStateChanged(int state) { 398f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 399f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 400399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon @Override 401f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean isFragmentActive(Fragment fragment) { 402f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mViewPager == null || mAdapter == null) { 403f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return false; 404f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 405f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return mViewPager.getCurrentItem() == mAdapter.getItemPosition(fragment); 406f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 407f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 408d4f7888c44dbc6808c20db3605bc48cc42f0b350Paul Westbrook @Override 4090c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public void onFragmentVisible(PhotoViewFragment fragment) { 4107b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal updateActionBar(); 411f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 412f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 413f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 414f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public InterceptType onTouchIntercept(float origX, float origY) { 415f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein boolean interceptLeft = false; 416f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein boolean interceptRight = false; 417f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 41879bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei for (OnScreenListener listener : mScreenListeners.values()) { 419f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (!interceptLeft) { 420f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein interceptLeft = listener.onInterceptMoveLeft(origX, origY); 421f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 422f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (!interceptRight) { 423f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein interceptRight = listener.onInterceptMoveRight(origX, origY); 424f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 425f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 426f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 427f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (interceptLeft) { 428f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (interceptRight) { 429f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return InterceptType.BOTH; 430f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 431f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return InterceptType.LEFT; 432f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else if (interceptRight) { 433f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return InterceptType.RIGHT; 434f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 435f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return InterceptType.NONE; 436f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 437f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 438f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 439f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Updates the title bar according to the value of {@link #mFullScreen}. 440f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 4410ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp protected void setFullScreen(boolean fullScreen, boolean setDelayedRunnable) { 442f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final boolean fullScreenChanged = (fullScreen != mFullScreen); 443f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mFullScreen = fullScreen; 444f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 445f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mFullScreen) { 4461abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein setLightsOutMode(true); 44740a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook cancelEnterFullScreenRunnable(); 448f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 4491abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein setLightsOutMode(false); 4501abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein if (setDelayedRunnable) { 45140a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook postEnterFullScreenRunnableWithDelay(); 4521abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 453f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 454f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 455f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (fullScreenChanged) { 45679bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei for (OnScreenListener listener : mScreenListeners.values()) { 4571abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein listener.onFullScreenChanged(mFullScreen); 4581abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 4591abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 4601abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 4611abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein 46240a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook private void postEnterFullScreenRunnableWithDelay() { 46340a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook mHandler.postDelayed(mEnterFullScreenRunnable, mEnterFullScreenDelayTime); 464150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 465150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 46640a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook private void cancelEnterFullScreenRunnable() { 46740a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook mHandler.removeCallbacks(mEnterFullScreenRunnable); 468150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 469150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 4707e6995626b551c215bc3064c95b9996af940746aAdam Copp protected void setLightsOutMode(boolean enabled) { 4711abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 4721abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein int flags = enabled 4731abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein ? View.SYSTEM_UI_FLAG_LOW_PROFILE 4741abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein | View.SYSTEM_UI_FLAG_FULLSCREEN 4751abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 4761abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 4771abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein : View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 4781abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; 4791abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein 4801abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein // using mViewPager since we have it and we need a view 4811abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein mViewPager.setSystemUiVisibility(flags); 4821abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } else { 4831abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein final ActionBar actionBar = getActionBar(); 4841abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein if (enabled) { 4851abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein actionBar.hide(); 4861abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } else { 4871abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein actionBar.show(); 488f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 4891abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein int flags = enabled 4901abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein ? View.SYSTEM_UI_FLAG_LOW_PROFILE 4911abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein : View.SYSTEM_UI_FLAG_VISIBLE; 4921abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein mViewPager.setSystemUiVisibility(flags); 493f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 494f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 495f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 49640a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook private Runnable mEnterFullScreenRunnable = new Runnable() { 4971abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein @Override 4981abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein public void run() { 499b462d1bf5d3833fabbdc38d13f66dadcf6ceda54Adam Copp setFullScreen(true, true); 5001abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 5011abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein }; 5021abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein 503399fe3d995ed4366a18c7ce6632b3014284df57aMartin Hibdon @Override 50479bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei public void setViewActivated(int position) { 50579bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei OnScreenListener listener = mScreenListeners.get(position); 50679bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei if (listener != null) { 507f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein listener.onViewActivated(); 508f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 509f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 510f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 511f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 512f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Adjusts the activity title and subtitle to reflect the photo name and count. 513f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 5147b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal protected void updateActionBar() { 515f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int position = mViewPager.getCurrentItem() + 1; 516f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final boolean hasAlbumCount = mAlbumCount >= 0; 517f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 518f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final Cursor cursor = getCursorAtProperPosition(); 519f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (cursor != null) { 520f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int photoNameIndex = cursor.getColumnIndex(PhotoContract.PhotoViewColumns.NAME); 5217b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal mActionBarTitle = cursor.getString(photoNameIndex); 52268a16aa04f9b98868f4412e7324b0fc292c9d858Andrew Sapperstein } else { 5237b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal mActionBarTitle = null; 524f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 525f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 526f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIsEmpty || !hasAlbumCount || position <= 0) { 5277b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal mActionBarSubtitle = null; 528f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 5297b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal mActionBarSubtitle = 5307b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal getResources().getString(R.string.photo_view_count, position, mAlbumCount); 531f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 5327b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal setActionBarTitles(getActionBar()); 5337b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal } 534f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 5357b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal /** 5367b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal * Sets the Action Bar title to {@link #mActionBarTitle} and the subtitle to 5377b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal * {@link #mActionBarSubtitle} 5387b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal */ 5397b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal private final void setActionBarTitles(ActionBar actionBar) { 5407b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal if (actionBar == null) { 5417b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal return; 5427b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal } 5437b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal actionBar.setTitle(getInputOrEmpty(mActionBarTitle)); 5447b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal actionBar.setSubtitle(getInputOrEmpty(mActionBarSubtitle)); 5457b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal } 5467b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal 5477b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal /** 5487b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal * If the input string is non-null, it is returned, otherwise an empty string is returned; 5497b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal * @param in 5507b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal * @return 5517b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal */ 5527b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal private static final String getInputOrEmpty(String in) { 5537b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal if (in == null) { 5547b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal return ""; 5557b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal } 5567b2d2778159adf9d01e5e7fc5371e49850b2e084Vikram Aggarwal return in; 557f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 558f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 559f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 560f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Utility method that will return the cursor that contains the data 561f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * at the current position so that it refers to the current image on screen. 562f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @return the cursor at the current position or 563f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * null if no cursor exists or if the {@link PhotoViewPager} is null. 564f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 565f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public Cursor getCursorAtProperPosition() { 566f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mViewPager == null) { 567f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return null; 568f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 569f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 570f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int position = mViewPager.getCurrentItem(); 571f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final Cursor cursor = mAdapter.getCursor(); 572f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 573f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (cursor == null) { 574f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return null; 575f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 576f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 577f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein cursor.moveToPosition(position); 578f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 579f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return cursor; 580f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 5819007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein 5829007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein public Cursor getCursor() { 5839007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein return (mAdapter == null) ? null : mAdapter.getCursor(); 5849007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein } 585150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 586150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein @Override 587150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein public void onMenuVisibilityChanged(boolean isVisible) { 588150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein if (isVisible) { 58940a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook cancelEnterFullScreenRunnable(); 590150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } else { 59140a26567ebaf6311bd7a102491d669abd1d68646Paul Westbrook postEnterFullScreenRunnableWithDelay(); 592150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 593150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 5940ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp 5950bf849421d303e05c600cdcd7dab73cc84809a36Mark Wei @Override 59679bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei public void onNewPhotoLoaded(int position) { 59779bc0d5ba2f06b25052fe95fac1593ebde234d9aMark Wei // do nothing 5988f359e98b9f18064a75c80b9c9ad8bda2713c612Paul Westbrook } 5998f359e98b9f18064a75c80b9c9ad8bda2713c612Paul Westbrook 6000ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp protected boolean isFullScreen() { 6010ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp return mFullScreen; 6020ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp } 6030ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp 6040ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp protected void setPhotoIndex(int index) { 6050ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp mPhotoIndex = index; 6060ab3e0cf9cbb5751a276e4c2555640a0e8173b5fAdam Copp } 6078746927a945358bb9e515985a37cac7807261026Martin Hibdon 6080bf849421d303e05c600cdcd7dab73cc84809a36Mark Wei @Override 6090bf849421d303e05c600cdcd7dab73cc84809a36Mark Wei public void onCursorChanged(PhotoViewFragment fragment, Cursor cursor) { 6100bf849421d303e05c600cdcd7dab73cc84809a36Mark Wei // do nothing 6110bf849421d303e05c600cdcd7dab73cc84809a36Mark Wei } 612f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein} 613