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