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.SuppressLint; 20 import android.app.ActionBar; 21 import android.content.Intent; 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.view.ViewPager; 28 import android.util.DisplayMetrics; 29 import android.view.Menu; 30 import android.view.MenuInflater; 31 import android.view.MenuItem; 32 import android.view.View; 33 import android.view.View.OnClickListener; 34 import android.view.ViewGroup; 35 import android.view.WindowManager.LayoutParams; 36 import android.widget.Toast; 37 38 import com.example.android.bitmapfun.R; 39 import com.example.android.bitmapfun.provider.Images; 40 import com.example.android.bitmapfun.util.DiskLruCache; 41 import com.example.android.bitmapfun.util.ImageCache; 42 import com.example.android.bitmapfun.util.ImageFetcher; 43 import com.example.android.bitmapfun.util.ImageResizer; 44 import com.example.android.bitmapfun.util.ImageWorker; 45 import com.example.android.bitmapfun.util.Utils; 46 47 public class ImageDetailActivity extends FragmentActivity implements OnClickListener { 48 private static final String IMAGE_CACHE_DIR = "images"; 49 public static final String EXTRA_IMAGE = "extra_image"; 50 51 private ImagePagerAdapter mAdapter; 52 private ImageResizer mImageWorker; 53 private ViewPager mPager; 54 55 @SuppressLint("NewApi") 56 @Override onCreate(Bundle savedInstanceState)57 public void onCreate(Bundle savedInstanceState) { 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 final int longest = height > width ? height : width; 68 69 // The ImageWorker takes care of loading images into our ImageView children asynchronously 70 mImageWorker = new ImageFetcher(this, longest); 71 mImageWorker.setAdapter(Images.imageWorkerUrlsAdapter); 72 mImageWorker.setImageCache(ImageCache.findOrCreateCache(this, IMAGE_CACHE_DIR)); 73 mImageWorker.setImageFadeIn(false); 74 75 // Set up ViewPager and backing adapter 76 mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), 77 mImageWorker.getAdapter().getSize()); 78 mPager = (ViewPager) findViewById(R.id.pager); 79 mPager.setAdapter(mAdapter); 80 mPager.setPageMargin((int) getResources().getDimension(R.dimen.image_detail_pager_margin)); 81 82 // Set up activity to go full screen 83 getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN); 84 85 // Enable some additional newer visibility and ActionBar features to create a more immersive 86 // photo viewing experience 87 if (Utils.hasActionBar()) { 88 final ActionBar actionBar = getActionBar(); 89 90 // Enable "up" navigation on ActionBar icon and hide title text 91 actionBar.setDisplayHomeAsUpEnabled(true); 92 actionBar.setDisplayShowTitleEnabled(false); 93 94 // Start low profile mode and hide ActionBar 95 mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); 96 actionBar.hide(); 97 98 // Hide and show the ActionBar as the visibility changes 99 mPager.setOnSystemUiVisibilityChangeListener( 100 new View.OnSystemUiVisibilityChangeListener() { 101 @Override 102 public void onSystemUiVisibilityChange(int vis) { 103 if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { 104 actionBar.hide(); 105 } else { 106 actionBar.show(); 107 } 108 } 109 }); 110 } 111 112 // Set the current item based on the extra passed in to this activity 113 final int extraCurrentItem = getIntent().getIntExtra(EXTRA_IMAGE, -1); 114 if (extraCurrentItem != -1) { 115 mPager.setCurrentItem(extraCurrentItem); 116 } 117 } 118 119 @Override onOptionsItemSelected(MenuItem item)120 public boolean onOptionsItemSelected(MenuItem item) { 121 switch (item.getItemId()) { 122 case android.R.id.home: 123 // Home or "up" navigation 124 final Intent intent = new Intent(this, ImageGridActivity.class); 125 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 126 startActivity(intent); 127 return true; 128 case R.id.clear_cache: 129 final ImageCache cache = mImageWorker.getImageCache(); 130 if (cache != null) { 131 mImageWorker.getImageCache().clearCaches(); 132 DiskLruCache.clearCache(this, ImageFetcher.HTTP_CACHE_DIR); 133 Toast.makeText(this, R.string.clear_cache_complete, 134 Toast.LENGTH_SHORT).show(); 135 } 136 return true; 137 } 138 return super.onOptionsItemSelected(item); 139 } 140 141 @Override onCreateOptionsMenu(Menu menu)142 public boolean onCreateOptionsMenu(Menu menu) { 143 MenuInflater inflater = getMenuInflater(); 144 inflater.inflate(R.menu.main_menu, menu); 145 return true; 146 } 147 148 /** 149 * Called by the ViewPager child fragments to load images via the one ImageWorker 150 * 151 * @return 152 */ getImageWorker()153 public ImageWorker getImageWorker() { 154 return mImageWorker; 155 } 156 157 /** 158 * The main adapter that backs the ViewPager. A subclass of FragmentStatePagerAdapter as there 159 * could be a large number of items in the ViewPager and we don't want to retain them all in 160 * memory at once but create/destroy them on the fly. 161 */ 162 private class ImagePagerAdapter extends FragmentStatePagerAdapter { 163 private final int mSize; 164 ImagePagerAdapter(FragmentManager fm, int size)165 public ImagePagerAdapter(FragmentManager fm, int size) { 166 super(fm); 167 mSize = size; 168 } 169 170 @Override getCount()171 public int getCount() { 172 return mSize; 173 } 174 175 @Override getItem(int position)176 public Fragment getItem(int position) { 177 return ImageDetailFragment.newInstance(position); 178 } 179 180 @Override destroyItem(ViewGroup container, int position, Object object)181 public void destroyItem(ViewGroup container, int position, Object object) { 182 final ImageDetailFragment fragment = (ImageDetailFragment) object; 183 // As the item gets destroyed we try and cancel any existing work. 184 fragment.cancelWork(); 185 super.destroyItem(container, position, object); 186 } 187 } 188 189 /** 190 * Set on the ImageView in the ViewPager children fragments, to enable/disable low profile mode 191 * when the ImageView is touched. 192 */ 193 @SuppressLint("NewApi") 194 @Override onClick(View v)195 public void onClick(View v) { 196 final int vis = mPager.getSystemUiVisibility(); 197 if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { 198 mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 199 } else { 200 mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); 201 } 202 } 203 } 204