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