1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.bitmapfun.ui; 18 19 import android.annotation.TargetApi; 20 import android.app.ActionBar; 21 import android.os.Bundle; 22 import android.support.v4.app.Fragment; 23 import android.support.v4.app.FragmentActivity; 24 import android.support.v4.app.FragmentManager; 25 import android.support.v4.app.FragmentStatePagerAdapter; 26 import android.support.v4.app.NavUtils; 27 import android.support.v4.view.ViewPager; 28 import android.util.DisplayMetrics; 29 import android.view.Menu; 30 import android.view.MenuItem; 31 import android.view.View; 32 import android.view.View.OnClickListener; 33 import android.view.WindowManager.LayoutParams; 34 import android.widget.Toast; 35 36 import com.example.android.bitmapfun.BuildConfig; 37 import com.example.android.bitmapfun.R; 38 import com.example.android.bitmapfun.provider.Images; 39 import com.example.android.bitmapfun.util.ImageCache; 40 import com.example.android.bitmapfun.util.ImageFetcher; 41 import com.example.android.bitmapfun.util.Utils; 42 43 public class ImageDetailActivity extends FragmentActivity implements OnClickListener { 44 private static final String IMAGE_CACHE_DIR = "images"; 45 public static final String EXTRA_IMAGE = "extra_image"; 46 47 private ImagePagerAdapter mAdapter; 48 private ImageFetcher mImageFetcher; 49 private ViewPager mPager; 50 51 @TargetApi(11) 52 @Override onCreate(Bundle savedInstanceState)53 public void onCreate(Bundle savedInstanceState) { 54 if (BuildConfig.DEBUG) { 55 Utils.enableStrictMode(); 56 } 57 super.onCreate(savedInstanceState); 58 setContentView(R.layout.image_detail_pager); 59 60 // Fetch screen height and width, to use as our max size when loading images as this 61 // activity runs full screen 62 final DisplayMetrics displayMetrics = new DisplayMetrics(); 63 getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); 64 final int height = displayMetrics.heightPixels; 65 final int width = displayMetrics.widthPixels; 66 67 // For this sample we'll use half of the longest width to resize our images. As the 68 // image scaling ensures the image is larger than this, we should be left with a 69 // resolution that is appropriate for both portrait and landscape. For best image quality 70 // we shouldn't divide by 2, but this will use more memory and require a larger memory 71 // cache. 72 final int longest = (height > width ? height : width) / 2; 73 74 ImageCache.ImageCacheParams cacheParams = 75 new ImageCache.ImageCacheParams(this, IMAGE_CACHE_DIR); 76 cacheParams.setMemCacheSizePercent(0.25f); // Set memory cache to 25% of app memory 77 78 // The ImageFetcher takes care of loading images into our ImageView children asynchronously 79 mImageFetcher = new ImageFetcher(this, longest); 80 mImageFetcher.addImageCache(getSupportFragmentManager(), cacheParams); 81 mImageFetcher.setImageFadeIn(false); 82 83 // Set up ViewPager and backing adapter 84 mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), Images.imageUrls.length); 85 mPager = (ViewPager) findViewById(R.id.pager); 86 mPager.setAdapter(mAdapter); 87 mPager.setPageMargin((int) getResources().getDimension(R.dimen.image_detail_pager_margin)); 88 mPager.setOffscreenPageLimit(2); 89 90 // Set up activity to go full screen 91 getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN); 92 93 // Enable some additional newer visibility and ActionBar features to create a more 94 // immersive photo viewing experience 95 if (Utils.hasHoneycomb()) { 96 final ActionBar actionBar = getActionBar(); 97 98 // Hide title text and set home as up 99 actionBar.setDisplayShowTitleEnabled(false); 100 actionBar.setDisplayHomeAsUpEnabled(true); 101 102 // Hide and show the ActionBar as the visibility changes 103 mPager.setOnSystemUiVisibilityChangeListener( 104 new View.OnSystemUiVisibilityChangeListener() { 105 @Override 106 public void onSystemUiVisibilityChange(int vis) { 107 if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { 108 actionBar.hide(); 109 } else { 110 actionBar.show(); 111 } 112 } 113 }); 114 115 // Start low profile mode and hide ActionBar 116 mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); 117 actionBar.hide(); 118 } 119 120 // Set the current item based on the extra passed in to this activity 121 final int extraCurrentItem = getIntent().getIntExtra(EXTRA_IMAGE, -1); 122 if (extraCurrentItem != -1) { 123 mPager.setCurrentItem(extraCurrentItem); 124 } 125 } 126 127 @Override onResume()128 public void onResume() { 129 super.onResume(); 130 mImageFetcher.setExitTasksEarly(false); 131 } 132 133 @Override onPause()134 protected void onPause() { 135 super.onPause(); 136 mImageFetcher.setExitTasksEarly(true); 137 mImageFetcher.flushCache(); 138 } 139 140 @Override onDestroy()141 protected void onDestroy() { 142 super.onDestroy(); 143 mImageFetcher.closeCache(); 144 } 145 146 @Override onOptionsItemSelected(MenuItem item)147 public boolean onOptionsItemSelected(MenuItem item) { 148 switch (item.getItemId()) { 149 case android.R.id.home: 150 NavUtils.navigateUpFromSameTask(this); 151 return true; 152 case R.id.clear_cache: 153 mImageFetcher.clearCache(); 154 Toast.makeText( 155 this, R.string.clear_cache_complete_toast,Toast.LENGTH_SHORT).show(); 156 return true; 157 } 158 return super.onOptionsItemSelected(item); 159 } 160 161 @Override onCreateOptionsMenu(Menu menu)162 public boolean onCreateOptionsMenu(Menu menu) { 163 getMenuInflater().inflate(R.menu.main_menu, menu); 164 return true; 165 } 166 167 /** 168 * Called by the ViewPager child fragments to load images via the one ImageFetcher 169 */ getImageFetcher()170 public ImageFetcher getImageFetcher() { 171 return mImageFetcher; 172 } 173 174 /** 175 * The main adapter that backs the ViewPager. A subclass of FragmentStatePagerAdapter as there 176 * could be a large number of items in the ViewPager and we don't want to retain them all in 177 * memory at once but create/destroy them on the fly. 178 */ 179 private class ImagePagerAdapter extends FragmentStatePagerAdapter { 180 private final int mSize; 181 ImagePagerAdapter(FragmentManager fm, int size)182 public ImagePagerAdapter(FragmentManager fm, int size) { 183 super(fm); 184 mSize = size; 185 } 186 187 @Override getCount()188 public int getCount() { 189 return mSize; 190 } 191 192 @Override getItem(int position)193 public Fragment getItem(int position) { 194 return ImageDetailFragment.newInstance(Images.imageUrls[position]); 195 } 196 } 197 198 /** 199 * Set on the ImageView in the ViewPager children fragments, to enable/disable low profile mode 200 * when the ImageView is touched. 201 */ 202 @TargetApi(11) 203 @Override onClick(View v)204 public void onClick(View v) { 205 final int vis = mPager.getSystemUiVisibility(); 206 if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { 207 mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 208 } else { 209 mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); 210 } 211 } 212 } 213