+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <GridView
- android:id="@id/android:list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:numColumns="auto_fit"
- android:columnWidth="@dimen/album_set_item_width"
- android:stretchMode="columnWidth"
- android:drawSelectorOnTop="true"
- android:background="#E5E5E5"
- android:paddingLeft="10dp"
- android:paddingRight="10dp"
- android:horizontalSpacing="6dp"
- android:verticalSpacing="6dp" />
-
- <TextView
- android:id="@id/android:empty"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:text="@string/empty_album" />
-
-</FrameLayout>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout android:id="@+id/progressContainer"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:gravity="center">
+
+ <ProgressBar style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/loading"
+ android:paddingTop="4dip"
+ android:singleLine="true" />
+
+ </LinearLayout>
+
+ <FrameLayout android:id="@+id/gridContainer"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <GridView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:choiceMode="multipleChoiceModal"
+ android:numColumns="auto_fit"
+ android:stretchMode="columnWidth"
+ android:drawSelectorOnTop="true" />
+ <TextView android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+ </FrameLayout>
+
+</FrameLayout>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingLeft="4dip"
- android:paddingRight="4dip">
-
- <GridView
- android:id="@id/android:list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:drawSelectorOnTop="true"
- android:numColumns="auto_fit"
- android:stretchMode="columnWidth"
- android:columnWidth="200dip"
- android:horizontalSpacing="1dip"
- android:verticalSpacing="1dip" />
-
- <TextView
- android:id="@id/android:empty"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:text="@string/empty_album" />
-
-</FrameLayout>
\ No newline at end of file
import android.app.Activity;
import android.os.Bundle;
-public class AlbumActivity extends Activity implements GalleryFragmentHost {
+public class AlbumActivity extends Activity implements MultiChoiceManager.Provider {
public static final String KEY_ALBUM_URI = AlbumFragment.KEY_ALBUM_URI;
public static final String KEY_ALBUM_TITLE = "AlbumTitle";
package com.android.photos;
-import android.app.Activity;
-import android.app.Fragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
-import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
-import com.android.gallery3d.R;
import com.android.gallery3d.app.Gallery;
import com.android.photos.adapters.PhotoThumbnailAdapter;
import com.android.photos.data.PhotoSetLoader;
import java.util.ArrayList;
-public class AlbumFragment extends Fragment implements OnItemClickListener,
- LoaderCallbacks<Cursor>, MultiChoiceManager.Delegate {
+public class AlbumFragment extends MultiSelectGridFragment implements LoaderCallbacks<Cursor> {
protected static final String KEY_ALBUM_URI = "AlbumUri";
private static final int LOADER_ALBUM = 1;
- private GridView mAlbumView;
- private View mEmptyView;
-
- private boolean mInitialLoadComplete = false;
private LoaderCompatShim<Cursor> mLoaderCompatShim;
private PhotoThumbnailAdapter mAdapter;
private String mAlbumPath;
- private GalleryFragmentHost mHost;
@Override
public void onCreate(Bundle savedInstanceState) {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View root = inflater.inflate(R.layout.photo_set, container, false);
- mAlbumView = (GridView) root.findViewById(android.R.id.list);
- // TODO: Remove once UI stabilizes
- mAlbumView.setColumnWidth(MediaItemsLoader.getThumbnailSize());
- mAlbumView.setOnItemClickListener(this);
- mEmptyView = root.findViewById(android.R.id.empty);
- mEmptyView.setVisibility(View.GONE);
- mAlbumView.setAdapter(mAdapter);
- mAlbumView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
- mAlbumView.setMultiChoiceModeListener(mHost.getMultiChoiceManager());
+ View root = super.onCreateView(inflater, container, savedInstanceState);
getLoaderManager().initLoader(LOADER_ALBUM, null, this);
- updateEmptyStatus();
return root;
}
- private void updateEmptyStatus() {
- boolean empty = (mAdapter == null || mAdapter.getCount() == 0);
- mAlbumView.setVisibility(empty ? View.GONE : View.VISIBLE);
- mEmptyView.setVisibility(empty && mInitialLoadComplete
- ? View.VISIBLE : View.GONE);
- }
-
@Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- mHost = (GalleryFragmentHost) activity;
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- mHost = null;
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ // TODO: Remove once UI stabilizes
+ getGridView().setColumnWidth(MediaItemsLoader.getThumbnailSize());
}
@Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
+ public void onGridItemClick(GridView g, View v, int position, long id) {
if (mLoaderCompatShim == null) {
// Not fully initialized yet, discard
return;
}
- Cursor item = mAdapter.getItem(position);
+ Cursor item = (Cursor) getItemAtPosition(position);
Uri uri = mLoaderCompatShim.uriForItem(item);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setClass(getActivity(), Gallery.class);
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// TODO: Switch to PhotoSetLoader
MediaItemsLoader loader = new MediaItemsLoader(getActivity(), mAlbumPath);
- mInitialLoadComplete = false;
mLoaderCompatShim = loader;
mAdapter.setDrawableFactory(mLoaderCompatShim);
return loader;
public void onLoadFinished(Loader<Cursor> loader,
Cursor data) {
mAdapter.swapCursor(data);
- mInitialLoadComplete = true;
- updateEmptyStatus();
+ setAdapter(mAdapter);
}
@Override
return ((Cursor) item).getInt(PhotoSetLoader.INDEX_SUPPORTED_OPERATIONS);
}
- @Override
- public Object getItemAtPosition(int position) {
- return mAdapter.getItem(position);
- }
-
private ArrayList<Uri> mSubItemUriTemp = new ArrayList<Uri>(1);
@Override
public ArrayList<Uri> getSubItemUrisForItem(Object item) {
return mSubItemUriTemp;
}
-
- @Override
- public Object getPathForItemAtPosition(int position) {
- return mLoaderCompatShim.getPathForItem(mAdapter.getItem(position));
- }
-
@Override
public void deleteItemWithPath(Object itemPath) {
mLoaderCompatShim.deleteItemWithPath(itemPath);
}
@Override
- public SparseBooleanArray getSelectedItemPositions() {
- return mAlbumView.getCheckedItemPositions();
- }
-
- @Override
- public int getSelectedItemCount() {
- return mAlbumView.getCheckedItemCount();
+ public Uri getItemUri(Object item) {
+ return mLoaderCompatShim.uriForItem((Cursor) item);
}
@Override
- public Uri getItemUri(Object item) {
- return mLoaderCompatShim.uriForItem((Cursor) item);
+ public Object getPathForItem(Object item) {
+ return mLoaderCompatShim.getPathForItem((Cursor) item);
}
}
package com.android.photos;
-import android.app.Activity;
-import android.app.Fragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore.Files.FileColumns;
-import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import com.android.gallery3d.R;
import java.util.ArrayList;
-public class AlbumSetFragment extends Fragment implements OnItemClickListener,
- LoaderCallbacks<Cursor>, MultiChoiceManager.Delegate {
+public class AlbumSetFragment extends MultiSelectGridFragment implements LoaderCallbacks<Cursor> {
- private GridView mAlbumSetView;
- private View mEmptyView;
private AlbumSetCursorAdapter mAdapter;
private LoaderCompatShim<Cursor> mLoaderCompatShim;
- private GalleryFragmentHost mHost;
private static final int LOADER_ALBUMSET = 1;
}
@Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- mHost = (GalleryFragmentHost) activity;
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- mHost = null;
- }
-
- @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View root = inflater.inflate(R.layout.album_set, container, false);
- mAlbumSetView = (GridView) root.findViewById(android.R.id.list);
- mEmptyView = root.findViewById(android.R.id.empty);
- mEmptyView.setVisibility(View.GONE);
- mAlbumSetView.setAdapter(mAdapter);
- mAlbumSetView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
- mAlbumSetView.setMultiChoiceModeListener(mHost.getMultiChoiceManager());
- mAlbumSetView.setOnItemClickListener(this);
+ View root = super.onCreateView(inflater, container, savedInstanceState);
getLoaderManager().initLoader(LOADER_ALBUMSET, null, this);
- updateEmptyStatus();
return root;
}
@Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ getGridView().setColumnWidth(getActivity().getResources()
+ .getDimensionPixelSize(R.dimen.album_set_item_width));
+ }
+
+ @Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// TODO: Switch to AlbumSetLoader
MediaSetLoader loader = new MediaSetLoader(getActivity());
public void onLoadFinished(Loader<Cursor> loader,
Cursor data) {
mAdapter.swapCursor(data);
- updateEmptyStatus();
- }
-
- private void updateEmptyStatus() {
- boolean empty = (mAdapter == null || mAdapter.getCount() == 0);
- mAlbumSetView.setVisibility(empty ? View.GONE : View.VISIBLE);
- mEmptyView.setVisibility(empty ? View.VISIBLE : View.GONE);
+ setAdapter(mAdapter);
}
@Override
}
@Override
- public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
+ public void onGridItemClick(GridView g, View v, int position, long id) {
if (mLoaderCompatShim == null) {
// Not fully initialized yet, discard
return;
}
- Cursor item = (Cursor) mAdapter.getItem(pos);
+ Cursor item = (Cursor) getItemAtPosition(position);
Context context = getActivity();
Intent intent = new Intent(context, AlbumActivity.class);
intent.putExtra(AlbumActivity.KEY_ALBUM_URI,
}
@Override
- public Object getItemAtPosition(int position) {
- return mAdapter.getItem(position);
- }
-
- @Override
public ArrayList<Uri> getSubItemUrisForItem(Object item) {
return mLoaderCompatShim.urisForSubItems((Cursor) item);
}
@Override
- public Object getPathForItemAtPosition(int position) {
- return mLoaderCompatShim.getPathForItem((Cursor) mAdapter.getItem(position));
- }
-
- @Override
public void deleteItemWithPath(Object itemPath) {
mLoaderCompatShim.deleteItemWithPath(itemPath);
}
@Override
- public SparseBooleanArray getSelectedItemPositions() {
- return mAlbumSetView.getCheckedItemPositions();
- }
-
- @Override
- public int getSelectedItemCount() {
- return mAlbumSetView.getCheckedItemCount();
+ public Uri getItemUri(Object item) {
+ return mLoaderCompatShim.uriForItem((Cursor) item);
}
@Override
- public Uri getItemUri(Object item) {
- return mLoaderCompatShim.uriForItem((Cursor) item);
+ public Object getPathForItem(Object item) {
+ return mLoaderCompatShim.getPathForItem((Cursor) item);
}
}
import java.util.ArrayList;
-public class GalleryActivity extends Activity implements GalleryFragmentHost {
+public class GalleryActivity extends Activity implements MultiChoiceManager.Provider {
private MultiChoiceManager mMultiChoiceManager;
private ViewPager mViewPager;
+++ /dev/null
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.photos;
-
-public interface GalleryFragmentHost {
- public MultiChoiceManager getMultiChoiceManager();
-}
public class MultiChoiceManager implements MultiChoiceModeListener,
OnShareTargetSelectedListener, SelectionManager.SelectedUriSource {
+ public interface Provider {
+ public MultiChoiceManager getMultiChoiceManager();
+ }
+
public interface Delegate {
public SparseBooleanArray getSelectedItemPositions();
public int getSelectedItemCount();
--- /dev/null
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.photos;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.SparseBooleanArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
+import android.widget.AdapterView;
+import android.widget.GridView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import com.android.gallery3d.R;
+
+import java.util.ArrayList;
+
+public abstract class MultiSelectGridFragment extends Fragment
+ implements MultiChoiceManager.Delegate, AdapterView.OnItemClickListener {
+
+ final private Handler mHandler = new Handler();
+
+ final private Runnable mRequestFocus = new Runnable() {
+ public void run() {
+ mGrid.focusableViewAvailable(mGrid);
+ }
+ };
+
+ ListAdapter mAdapter;
+ GridView mGrid;
+ TextView mEmptyView;
+ View mProgressContainer;
+ View mGridContainer;
+ CharSequence mEmptyText;
+ boolean mGridShown;
+ MultiChoiceManager.Provider mHost;
+
+ public MultiSelectGridFragment() {
+ }
+
+ /**
+ * Provide default implementation to return a simple grid view. Subclasses
+ * can override to replace with their own layout. If doing so, the returned
+ * view hierarchy <em>must</em> have a GridView whose id is
+ * {@link android.R.id#grid android.R.id.list} and can optionally have a
+ * sibling text view id {@link android.R.id#empty android.R.id.empty} that
+ * is to be shown when the grid is empty.
+ * <p>
+ * If you are overriding this method with your own custom content, consider
+ * including the standard layout R.layout.multigrid_content in your layout
+ * file, so that you continue to retain all of the standard behavior of
+ * MultiSelectGridFragment. In particular, this is currently the only way to
+ * have the built-in indeterminate progress state be shown.
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.multigrid_content, container, false);
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ mHost = (MultiChoiceManager.Provider) activity;
+ if (mGrid != null) {
+ mGrid.setMultiChoiceModeListener(mHost.getMultiChoiceManager());
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mHost = null;
+ }
+
+ /**
+ * Attach to grid view once the view hierarchy has been created.
+ */
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ ensureGrid();
+ }
+
+ /**
+ * Detach from grid view.
+ */
+ @Override
+ public void onDestroyView() {
+ mHandler.removeCallbacks(mRequestFocus);
+ mGrid = null;
+ mGridShown = false;
+ mEmptyView = null;
+ mProgressContainer = mGridContainer = null;
+ super.onDestroyView();
+ }
+
+ /**
+ * This method will be called when an item in the grid is selected.
+ * Subclasses should override. Subclasses can call
+ * getGridView().getItemAtPosition(position) if they need to access the data
+ * associated with the selected item.
+ *
+ * @param g The GridView where the click happened
+ * @param v The view that was clicked within the GridView
+ * @param position The position of the view in the grid
+ * @param id The id of the item that was clicked
+ */
+ public void onGridItemClick(GridView g, View v, int position, long id) {
+ }
+
+ /**
+ * Provide the cursor for the grid view.
+ */
+ public void setAdapter(ListAdapter adapter) {
+ boolean hadAdapter = mAdapter != null;
+ mAdapter = adapter;
+ if (mGrid != null) {
+ mGrid.setAdapter(adapter);
+ if (!mGridShown && !hadAdapter) {
+ // The grid was hidden, and previously didn't have an
+ // adapter. It is now time to show it.
+ setGridShown(true, getView().getWindowToken() != null);
+ }
+ }
+ }
+
+ /**
+ * Set the currently selected grid item to the specified position with the
+ * adapter's data
+ *
+ * @param position
+ */
+ public void setSelection(int position) {
+ ensureGrid();
+ mGrid.setSelection(position);
+ }
+
+ /**
+ * Get the position of the currently selected grid item.
+ */
+ public int getSelectedItemPosition() {
+ ensureGrid();
+ return mGrid.getSelectedItemPosition();
+ }
+
+ /**
+ * Get the cursor row ID of the currently selected grid item.
+ */
+ public long getSelectedItemId() {
+ ensureGrid();
+ return mGrid.getSelectedItemId();
+ }
+
+ /**
+ * Get the activity's grid view widget.
+ */
+ public GridView getGridView() {
+ ensureGrid();
+ return mGrid;
+ }
+
+ /**
+ * The default content for a MultiSelectGridFragment has a TextView that can
+ * be shown when the grid is empty. If you would like to have it shown, call
+ * this method to supply the text it should use.
+ */
+ public void setEmptyText(CharSequence text) {
+ ensureGrid();
+ if (mEmptyView == null) {
+ return;
+ }
+ mEmptyView.setText(text);
+ if (mEmptyText == null) {
+ mGrid.setEmptyView(mEmptyView);
+ }
+ mEmptyText = text;
+ }
+
+ /**
+ * Control whether the grid is being displayed. You can make it not
+ * displayed if you are waiting for the initial data to show in it. During
+ * this time an indeterminate progress indicator will be shown instead.
+ * <p>
+ * Applications do not normally need to use this themselves. The default
+ * behavior of MultiSelectGridFragment is to start with the grid not being
+ * shown, only showing it once an adapter is given with
+ * {@link #setAdapter(ListAdapter)}. If the grid at that point had not been
+ * shown, when it does get shown it will be do without the user ever seeing
+ * the hidden state.
+ *
+ * @param shown If true, the grid view is shown; if false, the progress
+ * indicator. The initial value is true.
+ */
+ public void setGridShown(boolean shown) {
+ setGridShown(shown, true);
+ }
+
+ /**
+ * Like {@link #setGridShown(boolean)}, but no animation is used when
+ * transitioning from the previous state.
+ */
+ public void setGridShownNoAnimation(boolean shown) {
+ setGridShown(shown, false);
+ }
+
+ /**
+ * Control whether the grid is being displayed. You can make it not
+ * displayed if you are waiting for the initial data to show in it. During
+ * this time an indeterminate progress indicator will be shown instead.
+ *
+ * @param shown If true, the grid view is shown; if false, the progress
+ * indicator. The initial value is true.
+ * @param animate If true, an animation will be used to transition to the
+ * new state.
+ */
+ private void setGridShown(boolean shown, boolean animate) {
+ ensureGrid();
+ if (mProgressContainer == null) {
+ throw new IllegalStateException("Can't be used with a custom content view");
+ }
+ if (mGridShown == shown) {
+ return;
+ }
+ mGridShown = shown;
+ if (shown) {
+ if (animate) {
+ mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_out));
+ mGridContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_in));
+ } else {
+ mProgressContainer.clearAnimation();
+ mGridContainer.clearAnimation();
+ }
+ mProgressContainer.setVisibility(View.GONE);
+ mGridContainer.setVisibility(View.VISIBLE);
+ } else {
+ if (animate) {
+ mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_in));
+ mGridContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_out));
+ } else {
+ mProgressContainer.clearAnimation();
+ mGridContainer.clearAnimation();
+ }
+ mProgressContainer.setVisibility(View.VISIBLE);
+ mGridContainer.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * Get the ListAdapter associated with this activity's GridView.
+ */
+ public ListAdapter getAdapter() {
+ return mAdapter;
+ }
+
+ private void ensureGrid() {
+ if (mGrid != null) {
+ return;
+ }
+ View root = getView();
+ if (root == null) {
+ throw new IllegalStateException("Content view not yet created");
+ }
+ if (root instanceof GridView) {
+ mGrid = (GridView) root;
+ } else {
+ View empty = root.findViewById(android.R.id.empty);
+ if (empty != null && empty instanceof TextView) {
+ mEmptyView = (TextView) empty;
+ }
+ mProgressContainer = root.findViewById(R.id.progressContainer);
+ mGridContainer = root.findViewById(R.id.gridContainer);
+ View rawGridView = root.findViewById(android.R.id.list);
+ if (!(rawGridView instanceof GridView)) {
+ throw new RuntimeException(
+ "Content has view with id attribute 'android.R.id.list' "
+ + "that is not a GridView class");
+ }
+ mGrid = (GridView) rawGridView;
+ if (mGrid == null) {
+ throw new RuntimeException(
+ "Your content must have a GridView whose id attribute is " +
+ "'android.R.id.list'");
+ }
+ if (mEmptyView != null) {
+ mGrid.setEmptyView(mEmptyView);
+ }
+ }
+ mGridShown = true;
+ mGrid.setOnItemClickListener(this);
+ mGrid.setMultiChoiceModeListener(mHost.getMultiChoiceManager());
+ if (mAdapter != null) {
+ ListAdapter adapter = mAdapter;
+ mAdapter = null;
+ setAdapter(adapter);
+ } else {
+ // We are starting without an adapter, so assume we won't
+ // have our data right away and start with the progress indicator.
+ if (mProgressContainer != null) {
+ setGridShown(false, false);
+ }
+ }
+ mHandler.post(mRequestFocus);
+ }
+
+ @Override
+ public Object getItemAtPosition(int position) {
+ return mAdapter.getItem(position);
+ }
+
+ @Override
+ public Object getPathForItemAtPosition(int position) {
+ return getPathForItem(getItemAtPosition(position));
+ }
+
+ @Override
+ public SparseBooleanArray getSelectedItemPositions() {
+ return mGrid.getCheckedItemPositions();
+ }
+
+ @Override
+ public int getSelectedItemCount() {
+ return mGrid.getCheckedItemCount();
+ }
+
+ public abstract Object getPathForItem(Object item);
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
+ onGridItemClick((GridView) parent, v, position, id);
+ }
+}
package com.android.photos;
-import android.app.Activity;
-import android.app.Fragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
-import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
-import com.android.gallery3d.R;
import com.android.gallery3d.app.Gallery;
import com.android.photos.adapters.PhotoThumbnailAdapter;
import com.android.photos.data.PhotoSetLoader;
import java.util.ArrayList;
-public class PhotoSetFragment extends Fragment implements OnItemClickListener,
- LoaderCallbacks<Cursor>, MultiChoiceManager.Delegate {
+public class PhotoSetFragment extends MultiSelectGridFragment implements LoaderCallbacks<Cursor> {
private static final int LOADER_PHOTOSET = 1;
- private GridView mPhotoSetView;
- private View mEmptyView;
-
- private boolean mInitialLoadComplete = false;
private LoaderCompatShim<Cursor> mLoaderCompatShim;
private PhotoThumbnailAdapter mAdapter;
- private GalleryFragmentHost mHost;
@Override
public void onCreate(Bundle savedInstanceState) {
}
@Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- mHost = (GalleryFragmentHost) activity;
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- mHost = null;
- }
-
- @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- View root = inflater.inflate(R.layout.photo_set, container, false);
- mPhotoSetView = (GridView) root.findViewById(android.R.id.list);
- // TODO: Remove once UI stabilizes
- mPhotoSetView.setColumnWidth(MediaItemsLoader.getThumbnailSize());
- mPhotoSetView.setOnItemClickListener(this);
- mEmptyView = root.findViewById(android.R.id.empty);
- mEmptyView.setVisibility(View.GONE);
- mPhotoSetView.setAdapter(mAdapter);
- mPhotoSetView.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
- mPhotoSetView.setMultiChoiceModeListener(mHost.getMultiChoiceManager());
+ View root = super.onCreateView(inflater, container, savedInstanceState);
getLoaderManager().initLoader(LOADER_PHOTOSET, null, this);
- updateEmptyStatus();
return root;
}
- private void updateEmptyStatus() {
- boolean empty = (mAdapter == null || mAdapter.getCount() == 0);
- mPhotoSetView.setVisibility(empty ? View.GONE : View.VISIBLE);
- mEmptyView.setVisibility(empty && mInitialLoadComplete
- ? View.VISIBLE : View.GONE);
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ // TODO: Remove once UI stabilizes
+ getGridView().setColumnWidth(MediaItemsLoader.getThumbnailSize());
}
@Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
+ public void onGridItemClick(GridView g, View v, int position, long id) {
if (mLoaderCompatShim == null) {
// Not fully initialized yet, discard
return;
}
- Cursor item = mAdapter.getItem(position);
+ Cursor item = (Cursor) getItemAtPosition(position);
Uri uri = mLoaderCompatShim.uriForItem(item);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setClass(getActivity(), Gallery.class);
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// TODO: Switch to PhotoSetLoader
MediaItemsLoader loader = new MediaItemsLoader(getActivity());
- mInitialLoadComplete = false;
mLoaderCompatShim = loader;
mAdapter.setDrawableFactory(mLoaderCompatShim);
return loader;
public void onLoadFinished(Loader<Cursor> loader,
Cursor data) {
mAdapter.swapCursor(data);
- mInitialLoadComplete = true;
- updateEmptyStatus();
+ setAdapter(mAdapter);
}
@Override
return ((Cursor) item).getInt(PhotoSetLoader.INDEX_SUPPORTED_OPERATIONS);
}
- @Override
- public Object getItemAtPosition(int position) {
- return mAdapter.getItem(position);
- }
-
private ArrayList<Uri> mSubItemUriTemp = new ArrayList<Uri>(1);
@Override
public ArrayList<Uri> getSubItemUrisForItem(Object item) {
return mSubItemUriTemp;
}
-
- @Override
- public Object getPathForItemAtPosition(int position) {
- return mLoaderCompatShim.getPathForItem(mAdapter.getItem(position));
- }
-
@Override
public void deleteItemWithPath(Object itemPath) {
mLoaderCompatShim.deleteItemWithPath(itemPath);
}
@Override
- public SparseBooleanArray getSelectedItemPositions() {
- return mPhotoSetView.getCheckedItemPositions();
- }
-
- @Override
- public int getSelectedItemCount() {
- return mPhotoSetView.getCheckedItemCount();
+ public Uri getItemUri(Object item) {
+ return mLoaderCompatShim.uriForItem((Cursor) item);
}
@Override
- public Uri getItemUri(Object item) {
- return mLoaderCompatShim.uriForItem((Cursor) item);
+ public Object getPathForItem(Object item) {
+ return mLoaderCompatShim.getPathForItem((Cursor) item);
}
}
public ArrayList<Uri> getSelectedShareableUris();
}
- public interface Client {
- public void setSelectionManager(SelectionManager manager);
- }
-
public SelectionManager(Activity activity) {
mActivity = activity;
if (ApiHelper.AT_LEAST_16) {