diff --git a/build/sdk.atree b/build/sdk.atree
index c8ec963d5..f224d50fa 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -162,7 +162,7 @@ development/samples/ContactManager samples/${PLATFORM_NAME}/ContactMan
development/samples/CrossCompatibility samples/${PLATFORM_NAME}/CrossCompatibility
development/samples/CubeLiveWallpaper samples/${PLATFORM_NAME}/CubeLiveWallpaper
development/samples/Home samples/${PLATFORM_NAME}/Home
-development/samples/Honeycomb-Gallery samples/${PLATFORM_NAME}/Honeycomb-Gallery
+development/samples/HoneycombGallery samples/${PLATFORM_NAME}/HoneycombGallery
development/samples/JetBoy samples/${PLATFORM_NAME}/JetBoy
development/samples/LunarLander samples/${PLATFORM_NAME}/LunarLander
development/samples/MultiResolution samples/${PLATFORM_NAME}/MultiResolution
diff --git a/samples/Honeycomb-Gallery/Android.mk b/samples/Honeycomb-Gallery/Android.mk
index 01788afb0..e56ae1575 100644
--- a/samples/Honeycomb-Gallery/Android.mk
+++ b/samples/Honeycomb-Gallery/Android.mk
@@ -6,7 +6,7 @@ LOCAL_MODULE_TAGS := samples
# Only compile source java files in this apk.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := Honeycomb-Gallery
+LOCAL_PACKAGE_NAME := HoneycombGallery
LOCAL_SDK_VERSION := current
diff --git a/samples/Honeycomb-Gallery/AndroidManifest.xml b/samples/Honeycomb-Gallery/AndroidManifest.xml
index cab59c15e..60fd4c62f 100644
--- a/samples/Honeycomb-Gallery/AndroidManifest.xml
+++ b/samples/Honeycomb-Gallery/AndroidManifest.xml
@@ -19,20 +19,28 @@
android:versionName="1.0">
+
+
-
+
+
+
+
+
diff --git a/samples/Honeycomb-Gallery/_index.html b/samples/Honeycomb-Gallery/_index.html
index 51605277c..963661e98 100644
--- a/samples/Honeycomb-Gallery/_index.html
+++ b/samples/Honeycomb-Gallery/_index.html
@@ -1,13 +1,27 @@
This is a demo application highlighting how to use some of the new APIs in
-Honeycomb, including Fragments, the Action Bar, drag'n drop, transition
-animations, and a stack widget. The image gallery shows how all these pieces
-can work together in one application.
+Honeycomb, including:
-The application includes the following classes:
+
+
+The image gallery shows how all these pieces can work together in one application.
+
+The application includes the following key classes:
- ContentFragment
- A fragment responsible for containing the "content" of the application.
- Displays images, receives drag/drop events from other fragments.
+ A fragment responsible for containing the "content" of the application.
+ Displays images, receives drag/drop events from other fragments, and can
+ invoke the contextual action bar using
+ action modes.
- TitlesFragment
Shows a ListView of photos to display in the ContentFragment. Photos can
be chosen either by tapping on the listview, or dragging them from the
@@ -19,7 +33,7 @@ can work together in one application.
ContentFragment. MainActivity is also responsible for keeping track of
the currently selected theme and currently selected photo when the
activity is recreated, such as when the screen is rotated or an intent to
- a seperate activity is fired (such as the included Camera sample).
+ a separate activity is fired (such as the included Camera sample).
MainActivity also contains code demonstrating how to animate
showing/hiding fragments (in this case, the TitlesFragment) and the
ActionBar, demonstrating how to smoothly transition between states
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/android_logo.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/android_logo.png
deleted file mode 100644
index f8be345f6..000000000
Binary files a/samples/Honeycomb-Gallery/res/drawable-hdpi/android_logo.png and /dev/null differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/btn_notification_ic_example_default.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/btn_notification_ic_example_default.png
new file mode 100644
index 000000000..aefa03051
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/btn_notification_ic_example_default.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/btn_notification_ic_example_pressed.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/btn_notification_ic_example_pressed.png
new file mode 100644
index 000000000..ea42154a6
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/btn_notification_ic_example_pressed.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera.png
deleted file mode 100644
index d03cbf9e6..000000000
Binary files a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera.png and /dev/null differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera_holo_dark.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera_holo_dark.png
new file mode 100644
index 000000000..c28118134
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera_holo_dark.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera_holo_light.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera_holo_light.png
new file mode 100644
index 000000000..296db3322
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera_holo_light.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_share_holo_dark.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_share_holo_dark.png
new file mode 100644
index 000000000..2f8e83f4c
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_share_holo_dark.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_share_holo_light.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_share_holo_light.png
new file mode 100644
index 000000000..505332a36
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_share_holo_light.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle.png
deleted file mode 100644
index a4b50d9db..000000000
Binary files a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle.png and /dev/null differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle_holo_dark.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle_holo_dark.png
new file mode 100644
index 000000000..93f51bd29
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle_holo_dark.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle_holo_light.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle_holo_light.png
new file mode 100644
index 000000000..090830a4e
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle_holo_light.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_stat_notify_example.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_stat_notify_example.png
new file mode 100644
index 000000000..b1fc03c29
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_stat_notify_example.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_default.9.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_default.9.png
new file mode 100644
index 000000000..ce17c9c94
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_default.9.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_pressed.9.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_pressed.9.png
new file mode 100644
index 000000000..d5579c9c6
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_pressed.9.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_selected.9.png b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_selected.9.png
new file mode 100644
index 000000000..3e02aa9a6
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_selected.9.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/btn_notification_ic_example_default.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/btn_notification_ic_example_default.png
new file mode 100644
index 000000000..540829f3a
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/btn_notification_ic_example_default.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/btn_notification_ic_example_pressed.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/btn_notification_ic_example_pressed.png
new file mode 100644
index 000000000..645bc5b5f
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/btn_notification_ic_example_pressed.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera.png
deleted file mode 100644
index a8f2f4165..000000000
Binary files a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera.png and /dev/null differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera_holo_dark.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera_holo_dark.png
new file mode 100644
index 000000000..6af2d1ca7
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera_holo_dark.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera_holo_light.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera_holo_light.png
new file mode 100644
index 000000000..4193cad88
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera_holo_light.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_share_holo_dark.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_share_holo_dark.png
new file mode 100644
index 000000000..996bd8808
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_share_holo_dark.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_share_holo_light.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_share_holo_light.png
new file mode 100644
index 000000000..943ba303a
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_share_holo_light.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle.png
deleted file mode 100644
index 9a77dc757..000000000
Binary files a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle.png and /dev/null differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle_holo_dark.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle_holo_dark.png
new file mode 100644
index 000000000..7c7cff4bd
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle_holo_dark.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle_holo_light.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle_holo_light.png
new file mode 100644
index 000000000..91d48fab4
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle_holo_light.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_stat_notify_example.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_stat_notify_example.png
new file mode 100644
index 000000000..fa825ace8
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_stat_notify_example.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_default.9.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_default.9.png
new file mode 100644
index 000000000..3588cf9b2
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_default.9.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_pressed.9.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_pressed.9.png
new file mode 100644
index 000000000..5bb7327b9
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_pressed.9.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_selected.9.png b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_selected.9.png
new file mode 100644
index 000000000..3842bc9e1
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_selected.9.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable-nodpi/notification_default_largeicon.png b/samples/Honeycomb-Gallery/res/drawable-nodpi/notification_default_largeicon.png
new file mode 100644
index 000000000..e50b97ee8
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-nodpi/notification_default_largeicon.png differ
diff --git a/samples/Honeycomb-Gallery/res/drawable/btn_notification_ic_example.xml b/samples/Honeycomb-Gallery/res/drawable/btn_notification_ic_example.xml
new file mode 100644
index 000000000..1fb298e1f
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/drawable/btn_notification_ic_example.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/samples/Honeycomb-Gallery/res/drawable/picture_frame.xml b/samples/Honeycomb-Gallery/res/drawable/picture_frame.xml
new file mode 100644
index 000000000..063abf1d3
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/drawable/picture_frame.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/samples/Honeycomb-Gallery/res/layout/content_welcome.xml b/samples/Honeycomb-Gallery/res/layout/content_welcome.xml
index 0b92508c2..189218fe1 100644
--- a/samples/Honeycomb-Gallery/res/layout/content_welcome.xml
+++ b/samples/Honeycomb-Gallery/res/layout/content_welcome.xml
@@ -15,13 +15,16 @@
limitations under the License.
-->
-
+ android:padding="24dp"
+ android:clickable="true">
-
+ android:background="@drawable/picture_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:duplicateParentState="true"/>
+
diff --git a/samples/Honeycomb-Gallery/res/layout/notification.xml b/samples/Honeycomb-Gallery/res/layout/notification.xml
new file mode 100644
index 000000000..3da757ddf
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/layout/notification.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Honeycomb-Gallery/res/menu/main_menu.xml b/samples/Honeycomb-Gallery/res/menu/main_menu.xml
index 1975bdc95..0e27cb539 100644
--- a/samples/Honeycomb-Gallery/res/menu/main_menu.xml
+++ b/samples/Honeycomb-Gallery/res/menu/main_menu.xml
@@ -18,16 +18,23 @@
diff --git a/samples/Honeycomb-Gallery/res/menu/photo_context_menu.xml b/samples/Honeycomb-Gallery/res/menu/photo_context_menu.xml
new file mode 100644
index 000000000..efe26c927
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/menu/photo_context_menu.xml
@@ -0,0 +1,23 @@
+
+
+
+
diff --git a/samples/Honeycomb-Gallery/res/values/attrs.xml b/samples/Honeycomb-Gallery/res/values/attrs.xml
new file mode 100644
index 000000000..954cbe478
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/values/attrs.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Honeycomb-Gallery/res/values/colors.xml b/samples/Honeycomb-Gallery/res/values/colors.xml
index 2714fcc89..d64863a9a 100644
--- a/samples/Honeycomb-Gallery/res/values/colors.xml
+++ b/samples/Honeycomb-Gallery/res/values/colors.xml
@@ -17,4 +17,5 @@
#ccffffff
#cc000000
+ #80cccccc
diff --git a/samples/Honeycomb-Gallery/res/values/strings.xml b/samples/Honeycomb-Gallery/res/values/strings.xml
index a6c3b5720..5c3b35526 100644
--- a/samples/Honeycomb-Gallery/res/values/strings.xml
+++ b/samples/Honeycomb-Gallery/res/values/strings.xml
@@ -15,10 +15,14 @@
limitations under the License.
-->
- Honeycomb Example
+ Honeycomb Gallery
Camera Example
Clip Label
Honeycomb Example Widget
Touch to show data
+
+ Example notification text
+
+ Photo selection
diff --git a/samples/Honeycomb-Gallery/res/values/styles.xml b/samples/Honeycomb-Gallery/res/values/styles.xml
new file mode 100644
index 000000000..7570b625e
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/values/styles.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/ContentFragment.java b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/ContentFragment.java
index a0f334f7b..8c3323b96 100644
--- a/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/ContentFragment.java
+++ b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/ContentFragment.java
@@ -16,29 +16,45 @@
package com.example.android.hcgallery;
-import java.util.StringTokenizer;
-
import android.app.ActionBar;
+import android.app.Activity;
import android.app.Fragment;
import android.content.ClipData;
-import android.content.ClipDescription;
import android.content.ClipData.Item;
+import android.content.ClipDescription;
+import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
+import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
+import android.view.ActionMode;
import android.view.DragEvent;
import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
import android.view.View.OnClickListener;
+import android.view.ViewGroup;
import android.widget.ImageView;
-import android.view.Window;
-import android.view.WindowManager;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.StringTokenizer;
public class ContentFragment extends Fragment {
+ private View mContentView;
+
// The bitmap currently used by ImageView
private Bitmap mBitmap = null;
+ // Current action mode (contextual action bar, a.k.a. CAB)
+ private ActionMode mCurrentActionMode;
+
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -47,47 +63,86 @@ public class ContentFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- final View view = inflater.inflate(R.layout.content_welcome, null);
- final ImageView imageView = (ImageView) view.findViewById(R.id.image);
- view.setDrawingCacheEnabled(false);
+ mContentView = inflater.inflate(R.layout.content_welcome, null);
+ final ImageView imageView = (ImageView) mContentView.findViewById(R.id.image);
+ mContentView.setDrawingCacheEnabled(false);
- view.setOnDragListener(new View.OnDragListener() {
+ mContentView.setOnDragListener(new View.OnDragListener() {
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
- case DragEvent.ACTION_DRAG_ENTERED:
- view.setBackgroundColor(Color.LTGRAY);
- break;
- case DragEvent.ACTION_DRAG_EXITED:
- view.setBackgroundColor(Color.TRANSPARENT);
- break;
- case DragEvent.ACTION_DRAG_STARTED:
- return processDragStarted(event);
- case DragEvent.ACTION_DROP:
- view.setBackgroundColor(Color.TRANSPARENT);
- return processDrop(event, imageView);
+ case DragEvent.ACTION_DRAG_ENTERED:
+ mContentView.setBackgroundColor(
+ getResources().getColor(R.color.drag_active_color));
+ break;
+
+ case DragEvent.ACTION_DRAG_EXITED:
+ mContentView.setBackgroundColor(Color.TRANSPARENT);
+ break;
+
+ case DragEvent.ACTION_DRAG_STARTED:
+ return processDragStarted(event);
+
+ case DragEvent.ACTION_DROP:
+ mContentView.setBackgroundColor(Color.TRANSPARENT);
+ return processDrop(event, imageView);
}
return false;
}
});
- view.setOnClickListener(new OnClickListener() {
+ // Keep the action bar visibility in sync with the system status bar. That is, when entering
+ // 'lights out mode,' hide the action bar, and when exiting this mode, show the action bar.
-
- public void onClick(View v) {
- ActionBar bar = getActivity().getActionBar();
- if (bar != null) {
- if (bar.isShowing()) {
- bar.hide();
- } else {
- bar.show();
+ final Activity activity = getActivity();
+ mContentView.setOnSystemUiVisibilityChangeListener(
+ new View.OnSystemUiVisibilityChangeListener() {
+ public void onSystemUiVisibilityChange(int visibility) {
+ ActionBar actionBar = activity.getActionBar();
+ if (actionBar != null) {
+ mContentView.setSystemUiVisibility(visibility);
+ if (visibility == View.STATUS_BAR_VISIBLE) {
+ actionBar.show();
+ } else {
+ actionBar.hide();
+ }
+ }
}
+ });
+
+ // Show/hide the system status bar when single-clicking a photo. This is also called
+ // 'lights out mode.' Activating and deactivating this mode also invokes the listener
+ // defined above, which will show or hide the action bar accordingly.
+
+ mContentView.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ if (mContentView.getSystemUiVisibility() == View.STATUS_BAR_VISIBLE) {
+ mContentView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
+ } else {
+ mContentView.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
}
}
});
- return view;
+
+ // When long-pressing a photo, activate the action mode for selection, showing the
+ // contextual action bar (CAB).
+
+ mContentView.setOnLongClickListener(new View.OnLongClickListener() {
+ public boolean onLongClick(View view) {
+ if (mCurrentActionMode != null) {
+ return false;
+ }
+
+ mCurrentActionMode = getActivity().startActionMode(
+ mContentSelectionActionModeCallback);
+ mContentView.setSelected(true);
+ return true;
+ }
+ });
+
+ return mContentView;
}
- boolean processDragStarted(DragEvent event) {
+ boolean processDragStarted(DragEvent event) {
// Determine whether to continue processing drag and drop based on the
// plain text mime type.
ClipDescription clipDesc = event.getClipDescription();
@@ -97,7 +152,7 @@ public class ContentFragment extends Fragment {
return false;
}
- private boolean processDrop(DragEvent event, ImageView imageView) {
+ boolean processDrop(DragEvent event, ImageView imageView) {
// Attempt to parse clip data with expected format: category||entry_id.
// Ignore event if data does not conform to this format.
ClipData data = event.getClipData();
@@ -130,16 +185,115 @@ public class ContentFragment extends Fragment {
return false;
}
- public void updateContentAndRecycleBitmap(int category, int position) {
- // Get the bitmap that needs to be drawn and update the ImageView
- Bitmap next = Directory.getCategory(category).getEntry(position)
- .getBitmap(getResources());
- ((ImageView) getView().findViewById(R.id.image)).setImageBitmap(next);
+ void updateContentAndRecycleBitmap(int category, int position) {
+ if (mCurrentActionMode != null) {
+ mCurrentActionMode.finish();
+ }
+
if (mBitmap != null) {
// This is an advanced call and should be used if you
// are working with a lot of bitmaps. The bitmap is dead
// after this call.
mBitmap.recycle();
}
+
+ // Get the bitmap that needs to be drawn and update the ImageView
+ mBitmap = Directory.getCategory(category).getEntry(position)
+ .getBitmap(getResources());
+ ((ImageView) getView().findViewById(R.id.image)).setImageBitmap(mBitmap);
}
+
+ void shareCurrentPhoto() {
+ File externalCacheDir = getActivity().getExternalCacheDir();
+ if (externalCacheDir == null) {
+ Toast.makeText(getActivity(), "Error writing to USB/external storage.",
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ // Prevent media scanning of the cache directory.
+ final File noMediaFile = new File(externalCacheDir, ".nomedia");
+ try {
+ noMediaFile.createNewFile();
+ } catch (IOException e) {
+ }
+
+ // Write the bitmap to temporary storage in the external storage directory (e.g. SD card).
+ // We perform the actual disk write operations on a separate thread using the
+ // {@link AsyncTask} class, thus avoiding the possibility of stalling the main (UI) thread.
+
+ final File tempFile = new File(externalCacheDir, "tempfile.jpg");
+
+ new AsyncTask() {
+ /**
+ * Compress and write the bitmap to disk on a separate thread.
+ * @return TRUE if the write was successful, FALSE otherwise.
+ */
+ protected Boolean doInBackground(Void... voids) {
+ try {
+ FileOutputStream fo = new FileOutputStream(tempFile, false);
+ if (!mBitmap.compress(Bitmap.CompressFormat.JPEG, 60, fo)) {
+ Toast.makeText(getActivity(), "Error writing bitmap data.",
+ Toast.LENGTH_SHORT).show();
+ return Boolean.FALSE;
+ }
+ return Boolean.TRUE;
+
+ } catch (FileNotFoundException e) {
+ Toast.makeText(getActivity(), "Error writing to USB/external storage.",
+ Toast.LENGTH_SHORT).show();
+ return Boolean.FALSE;
+ }
+ }
+
+ /**
+ * After doInBackground completes (either successfully or in failure), we invoke an
+ * intent to share the photo. This code is run on the main (UI) thread.
+ */
+ protected void onPostExecute(Boolean result) {
+ if (result != Boolean.TRUE) {
+ return;
+ }
+
+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
+ shareIntent.setType("image/jpeg");
+ startActivity(Intent.createChooser(shareIntent, "Share photo"));
+ }
+ }.execute();
+ }
+
+ /**
+ * The callback for the 'photo selected' {@link ActionMode}. In this action mode, we can
+ * provide contextual actions for the selected photo. We currently only provide the 'share'
+ * action, but we could also add clipboard functions such as cut/copy/paste here as well.
+ */
+ private ActionMode.Callback mContentSelectionActionModeCallback = new ActionMode.Callback() {
+ public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
+ actionMode.setTitle(R.string.photo_selection_cab_title);
+
+ MenuInflater inflater = getActivity().getMenuInflater();
+ inflater.inflate(R.menu.photo_context_menu, menu);
+ return true;
+ }
+
+ public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
+ return false;
+ }
+
+ public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
+ switch (menuItem.getItemId()) {
+ case R.id.share:
+ shareCurrentPhoto();
+ actionMode.finish();
+ return true;
+ }
+ return false;
+ }
+
+ public void onDestroyActionMode(ActionMode actionMode) {
+ mContentView.setSelected(false);
+ mCurrentActionMode = null;
+ }
+ };
}
diff --git a/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/FitCenterFrameLayout.java b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/FitCenterFrameLayout.java
new file mode 100644
index 000000000..c6247ba4e
--- /dev/null
+++ b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/FitCenterFrameLayout.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2011 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.example.android.hcgallery;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A simple layout that fits and centers each child view, maintaining aspect ratio.
+ */
+public class FitCenterFrameLayout extends ViewGroup {
+ public FitCenterFrameLayout(Context context) {
+ super(context);
+ }
+
+ public FitCenterFrameLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // We purposely disregard child measurements.
+ final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
+ final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
+ setMeasuredDimension(width, height);
+
+ int childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.UNSPECIFIED);
+ int childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED);
+
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ getChildAt(i).measure(childWidthSpec, childHeightSpec);
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int childCount = getChildCount();
+
+ final int parentLeft = getPaddingLeft();
+ final int parentTop = getPaddingTop();
+ final int parentRight = r - l - getPaddingRight();
+ final int parentBottom = b - t - getPaddingBottom();
+
+ final int parentWidth = parentRight - parentLeft;
+ final int parentHeight = parentBottom - parentTop;
+
+ int unpaddedWidth, unpaddedHeight, parentUnpaddedWidth, parentUnpaddedHeight;
+ int childPaddingLeft, childPaddingTop, childPaddingRight, childPaddingBottom;
+
+ for (int i = 0; i < childCount; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() == GONE) {
+ continue;
+ }
+
+ // Fit and center the child within the parent. Make sure not to consider padding
+ // as part of the child's aspect ratio.
+
+ childPaddingLeft = child.getPaddingLeft();
+ childPaddingTop = child.getPaddingTop();
+ childPaddingRight = child.getPaddingRight();
+ childPaddingBottom = child.getPaddingBottom();
+
+ unpaddedWidth = child.getMeasuredWidth() - childPaddingLeft - childPaddingRight;
+ unpaddedHeight = child.getMeasuredHeight() - childPaddingTop - childPaddingBottom;
+
+ parentUnpaddedWidth = parentWidth - childPaddingLeft - childPaddingRight;
+ parentUnpaddedHeight = parentHeight - childPaddingTop - childPaddingBottom;
+
+ if (parentUnpaddedWidth * unpaddedHeight > parentUnpaddedHeight * unpaddedWidth) {
+ // The child view should be left/right letterboxed.
+ final int scaledChildWidth = unpaddedWidth * parentUnpaddedHeight
+ / unpaddedHeight + childPaddingLeft + childPaddingRight;
+ child.layout(
+ parentLeft + (parentWidth - scaledChildWidth) / 2,
+ parentTop,
+ parentRight - (parentWidth - scaledChildWidth) / 2,
+ parentBottom);
+ } else {
+ // The child view should be top/bottom letterboxed.
+ final int scaledChildHeight = unpaddedHeight * parentUnpaddedWidth
+ / unpaddedWidth + childPaddingTop + childPaddingBottom;
+ child.layout(
+ parentLeft,
+ parentTop + (parentHeight - scaledChildHeight) / 2,
+ parentRight,
+ parentTop + (parentHeight + scaledChildHeight) / 2);
+ }
+ }
+ }
+}
diff --git a/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/MainActivity.java b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/MainActivity.java
index 2086975ee..3cfaf6d15 100644
--- a/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/MainActivity.java
+++ b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/MainActivity.java
@@ -28,10 +28,15 @@ import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
-import android.graphics.drawable.ColorDrawable;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
@@ -39,9 +44,13 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
+import android.widget.RemoteViews;
public class MainActivity extends Activity implements ActionBar.TabListener {
+ private static final int NOTIFICATION_DEFAULT = 1;
+ private static final String ACTION_DIALOG = "com.example.android.hcgallery.action.DIALOG";
+
private View mActionBarView;
private Animator mCurrentTitlesAnimator;
private String[] mToggleLabels = {"Show Titles", "Hide Titles"};
@@ -51,26 +60,18 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
if(savedInstanceState != null && savedInstanceState.getInt("theme", -1) != -1) {
mThemeId = savedInstanceState.getInt("theme");
this.setTheme(mThemeId);
}
- requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.main);
Directory.initializeDirectory();
ActionBar bar = getActionBar();
- if (mThemeId == android.R.style.Theme_Holo_Light || mThemeId == -1) {
- bar.setBackgroundDrawable(
- new ColorDrawable(getResources().getColor(R.color.actionbar_background_light)));
- } else {
- bar.setBackgroundDrawable(
- new ColorDrawable(getResources().getColor(R.color.actionbar_background_dark)));
- }
-
int i;
for (i = 0; i < Directory.getCategoryCount(); i++) {
bar.addTab(bar.newTab().setText(Directory.getCategory(i).getName())
@@ -122,21 +123,30 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
intent.putExtra("theme", mThemeId);
startActivity(intent);
return true;
+
case R.id.toggleTitles:
toggleVisibleTitles();
return true;
case R.id.toggleTheme:
- if (mThemeId == android.R.style.Theme_Holo) {
- mThemeId = android.R.style.Theme_Holo_Light;
+ if (mThemeId == R.style.AppTheme_Dark) {
+ mThemeId = R.style.AppTheme_Light;
} else {
- mThemeId = android.R.style.Theme_Holo;
+ mThemeId = R.style.AppTheme_Dark;
}
this.recreate();
return true;
case R.id.showDialog:
- showDialog();
+ showDialog("This is indeed an awesome dialog.");
+ return true;
+
+ case R.id.showStandardNotification:
+ showNotification(false);
+ return true;
+
+ case R.id.showCustomNotification:
+ showNotification(true);
return true;
default:
@@ -225,21 +235,84 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
mCurrentTitlesAnimator = objectAnimator;
invalidateOptionsMenu();
+
+ // Manually trigger onNewIntent to check for ACTION_DIALOG.
+ onNewIntent(getIntent());
}
- void showDialog() {
+ @Override
+ protected void onNewIntent(Intent intent) {
+ if (ACTION_DIALOG.equals(intent.getAction())) {
+ showDialog(intent.getStringExtra(Intent.EXTRA_TEXT));
+ }
+ }
+ void showDialog(String text) {
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getFragmentManager().beginTransaction();
- DialogFragment newFragment = MyDialogFragment.newInstance("The Dialog Of Awesome");
+ DialogFragment newFragment = MyDialogFragment.newInstance(text);
- // Create and show the dialog.
+ // Show the dialog.
newFragment.show(ft, "dialog");
}
+ void showNotification(boolean custom) {
+ final Resources res = getResources();
+ final NotificationManager notificationManager = (NotificationManager) getSystemService(
+ NOTIFICATION_SERVICE);
+
+ Notification.Builder builder = new Notification.Builder(this)
+ .setSmallIcon(R.drawable.ic_stat_notify_example)
+ .setAutoCancel(true)
+ .setTicker(getString(R.string.notification_text))
+ .setContentIntent(getDialogPendingIntent("Tapped the notification entry."));
+
+ if (custom) {
+ // Sets a custom content view for the notification, including an image button.
+ RemoteViews layout = new RemoteViews(getPackageName(), R.layout.notification);
+ layout.setTextViewText(R.id.notification_title, getString(R.string.app_name));
+ layout.setOnClickPendingIntent(R.id.notification_button,
+ getDialogPendingIntent("Tapped the 'dialog' button in the notification."));
+ builder.setContent(layout);
+
+ // Notifications in Android 3.0 now have a standard mechanism for displaying large
+ // bitmaps such as contact avatars. Here, we load an example image and resize it to the
+ // appropriate size for large bitmaps in notifications.
+ Bitmap largeIconTemp = BitmapFactory.decodeResource(res,
+ R.drawable.notification_default_largeicon);
+ Bitmap largeIcon = Bitmap.createScaledBitmap(
+ largeIconTemp,
+ res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
+ res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height),
+ false);
+ largeIconTemp.recycle();
+
+ builder.setLargeIcon(largeIcon);
+
+ } else {
+ builder
+ .setNumber(7) // An example number.
+ .setContentTitle(getString(R.string.app_name))
+ .setContentText(getString(R.string.notification_text));
+ }
+
+ notificationManager.notify(NOTIFICATION_DEFAULT, builder.getNotification());
+ }
+
+ PendingIntent getDialogPendingIntent(String dialogText) {
+ return PendingIntent.getActivity(
+ this,
+ dialogText.hashCode(), // Otherwise previous PendingIntents with the same
+ // requestCode may be overwritten.
+ new Intent(ACTION_DIALOG)
+ .putExtra(Intent.EXTRA_TEXT, dialogText)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
+ 0);
+ }
+
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.getItem(1).setTitle(mToggleLabels[mLabelIndex]);
@@ -261,24 +334,19 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
public static MyDialogFragment newInstance(String title) {
MyDialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
- args.putString("title", title);
+ args.putString("text", title);
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
- String title = getArguments().getString("title");
+ String text = getArguments().getString("text");
return new AlertDialog.Builder(getActivity())
- .setTitle(title)
- .setPositiveButton("OK",
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- }
- }
- )
- .setNegativeButton("Cancel",
+ .setTitle("A Dialog of Awesome")
+ .setMessage(text)
+ .setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
diff --git a/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/TitlesFragment.java b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/TitlesFragment.java
index 8ee297c32..85a7b68ea 100644
--- a/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/TitlesFragment.java
+++ b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/TitlesFragment.java
@@ -20,6 +20,8 @@ import android.app.Fragment;
import android.app.FragmentManager;
import android.app.ListFragment;
import android.content.ClipData;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
@@ -28,6 +30,7 @@ import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.TextPaint;
+import android.util.TypedValue;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
@@ -53,47 +56,40 @@ public class TitlesFragment extends ListFragment {
populateTitles(mCategory);
ListView lv = getListView();
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
- selectPosition(mCurPosition);
- lv.setCacheColorHint(Color.WHITE);
+ lv.setCacheColorHint(Color.TRANSPARENT);
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
-
- public boolean onItemLongClick(AdapterView> av, View v, int pos,
- long id) {
+ public boolean onItemLongClick(AdapterView> av, View v, int pos, long id) {
final String title = (String) ((TextView) v).getText();
// Set up clip data with the category||entry_id format.
final String textData = String.format("%d||%d", mCategory, pos);
ClipData data = ClipData.newPlainText(title, textData);
-
- v.startDrag(data, new MyDragShadowBuilder(v, title), null, 0);
+ v.startDrag(data, new MyDragShadowBuilder(v), null, 0);
return true;
}
});
+
+ selectPosition(mCurPosition);
}
- private static class MyDragShadowBuilder extends View.DragShadowBuilder {
- private static Drawable mShadow;
- private static String mLabel;
- private static int mViewHeight;
-
- public MyDragShadowBuilder(View v, String label) {
+ private class MyDragShadowBuilder extends View.DragShadowBuilder {
+ private Drawable mShadow;
+
+ public MyDragShadowBuilder(View v) {
super(v);
- mShadow = new ColorDrawable(Color.BLUE);
+
+ final TypedArray a = v.getContext().obtainStyledAttributes(R.styleable.AppTheme);
+ mShadow = a.getDrawable(R.styleable.AppTheme_listDragShadowBackground);
+ mShadow.setCallback(v);
mShadow.setBounds(0, 0, v.getWidth(), v.getHeight());
- mLabel = label;
- mViewHeight = v.getHeight();
+ a.recycle();
}
@Override
public void onDrawShadow(Canvas canvas) {
super.onDrawShadow(canvas);
mShadow.draw(canvas);
- Paint paint = new TextPaint();
- paint.setTextSize(20);
- paint.setColor(Color.LTGRAY);
- paint.setTypeface(Typeface.DEFAULT_BOLD);
- paint.setAntiAlias(true);
- canvas.drawText(mLabel, 20, (float) (mViewHeight * .6), paint);
+ getView().draw(canvas);
}
}
@@ -116,13 +112,13 @@ public class TitlesFragment extends ListFragment {
ContentFragment frag = (ContentFragment) getFragmentManager()
.findFragmentById(R.id.frag_content);
frag.updateContentAndRecycleBitmap(mCategory, position);
+ mCurPosition = position;
}
public void selectPosition(int position) {
ListView lv = getListView();
lv.setItemChecked(position, true);
updateImage(position);
-
}
@Override