PhotoViewActivity.java revision e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3
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; 24f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.app.Fragment; 25f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.app.LoaderManager.LoaderCallbacks; 26f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.content.Intent; 27f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.content.Loader; 28f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.database.Cursor; 29f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.net.Uri; 301abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sappersteinimport android.os.Build; 31f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.os.Bundle; 32f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.os.Handler; 33f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.support.v4.view.ViewPager.OnPageChangeListener; 34f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport android.view.View; 35f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 36f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.PhotoViewPager.InterceptType; 37f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.PhotoViewPager.OnInterceptTouchListener; 38f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.adapters.PhotoPagerAdapter; 390c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sappersteinimport com.android.ex.photo.fragments.PhotoViewFragment; 40f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.loaders.PhotoPagerLoader; 41f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport com.android.ex.photo.provider.PhotoContract; 42f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 43f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport java.util.HashSet; 44f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinimport java.util.Set; 45f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 46f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein/** 47f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Activity to view the contents of an album. 48f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 49f77a7eb196d16110c7b1087352b423913821ff61Andrew Sappersteinpublic class PhotoViewActivity extends Activity implements 50f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein LoaderCallbacks<Cursor>, OnPageChangeListener, OnInterceptTouchListener, 519556f61c11991d6e955cfd68ca53f4f489dfa8c5Paul Westbrook OnMenuVisibilityListener { 52f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 53f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 54f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Listener to be invoked for screen events. 55f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 56f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static interface OnScreenListener { 57f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 58f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 59f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * The full screen state has changed. 60f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 611abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein public void onFullScreenChanged(boolean fullScreen); 62f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 63f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 64f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * A new view has been activated and the previous view de-activated. 65f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 66f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onViewActivated(); 67f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 68f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 69f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Called when a right-to-left touch move intercept is about to occur. 70f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 71f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @param origX the raw x coordinate of the initial touch 72f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @param origY the raw y coordinate of the initial touch 73f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @return {@code true} if the touch should be intercepted. 74f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 75f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean onInterceptMoveLeft(float origX, float origY); 76f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 77f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 78f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Called when a left-to-right touch move intercept is about to occur. 79f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * 80f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @param origX the raw x coordinate of the initial touch 81f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @param origY the raw y coordinate of the initial touch 82f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @return {@code true} if the touch should be intercepted. 83f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 84f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean onInterceptMoveRight(float origX, float origY); 85f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 86f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 870c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public static interface CursorChangedListener { 880c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein /** 890c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein * Called when the cursor that contains the photo list data 900c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein * is updated. Note that there is no guarantee that the cursor 910c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein * will be at the proper position. 920c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein * @param cursor the cursor containing the photo list data 930c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein */ 940c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public void onCursorChanged(Cursor cursor); 950c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 960c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 97f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private final static String STATE_ITEM_KEY = 98f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein "com.google.android.apps.plus.PhotoViewFragment.ITEM"; 99f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private final static String STATE_FULLSCREEN_KEY = 100f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein "com.google.android.apps.plus.PhotoViewFragment.FULLSCREEN"; 101f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 102f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private static final int LOADER_PHOTO_LIST = 1; 103f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 104f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Count used when the real photo count is unknown [but, may be determined] */ 105f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static final int ALBUM_COUNT_UNKNOWN = -1; 106f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 107f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Argument key for the dialog message */ 108f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static final String KEY_MESSAGE = "dialog_message"; 109f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 110f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public static int sMemoryClass; 111f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 112f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The URI of the photos we're viewing; may be {@code null} */ 113f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private String mPhotosUri; 114f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The index of the currently viewed photo */ 115f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private int mPhotoIndex; 116f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The query projection to use; may be {@code null} */ 117f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private String[] mProjection; 118f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The total number of photos; only valid if {@link #mIsEmpty} is {@code false}. */ 119f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private int mAlbumCount = ALBUM_COUNT_UNKNOWN; 120f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** {@code true} if the view is empty. Otherwise, {@code false}. */ 121f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private boolean mIsEmpty; 122f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The main pager; provides left/right swipe between photos */ 123f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private PhotoViewPager mViewPager; 124f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Adapter to create pager views */ 125f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private PhotoPagerAdapter mAdapter; 126f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Whether or not we're in "full screen" mode */ 127f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private boolean mFullScreen; 128f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** The set of listeners wanting full screen state */ 129f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private Set<OnScreenListener> mScreenListeners = new HashSet<OnScreenListener>(); 1300c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein /** The set of listeners wanting full screen state */ 1310c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein private Set<CursorChangedListener> mCursorListeners = new HashSet<CursorChangedListener>(); 132f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** When {@code true}, restart the loader when the activity becomes active */ 133f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private boolean mRestartLoader; 134f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** Whether or not this activity is paused */ 135f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein private boolean mIsPaused = true; 136e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook private final Handler mHandler = new Handler(); 137f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // TODO Find a better way to do this. We basically want the activity to display the 138f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // "loading..." progress until the fragment takes over and shows it's own "loading..." 139f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // progress [located in photo_header_view.xml]. We could potentially have all status displayed 140f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // by the activity, but, that gets tricky when it comes to screen rotation. For now, we 141f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // track the loading by this variable which is fragile and may cause phantom "loading..." 142f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // text. 1431abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein private long mActionBarHideDelayTime; 144f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 145f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 146f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein protected void onCreate(Bundle savedInstanceState) { 147f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onCreate(savedInstanceState); 148f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 149f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final ActivityManager mgr = (ActivityManager) getApplicationContext(). 150f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein getSystemService(Activity.ACTIVITY_SERVICE); 151f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein sMemoryClass = mgr.getMemoryClass(); 152f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 153f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein Intent mIntent = getIntent(); 154f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 155f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein int currentItem = -1; 156f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (savedInstanceState != null) { 157f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein currentItem = savedInstanceState.getInt(STATE_ITEM_KEY, -1); 158f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mFullScreen = savedInstanceState.getBoolean(STATE_FULLSCREEN_KEY, false); 159f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 160f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 161f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // uri of the photos to view; optional 162f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIntent.hasExtra(Intents.EXTRA_PHOTOS_URI)) { 163f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotosUri = mIntent.getStringExtra(Intents.EXTRA_PHOTOS_URI); 164f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 165f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 166f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // projection for the query; optional 167f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // I.f not set, the default projection is used. 168f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // This projection must include the columns from the default projection. 169f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIntent.hasExtra(Intents.EXTRA_PROJECTION)) { 170f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mProjection = mIntent.getStringArrayExtra(Intents.EXTRA_PROJECTION); 171f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 172f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mProjection = null; 173f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 174f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 175f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Set the current item from the intent if wasn't in the saved instance 176f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIntent.hasExtra(Intents.EXTRA_PHOTO_INDEX) && currentItem < 0) { 177f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein currentItem = mIntent.getIntExtra(Intents.EXTRA_PHOTO_INDEX, -1); 178f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 179f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoIndex = currentItem; 180f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 181f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setContentView(R.layout.photo_activity_view); 182f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 183f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Create the adapter and add the view pager 184f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mAdapter = new PhotoPagerAdapter(this, getFragmentManager(), null); 185f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 186f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mViewPager = (PhotoViewPager) findViewById(R.id.photo_view_pager); 187f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mViewPager.setAdapter(mAdapter); 188f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mViewPager.setOnPageChangeListener(this); 189f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mViewPager.setOnInterceptTouchListener(this); 190f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 191f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Kick off the loader 192f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein getLoaderManager().initLoader(LOADER_PHOTO_LIST, null, this); 193f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 194f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final ActionBar actionBar = getActionBar(); 195f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein actionBar.setDisplayHomeAsUpEnabled(true); 1961abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein mActionBarHideDelayTime = getResources().getInteger( 1971abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein R.integer.action_bar_delay_time_in_millis); 198150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein actionBar.addOnMenuVisibilityListener(this); 19968a16aa04f9b98868f4412e7324b0fc292c9d858Andrew Sapperstein actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 200f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 201f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 202f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 203f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein protected void onResume() { 204f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onResume(); 205f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setFullScreen(mFullScreen, false); 206f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 207f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mIsPaused = false; 208f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mRestartLoader) { 209f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mRestartLoader = false; 210f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein getLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this); 211f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 212f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 213f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 214f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 215f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein protected void onPause() { 216f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mIsPaused = true; 217f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 218f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onPause(); 219f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 220f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 221f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 222f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onBackPressed() { 223f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // If in full screen mode, toggle mode & eat the 'back' 224f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mFullScreen) { 225f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein toggleFullScreen(); 226f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 227f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onBackPressed(); 228f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 229f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 230f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 231f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 232f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onSaveInstanceState(Bundle outState) { 233f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein super.onSaveInstanceState(outState); 234f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 235f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein outState.putInt(STATE_ITEM_KEY, mViewPager.getCurrentItem()); 236f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein outState.putBoolean(STATE_FULLSCREEN_KEY, mFullScreen); 237f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 238f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 239f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void addScreenListener(OnScreenListener listener) { 240f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mScreenListeners.add(listener); 241f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 242f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 243f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void removeScreenListener(OnScreenListener listener) { 244f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mScreenListeners.remove(listener); 245f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 246f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 2470c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public synchronized void addCursorListener(CursorChangedListener listener) { 2480c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mCursorListeners.add(listener); 2490c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 2500c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 2510c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public synchronized void removeCursorListener(CursorChangedListener listener) { 2520c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein mCursorListeners.remove(listener); 2530c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 2540c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 255f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean isFragmentFullScreen(Fragment fragment) { 256f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mViewPager == null || mAdapter == null || mAdapter.getCount() == 0) { 257f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return mFullScreen; 258f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 259f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return mFullScreen || (mViewPager.getCurrentItem() != mAdapter.getItemPosition(fragment)); 260f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 261f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 262f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void toggleFullScreen() { 263f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein setFullScreen(!mFullScreen, true); 264f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 265f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 266f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPhotoRemoved(long photoId) { 267f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final Cursor data = mAdapter.getCursor(); 268f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (data == null) { 269f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein // Huh?! How would this happen? 270f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return; 271f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 272f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 273f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int dataCount = data.getCount(); 274f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (dataCount <= 1) { 275f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein finish(); 276f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return; 277f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 278f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 279f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein getLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this); 280f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 281f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 282f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 283f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public Loader<Cursor> onCreateLoader(int id, Bundle args) { 284f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (id == LOADER_PHOTO_LIST) { 285f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return new PhotoPagerLoader(this, Uri.parse(mPhotosUri), mProjection); 286f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 287f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return null; 288f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 289f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 290f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 291f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) { 292f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int id = loader.getId(); 293f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (id == LOADER_PHOTO_LIST) { 294f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (data == null || data.getCount() == 0) { 295f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mIsEmpty = true; 296f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 297f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mAlbumCount = data.getCount(); 298f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 299e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // We're paused; don't do anything now, we'll get re-invoked 300e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // when the activity becomes active again 301e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // TODO(pwestbro): This shouldn't be necessary, as the loader manager should 302e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // restart the loader 303e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook if (mIsPaused) { 304e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mRestartLoader = true; 305e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook return; 306e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook } 307e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mIsEmpty = false; 308e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook 309e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // set the selected photo 310e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook int itemIndex = mPhotoIndex; 311e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook 312e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // Use an index of 0 if the index wasn't specified or couldn't be found 313e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook if (itemIndex < 0) { 314e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook itemIndex = 0; 315e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook } 316e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook 317e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mAdapter.swapCursor(data); 318e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook notifyCursorListeners(data); 319e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook 320e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mViewPager.setCurrentItem(itemIndex, false); 321e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook setViewActivated(); 322f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 323f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 324f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 325f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 3260c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein private synchronized void notifyCursorListeners(Cursor data) { 3270c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein // tell all of the objects listening for cursor changes 3280c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein // that the cursor has changed 3290c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein for (CursorChangedListener listener : mCursorListeners) { 3300c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein listener.onCursorChanged(data); 3310c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 3320c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein } 3330c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein 334f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 335f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onLoaderReset(Loader<Cursor> loader) { 336e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // If the loader is reset, remove the reference in the adapter to this cursor 337e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // TODO(pwestbro): reenable this when b/7075236 is fixed 338e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook // mAdapter.swapCursor(null); 339f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 340f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 341f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 342f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 343f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 344f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 345f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 346f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPageSelected(int position) { 347f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mPhotoIndex = position; 348150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein setViewActivated(); 349f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 350f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 351f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 352f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public void onPageScrollStateChanged(int state) { 353f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 354f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 355f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public boolean isFragmentActive(Fragment fragment) { 356f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mViewPager == null || mAdapter == null) { 357f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return false; 358f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 359f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return mViewPager.getCurrentItem() == mAdapter.getItemPosition(fragment); 360f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 361f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 3620c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public void onFragmentVisible(PhotoViewFragment fragment) { 363150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein updateActionBar(fragment); 364f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 365f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 366f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein @Override 367f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public InterceptType onTouchIntercept(float origX, float origY) { 368f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein boolean interceptLeft = false; 369f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein boolean interceptRight = false; 370f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 371f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein for (OnScreenListener listener : mScreenListeners) { 372f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (!interceptLeft) { 373f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein interceptLeft = listener.onInterceptMoveLeft(origX, origY); 374f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 375f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (!interceptRight) { 376f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein interceptRight = listener.onInterceptMoveRight(origX, origY); 377f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 378f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein listener.onViewActivated(); 379f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 380f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 381f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (interceptLeft) { 382f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (interceptRight) { 383f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return InterceptType.BOTH; 384f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 385f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return InterceptType.LEFT; 386f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else if (interceptRight) { 387f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return InterceptType.RIGHT; 388f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 389f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return InterceptType.NONE; 390f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 391f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 392f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 393f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Updates the title bar according to the value of {@link #mFullScreen}. 394f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 3951abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein private void setFullScreen(boolean fullScreen, boolean setDelayedRunnable) { 396f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final boolean fullScreenChanged = (fullScreen != mFullScreen); 397f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein mFullScreen = fullScreen; 398f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 399f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mFullScreen) { 4001abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein setLightsOutMode(true); 401150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein cancelActionBarHideRunnable(); 402f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 4031abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein setLightsOutMode(false); 4041abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein if (setDelayedRunnable) { 405150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein postActionBarHideRunnableWithDelay(); 4061abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 407f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 408f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 409f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (fullScreenChanged) { 410f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein for (OnScreenListener listener : mScreenListeners) { 4111abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein listener.onFullScreenChanged(mFullScreen); 4121abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 4131abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 4141abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 4151abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein 416150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein private void postActionBarHideRunnableWithDelay() { 417e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mHandler.postDelayed(mActionBarHideRunnable, 418150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein mActionBarHideDelayTime); 419150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 420150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 421150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein private void cancelActionBarHideRunnable() { 422e6d03190d2b2ec6ea07a59daa7e687c3c383f9c3Paul Westbrook mHandler.removeCallbacks(mActionBarHideRunnable); 423150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 424150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 4251abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein private void setLightsOutMode(boolean enabled) { 4261abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 4271abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein int flags = enabled 4281abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein ? View.SYSTEM_UI_FLAG_LOW_PROFILE 4291abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein | View.SYSTEM_UI_FLAG_FULLSCREEN 4301abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 4311abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 4321abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein : View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 4331abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; 4341abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein 4351abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein // using mViewPager since we have it and we need a view 4361abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein mViewPager.setSystemUiVisibility(flags); 4371abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } else { 4381abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein final ActionBar actionBar = getActionBar(); 4391abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein if (enabled) { 4401abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein actionBar.hide(); 4411abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } else { 4421abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein actionBar.show(); 443f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 4441abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein int flags = enabled 4451abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein ? View.SYSTEM_UI_FLAG_LOW_PROFILE 4461abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein : View.SYSTEM_UI_FLAG_VISIBLE; 4471abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein mViewPager.setSystemUiVisibility(flags); 448f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 449f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 450f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 4511abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein private Runnable mActionBarHideRunnable = new Runnable() { 4521abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein @Override 4531abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein public void run() { 4541abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein PhotoViewActivity.this.setLightsOutMode(true); 4551abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein } 4561abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein }; 4571abd4654c2eeacc7d854a438a9c72d7239278beaAndrew Sapperstein 4580c18e5deef5209d21b527a01feb6b789715eb48eAndrew Sapperstein public void setViewActivated() { 459f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein for (OnScreenListener listener : mScreenListeners) { 460f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein listener.onViewActivated(); 461f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 462f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 463f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 464f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 465f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Adjusts the activity title and subtitle to reflect the photo name and count. 466f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 467150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein protected void updateActionBar(PhotoViewFragment fragment) { 468f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int position = mViewPager.getCurrentItem() + 1; 46968a16aa04f9b98868f4412e7324b0fc292c9d858Andrew Sapperstein final String title; 470f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final String subtitle; 471f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final boolean hasAlbumCount = mAlbumCount >= 0; 472f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 473f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final Cursor cursor = getCursorAtProperPosition(); 474f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 475f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (cursor != null) { 476f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int photoNameIndex = cursor.getColumnIndex(PhotoContract.PhotoViewColumns.NAME); 47768a16aa04f9b98868f4412e7324b0fc292c9d858Andrew Sapperstein title = cursor.getString(photoNameIndex); 47868a16aa04f9b98868f4412e7324b0fc292c9d858Andrew Sapperstein } else { 47968a16aa04f9b98868f4412e7324b0fc292c9d858Andrew Sapperstein title = null; 480f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 481f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 482f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mIsEmpty || !hasAlbumCount || position <= 0) { 483f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein subtitle = null; 484f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } else { 485f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein subtitle = getResources().getString(R.string.photo_view_count, position, mAlbumCount); 486f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 487f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 488f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final ActionBar actionBar = getActionBar(); 48968a16aa04f9b98868f4412e7324b0fc292c9d858Andrew Sapperstein actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE); 49068a16aa04f9b98868f4412e7324b0fc292c9d858Andrew Sapperstein actionBar.setTitle(title); 491f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein actionBar.setSubtitle(subtitle); 492f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 493f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 494f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein /** 495f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * Utility method that will return the cursor that contains the data 496f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * at the current position so that it refers to the current image on screen. 497f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * @return the cursor at the current position or 498f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein * null if no cursor exists or if the {@link PhotoViewPager} is null. 499f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein */ 500f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein public Cursor getCursorAtProperPosition() { 501f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (mViewPager == null) { 502f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return null; 503f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 504f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 505f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final int position = mViewPager.getCurrentItem(); 506f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein final Cursor cursor = mAdapter.getCursor(); 507f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 508f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein if (cursor == null) { 509f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return null; 510f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 511f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 512f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein cursor.moveToPosition(position); 513f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein 514f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein return cursor; 515f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein } 5169007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein 5179007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein public Cursor getCursor() { 5189007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein return (mAdapter == null) ? null : mAdapter.getCursor(); 5199007d640832f674a9d65058a3c2a484c078d239eAndrew Sapperstein } 520150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein 521150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein @Override 522150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein public void onMenuVisibilityChanged(boolean isVisible) { 523150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein if (isVisible) { 524150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein cancelActionBarHideRunnable(); 525150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } else { 526150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein postActionBarHideRunnableWithDelay(); 527150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 528150e623129eef49467f1d6f67649e4636a4513f2Andrew Sapperstein } 529f77a7eb196d16110c7b1087352b423913821ff61Andrew Sapperstein} 530