PreviewImagePagerAdapter.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /* ownCloud Android client application
  2. * Copyright (C) 2012-2013 ownCloud Inc.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. package com.owncloud.android.ui.preview;
  18. import java.util.HashMap;
  19. import java.util.HashSet;
  20. import java.util.Map;
  21. import java.util.Set;
  22. import java.util.Vector;
  23. import com.owncloud.android.datamodel.OCFile;
  24. import com.owncloud.android.ui.fragment.FileFragment;
  25. import android.accounts.Account;
  26. import android.support.v4.app.Fragment;
  27. import android.support.v4.app.FragmentManager;
  28. import android.support.v4.app.FragmentStatePagerAdapter;
  29. import android.view.ViewGroup;
  30. import com.owncloud.android.datamodel.FileDataStorageManager;
  31. /**
  32. * Adapter class that provides Fragment instances
  33. *
  34. * @author David A. Velasco
  35. */
  36. //public class PreviewImagePagerAdapter extends PagerAdapter {
  37. public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
  38. private Vector<OCFile> mImageFiles;
  39. private Account mAccount;
  40. private Set<Object> mObsoleteFragments;
  41. private Set<Integer> mObsoletePositions;
  42. private Set<Integer> mDownloadErrors;
  43. private FileDataStorageManager mStorageManager;
  44. private Map<Integer, FileFragment> mCachedFragments;
  45. /**
  46. * Constructor.
  47. *
  48. * @param fragmentManager {@link FragmentManager} instance that will handle the {@link Fragment}s provided by the adapter.
  49. * @param parentFolder Folder where images will be searched for.
  50. * @param storageManager Bridge to database.
  51. */
  52. public PreviewImagePagerAdapter(FragmentManager fragmentManager, OCFile parentFolder, Account account, FileDataStorageManager storageManager) {
  53. super(fragmentManager);
  54. if (fragmentManager == null) {
  55. throw new IllegalArgumentException("NULL FragmentManager instance");
  56. }
  57. if (parentFolder == null) {
  58. throw new IllegalArgumentException("NULL parent folder");
  59. }
  60. if (storageManager == null) {
  61. throw new IllegalArgumentException("NULL storage manager");
  62. }
  63. mAccount = account;
  64. mStorageManager = storageManager;
  65. mImageFiles = mStorageManager.getFolderImages(parentFolder);
  66. mObsoleteFragments = new HashSet<Object>();
  67. mObsoletePositions = new HashSet<Integer>();
  68. mDownloadErrors = new HashSet<Integer>();
  69. //mFragmentManager = fragmentManager;
  70. mCachedFragments = new HashMap<Integer, FileFragment>();
  71. }
  72. /**
  73. * Returns the image files handled by the adapter.
  74. *
  75. * @return A vector with the image files handled by the adapter.
  76. */
  77. protected OCFile getFileAt(int position) {
  78. return mImageFiles.get(position);
  79. }
  80. public Fragment getItem(int i) {
  81. OCFile file = mImageFiles.get(i);
  82. Fragment fragment = null;
  83. if (file.isDown()) {
  84. fragment = new PreviewImageFragment(file, mAccount, mObsoletePositions.contains(Integer.valueOf(i)));
  85. } else if (mDownloadErrors.contains(Integer.valueOf(i))) {
  86. fragment = new FileDownloadFragment(file, mAccount, true);
  87. ((FileDownloadFragment)fragment).setError(true);
  88. mDownloadErrors.remove(Integer.valueOf(i));
  89. } else {
  90. fragment = new FileDownloadFragment(file, mAccount, mObsoletePositions.contains(Integer.valueOf(i)));
  91. }
  92. mObsoletePositions.remove(Integer.valueOf(i));
  93. return fragment;
  94. }
  95. public int getFilePosition(OCFile file) {
  96. return mImageFiles.indexOf(file);
  97. }
  98. @Override
  99. public int getCount() {
  100. return mImageFiles.size();
  101. }
  102. @Override
  103. public CharSequence getPageTitle(int position) {
  104. return mImageFiles.get(position).getFileName();
  105. }
  106. public void updateFile(int position, OCFile file) {
  107. FileFragment fragmentToUpdate = mCachedFragments.get(Integer.valueOf(position));
  108. if (fragmentToUpdate != null) {
  109. mObsoleteFragments.add(fragmentToUpdate);
  110. }
  111. mObsoletePositions.add(Integer.valueOf(position));
  112. mImageFiles.set(position, file);
  113. }
  114. public void updateWithDownloadError(int position) {
  115. FileFragment fragmentToUpdate = mCachedFragments.get(Integer.valueOf(position));
  116. if (fragmentToUpdate != null) {
  117. mObsoleteFragments.add(fragmentToUpdate);
  118. }
  119. mDownloadErrors.add(Integer.valueOf(position));
  120. }
  121. public void clearErrorAt(int position) {
  122. FileFragment fragmentToUpdate = mCachedFragments.get(Integer.valueOf(position));
  123. if (fragmentToUpdate != null) {
  124. mObsoleteFragments.add(fragmentToUpdate);
  125. }
  126. mDownloadErrors.remove(Integer.valueOf(position));
  127. }
  128. @Override
  129. public int getItemPosition(Object object) {
  130. if (mObsoleteFragments.contains(object)) {
  131. mObsoleteFragments.remove(object);
  132. return POSITION_NONE;
  133. }
  134. return super.getItemPosition(object);
  135. }
  136. @Override
  137. public Object instantiateItem(ViewGroup container, int position) {
  138. Object fragment = super.instantiateItem(container, position);
  139. mCachedFragments.put(Integer.valueOf(position), (FileFragment)fragment);
  140. return fragment;
  141. }
  142. @Override
  143. public void destroyItem(ViewGroup container, int position, Object object) {
  144. mCachedFragments.remove(Integer.valueOf(position));
  145. super.destroyItem(container, position, object);
  146. }
  147. public boolean pendingErrorAt(int position) {
  148. return mDownloadErrors.contains(Integer.valueOf(position));
  149. }
  150. /* -*
  151. * Called when a change in the shown pages is going to start being made.
  152. *
  153. * @param container The containing View which is displaying this adapter's page views.
  154. *- /
  155. @Override
  156. public void startUpdate(ViewGroup container) {
  157. Log.e(TAG, "** startUpdate");
  158. }
  159. @Override
  160. public Object instantiateItem(ViewGroup container, int position) {
  161. Log.e(TAG, "** instantiateItem " + position);
  162. if (mFragments.size() > position) {
  163. Fragment fragment = mFragments.get(position);
  164. if (fragment != null) {
  165. Log.e(TAG, "** \t returning cached item");
  166. return fragment;
  167. }
  168. }
  169. if (mCurTransaction == null) {
  170. mCurTransaction = mFragmentManager.beginTransaction();
  171. }
  172. Fragment fragment = getItem(position);
  173. if (mSavedState.size() > position) {
  174. Fragment.SavedState savedState = mSavedState.get(position);
  175. if (savedState != null) {
  176. // TODO WATCH OUT:
  177. // * The Fragment must currently be attached to the FragmentManager.
  178. // * A new Fragment created using this saved state must be the same class type as the Fragment it was created from.
  179. // * The saved state can not contain dependencies on other fragments -- that is it can't use putFragment(Bundle, String, Fragment)
  180. // to store a fragment reference
  181. fragment.setInitialSavedState(savedState);
  182. }
  183. }
  184. while (mFragments.size() <= position) {
  185. mFragments.add(null);
  186. }
  187. fragment.setMenuVisibility(false);
  188. mFragments.set(position, fragment);
  189. //Log.e(TAG, "** \t adding fragment at position " + position + ", containerId " + container.getId());
  190. mCurTransaction.add(container.getId(), fragment);
  191. return fragment;
  192. }
  193. @Override
  194. public void destroyItem(ViewGroup container, int position, Object object) {
  195. Log.e(TAG, "** destroyItem " + position);
  196. Fragment fragment = (Fragment)object;
  197. if (mCurTransaction == null) {
  198. mCurTransaction = mFragmentManager.beginTransaction();
  199. }
  200. Log.e(TAG, "** \t removing fragment at position " + position);
  201. while (mSavedState.size() <= position) {
  202. mSavedState.add(null);
  203. }
  204. mSavedState.set(position, mFragmentManager.saveFragmentInstanceState(fragment));
  205. mFragments.set(position, null);
  206. mCurTransaction.remove(fragment);
  207. }
  208. @Override
  209. public void setPrimaryItem(ViewGroup container, int position, Object object) {
  210. Fragment fragment = (Fragment)object;
  211. if (fragment != mCurrentPrimaryItem) {
  212. if (mCurrentPrimaryItem != null) {
  213. mCurrentPrimaryItem.setMenuVisibility(false);
  214. }
  215. if (fragment != null) {
  216. fragment.setMenuVisibility(true);
  217. }
  218. mCurrentPrimaryItem = fragment;
  219. }
  220. }
  221. @Override
  222. public void finishUpdate(ViewGroup container) {
  223. Log.e(TAG, "** finishUpdate (start)");
  224. if (mCurTransaction != null) {
  225. mCurTransaction.commitAllowingStateLoss();
  226. mCurTransaction = null;
  227. mFragmentManager.executePendingTransactions();
  228. }
  229. Log.e(TAG, "** finishUpdate (end)");
  230. }
  231. @Override
  232. public boolean isViewFromObject(View view, Object object) {
  233. return ((Fragment)object).getView() == view;
  234. }
  235. @Override
  236. public Parcelable saveState() {
  237. Bundle state = null;
  238. if (mSavedState.size() > 0) {
  239. state = new Bundle();
  240. Fragment.SavedState[] savedStates = new Fragment.SavedState[mSavedState.size()];
  241. mSavedState.toArray(savedStates);
  242. state.putParcelableArray("states", savedStates);
  243. }
  244. for (int i=0; i<mFragments.size(); i++) {
  245. Fragment fragment = mFragments.get(i);
  246. if (fragment != null) {
  247. if (state == null) {
  248. state = new Bundle();
  249. }
  250. String key = "f" + i;
  251. mFragmentManager.putFragment(state, key, fragment);
  252. }
  253. }
  254. return state;
  255. }
  256. @Override
  257. public void restoreState(Parcelable state, ClassLoader loader) {
  258. if (state != null) {
  259. Bundle bundle = (Bundle)state;
  260. bundle.setClassLoader(loader);
  261. Parcelable[] states = bundle.getParcelableArray("states");
  262. mSavedState.clear();
  263. mFragments.clear();
  264. if (states != null) {
  265. for (int i=0; i<states.length; i++) {
  266. mSavedState.add((Fragment.SavedState)states[i]);
  267. }
  268. }
  269. Iterable<String> keys = bundle.keySet();
  270. for (String key: keys) {
  271. if (key.startsWith("f")) {
  272. int index = Integer.parseInt(key.substring(1));
  273. Fragment f = mFragmentManager.getFragment(bundle, key);
  274. if (f != null) {
  275. while (mFragments.size() <= index) {
  276. mFragments.add(null);
  277. }
  278. f.setMenuVisibility(false);
  279. mFragments.set(index, f);
  280. } else {
  281. Log.w(TAG, "Bad fragment at key " + key);
  282. }
  283. }
  284. }
  285. }
  286. }
  287. */
  288. }