• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

development


Commit MetaInfo

Revisãof4f345d0b75c96d92f15a9aba8d58d5d4bec27c6 (tree)
Hora2011-02-08 10:03:19
AutorRoman Nurik <romannurik@goog...>
CommiterRoman Nurik

Mensagem de Log

Major update to HoneycombGallery

* Add action bar and icon theming
* Add contextual action bar and photo sharing
* Add notifications (with large icons too)
* Add fullscreening (lights-out mode)
* Add a picture frame

Change-Id: I07a1da435d5adc7bc76c7ac2cc087ff2efd74156

Mudança Sumário

Diff

--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -162,7 +162,7 @@ development/samples/ContactManager samples/${PLATFORM_NAME}/ContactMan
162162 development/samples/CrossCompatibility samples/${PLATFORM_NAME}/CrossCompatibility
163163 development/samples/CubeLiveWallpaper samples/${PLATFORM_NAME}/CubeLiveWallpaper
164164 development/samples/Home samples/${PLATFORM_NAME}/Home
165-development/samples/Honeycomb-Gallery samples/${PLATFORM_NAME}/Honeycomb-Gallery
165+development/samples/HoneycombGallery samples/${PLATFORM_NAME}/HoneycombGallery
166166 development/samples/JetBoy samples/${PLATFORM_NAME}/JetBoy
167167 development/samples/LunarLander samples/${PLATFORM_NAME}/LunarLander
168168 development/samples/MultiResolution samples/${PLATFORM_NAME}/MultiResolution
--- a/samples/Honeycomb-Gallery/Android.mk
+++ b/samples/Honeycomb-Gallery/Android.mk
@@ -6,7 +6,7 @@ LOCAL_MODULE_TAGS := samples
66 # Only compile source java files in this apk.
77 LOCAL_SRC_FILES := $(call all-java-files-under, src)
88
9-LOCAL_PACKAGE_NAME := Honeycomb-Gallery
9+LOCAL_PACKAGE_NAME := HoneycombGallery
1010
1111 LOCAL_SDK_VERSION := current
1212
--- a/samples/Honeycomb-Gallery/AndroidManifest.xml
+++ b/samples/Honeycomb-Gallery/AndroidManifest.xml
@@ -19,20 +19,28 @@
1919 android:versionName="1.0">
2020
2121 <uses-sdk android:minSdkVersion="11" />
22+
2223 <uses-permission android:name="android.permission.CAMERA" />
24+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2325
2426 <application android:label="@string/app_name"
2527 android:icon="@drawable/icon"
2628 android:logo="@drawable/logo"
27- android:theme="@android:style/Theme.Holo.Light"
29+ android:theme="@style/AppTheme.Light"
2830 android:hardwareAccelerated="true"
2931 android:debuggable="true">
3032
31- <activity android:name=".MainActivity" android:label="@string/app_name">
33+ <activity android:name=".MainActivity"
34+ android:label="@string/app_name"
35+ android:launchMode="singleTop">
3236 <intent-filter>
3337 <action android:name="android.intent.action.MAIN" />
3438 <category android:name="android.intent.category.LAUNCHER" />
3539 </intent-filter>
40+ <intent-filter>
41+ <action android:name="com.example.android.hcgallery.action.DIALOG" />
42+ <category android:name="android.intent.category.DEFAULT" />
43+ </intent-filter>
3644 </activity>
3745
3846 <!-- CameraSample -->
--- a/samples/Honeycomb-Gallery/_index.html
+++ b/samples/Honeycomb-Gallery/_index.html
@@ -1,13 +1,27 @@
11 <p>This is a demo application highlighting how to use some of the new APIs in
2-Honeycomb, including Fragments, the Action Bar, drag'n drop, transition
3-animations, and a stack widget. The image gallery shows how all these pieces
4-can work together in one application.</p>
2+Honeycomb, including:</p>
53
6-<p>The application includes the following classes:<p>
4+<ul>
5+ <li><a href="../../../guide/topics/fundamentals/fragments.html">Fragments</a></li>
6+ <li>The <a href="../../../guide/topics/ui/actionbar.html">action bar</a>
7+ and contextual action bar</li>
8+ <li>Drag and drop</li>
9+ <li>The new <a href="../../../reference/android/animation/package-summary.html"><code>android.animation</code></a>
10+ framework</li>
11+ <li>Custom notifications</li>
12+ <li><a href="../../../reference/android/widget/StackView.html"><code>StackView</code></a>
13+ and other adapter-based app widgets</li>
14+</ul>
15+
16+<p>The image gallery shows how all these pieces can work together in one application.</p>
17+
18+<p>The application includes the following key classes:<p>
719 <ul>
820 <li><a href="src/com/example/android/hcgallery/ContentFragment.html">ContentFragment</a>
9- A fragment responsible for containing the "content" of the application.
10- Displays images, receives drag/drop events from other fragments.</li>
21+ A fragment responsible for containing the "content" of the application.
22+ Displays images, receives drag/drop events from other fragments, and can
23+ invoke the contextual action bar using
24+ <a href="../../../reference/android/view/ActionMode.html">action modes</a>.</li>
1125 <li><a href="src/com/example/android/hcgallery/TitlesFragment.html">TitlesFragment</a>
1226 Shows a ListView of photos to display in the ContentFragment. Photos can
1327 be chosen either by tapping on the listview, or dragging them from the
@@ -19,7 +33,7 @@ can work together in one application.</p>
1933 ContentFragment. MainActivity is also responsible for keeping track of
2034 the currently selected theme and currently selected photo when the
2135 activity is recreated, such as when the screen is rotated or an intent to
22- a seperate activity is fired (such as the included Camera sample).
36+ a separate activity is fired (such as the included Camera sample).
2337 MainActivity also contains code demonstrating how to animate
2438 showing/hiding fragments (in this case, the TitlesFragment) and the
2539 ActionBar, demonstrating how to smoothly transition between states
Binary files a/samples/Honeycomb-Gallery/res/drawable-hdpi/android_logo.png and /dev/null differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/btn_notification_ic_example_default.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/btn_notification_ic_example_pressed.png differ
Binary files a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera.png and /dev/null differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera_holo_dark.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera_holo_light.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_share_holo_dark.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_share_holo_light.png differ
Binary files a/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle.png and /dev/null differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle_holo_dark.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle_holo_light.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/ic_stat_notify_example.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_default.9.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_pressed.9.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-hdpi/picture_frame_selected.9.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/btn_notification_ic_example_default.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/btn_notification_ic_example_pressed.png differ
Binary files a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera.png and /dev/null differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera_holo_dark.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera_holo_light.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_share_holo_dark.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_share_holo_light.png differ
Binary files a/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle.png and /dev/null differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle_holo_dark.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle_holo_light.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/ic_stat_notify_example.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_default.9.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_pressed.9.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-mdpi/picture_frame_selected.9.png differ
Binary files /dev/null and b/samples/Honeycomb-Gallery/res/drawable-nodpi/notification_default_largeicon.png differ
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/drawable/btn_notification_ic_example.xml
@@ -0,0 +1,20 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!--
3+ Copyright (C) 2011 The Android Open Source Project
4+
5+ Licensed under the Apache License, Version 2.0 (the "License");
6+ you may not use this file except in compliance with the License.
7+ You may obtain a copy of the License at
8+
9+ http://www.apache.org/licenses/LICENSE-2.0
10+
11+ Unless required by applicable law or agreed to in writing, software
12+ distributed under the License is distributed on an "AS IS" BASIS,
13+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ See the License for the specific language governing permissions and
15+ limitations under the License.
16+ -->
17+<selector xmlns:android="http://schemas.android.com/apk/res/android">
18+ <item android:state_pressed="true" android:drawable="@drawable/btn_notification_ic_example_pressed" />
19+ <item android:drawable="@drawable/btn_notification_ic_example_default" />
20+</selector>
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/drawable/picture_frame.xml
@@ -0,0 +1,21 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!--
3+ Copyright (C) 2011 The Android Open Source Project
4+
5+ Licensed under the Apache License, Version 2.0 (the "License");
6+ you may not use this file except in compliance with the License.
7+ You may obtain a copy of the License at
8+
9+ http://www.apache.org/licenses/LICENSE-2.0
10+
11+ Unless required by applicable law or agreed to in writing, software
12+ distributed under the License is distributed on an "AS IS" BASIS,
13+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ See the License for the specific language governing permissions and
15+ limitations under the License.
16+ -->
17+<selector xmlns:android="http://schemas.android.com/apk/res/android">
18+ <item android:state_selected="true" android:drawable="@drawable/picture_frame_selected" />
19+ <item android:state_pressed="true" android:drawable="@drawable/picture_frame_pressed" />
20+ <item android:drawable="@drawable/picture_frame_default" />
21+</selector>
--- a/samples/Honeycomb-Gallery/res/layout/content_welcome.xml
+++ b/samples/Honeycomb-Gallery/res/layout/content_welcome.xml
@@ -15,13 +15,16 @@
1515 limitations under the License.
1616 -->
1717
18-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
18+<view xmlns:android="http://schemas.android.com/apk/res/android"
19+ class="com.example.android.hcgallery.FitCenterFrameLayout"
1920 android:layout_width="match_parent"
2021 android:layout_height="match_parent"
21- android:padding="12dp">
22+ android:padding="24dp"
23+ android:clickable="true">
2224 <ImageView android:id="@+id/image"
23- android:layout_width="match_parent"
24- android:layout_height="match_parent"
25- android:scaleType="fitCenter"
26- android:layout_gravity="center" />
27-</FrameLayout>
25+ android:background="@drawable/picture_frame"
26+ android:layout_width="wrap_content"
27+ android:layout_height="wrap_content"
28+ android:layout_gravity="center"
29+ android:duplicateParentState="true"/>
30+</view>
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/layout/notification.xml
@@ -0,0 +1,60 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!--
3+ Copyright (C) 2011 The Android Open Source Project
4+
5+ Licensed under the Apache License, Version 2.0 (the "License");
6+ you may not use this file except in compliance with the License.
7+ You may obtain a copy of the License at
8+
9+ http://www.apache.org/licenses/LICENSE-2.0
10+
11+ Unless required by applicable law or agreed to in writing, software
12+ distributed under the License is distributed on an "AS IS" BASIS,
13+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ See the License for the specific language governing permissions and
15+ limitations under the License.
16+ -->
17+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
18+ android:id="@+id/notificationbg"
19+ android:layout_width="match_parent"
20+ android:layout_height="match_parent"
21+ android:orientation="horizontal">
22+
23+ <LinearLayout
24+ android:paddingLeft="16dip"
25+ android:layout_width="0dip"
26+ android:layout_height="wrap_content"
27+ android:layout_weight="1"
28+ android:layout_gravity="center_vertical"
29+ android:orientation="vertical">
30+
31+ <TextView android:id="@+id/notification_title"
32+ style="@android:style/TextAppearance.StatusBar.EventContent.Title"
33+ android:focusable="true"
34+ android:ellipsize="marquee"
35+ android:singleLine="true"
36+ android:layout_gravity="left"
37+ android:layout_width="match_parent"
38+ android:layout_height="wrap_content" />
39+
40+ <TextView android:id="@+id/notification_subtitle"
41+ style="@android:style/TextAppearance.StatusBar.EventContent"
42+ android:layout_gravity="left"
43+ android:maxLines="2"
44+ android:scrollHorizontally="true"
45+ android:ellipsize="end"
46+ android:layout_width="match_parent"
47+ android:layout_height="wrap_content"
48+ android:text="@string/notification_text" />
49+
50+ </LinearLayout>
51+
52+ <ImageButton
53+ android:id="@+id/notification_button"
54+ android:src="@drawable/btn_notification_ic_example"
55+ android:background="@null"
56+ android:layout_weight="0"
57+ android:layout_width="48dip"
58+ android:layout_height="match_parent" />
59+
60+</LinearLayout>
--- a/samples/Honeycomb-Gallery/res/menu/main_menu.xml
+++ b/samples/Honeycomb-Gallery/res/menu/main_menu.xml
@@ -18,16 +18,23 @@
1818 <menu xmlns:android="http://schemas.android.com/apk/res/android">
1919 <item android:id="@+id/camera"
2020 android:title="Camera"
21- android:icon="@drawable/ic_menu_camera"
21+ android:icon="?attr/menuIconCamera"
2222 android:showAsAction="ifRoom" />
2323 <item android:id="@+id/toggleTitles"
24- android:icon="@drawable/ic_menu_toggle"
24+ android:icon="?attr/menuIconToggle"
2525 android:title="Toggle Titles"
2626 android:showAsAction="ifRoom|withText" />
27+ <!-- Example of items in the overflow menu -->
2728 <item android:id="@+id/toggleTheme"
2829 android:title="Day/Night"
29- android:showAsAction="ifRoom|withText" />
30+ android:showAsAction="never" />
3031 <item android:id="@+id/showDialog"
31- android:title="Show a dialog"
32- android:showAsAction="ifRoom|withText" />
32+ android:title="Show a dialog"
33+ android:showAsAction="never" />
34+ <item android:id="@+id/showStandardNotification"
35+ android:title="Show a basic notification"
36+ android:showAsAction="never" />
37+ <item android:id="@+id/showCustomNotification"
38+ android:title="Show a custom notification"
39+ android:showAsAction="never" />
3340 </menu>
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/menu/photo_context_menu.xml
@@ -0,0 +1,23 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!--
3+ Copyright (C) 2011 The Android Open Source Project
4+
5+ Licensed under the Apache License, Version 2.0 (the "License");
6+ you may not use this file except in compliance with the License.
7+ You may obtain a copy of the License at
8+
9+ http://www.apache.org/licenses/LICENSE-2.0
10+
11+ Unless required by applicable law or agreed to in writing, software
12+ distributed under the License is distributed on an "AS IS" BASIS,
13+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ See the License for the specific language governing permissions and
15+ limitations under the License.
16+ -->
17+
18+<menu xmlns:android="http://schemas.android.com/apk/res/android">
19+ <item android:id="@+id/share"
20+ android:title="Share"
21+ android:icon="?attr/menuIconShare"
22+ android:showAsAction="always|withText" />
23+</menu>
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/values/attrs.xml
@@ -0,0 +1,24 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!--
3+ Copyright (C) 2011 The Android Open Source Project
4+
5+ Licensed under the Apache License, Version 2.0 (the "License");
6+ you may not use this file except in compliance with the License.
7+ You may obtain a copy of the License at
8+
9+ http://www.apache.org/licenses/LICENSE-2.0
10+
11+ Unless required by applicable law or agreed to in writing, software
12+ distributed under the License is distributed on an "AS IS" BASIS,
13+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ See the License for the specific language governing permissions and
15+ limitations under the License.
16+ -->
17+<resources>
18+ <declare-styleable name="AppTheme">
19+ <attr name="listDragShadowBackground" format="reference" />
20+ <attr name="menuIconCamera" format="reference" />
21+ <attr name="menuIconToggle" format="reference" />
22+ <attr name="menuIconShare" format="reference" />
23+ </declare-styleable>
24+</resources>
--- a/samples/Honeycomb-Gallery/res/values/colors.xml
+++ b/samples/Honeycomb-Gallery/res/values/colors.xml
@@ -17,4 +17,5 @@
1717 <resources>
1818 <color name="actionbar_background_light">#ccffffff</color>
1919 <color name="actionbar_background_dark">#cc000000</color>
20+ <color name="drag_active_color">#80cccccc</color>
2021 </resources>
--- a/samples/Honeycomb-Gallery/res/values/strings.xml
+++ b/samples/Honeycomb-Gallery/res/values/strings.xml
@@ -15,10 +15,14 @@
1515 limitations under the License.
1616 -->
1717 <resources>
18- <string name="app_name">Honeycomb Example</string>
18+ <string name="app_name">Honeycomb Gallery</string>
1919 <string name="camera_sample">Camera Example</string>
2020 <string name="clip_label">Clip Label</string>
2121
2222 <string name="app_widget_name">Honeycomb Example Widget</string>
2323 <string name="widget_empty_view_text">Touch to show data</string>
24+
25+ <string name="notification_text">Example notification text</string>
26+
27+ <string name="photo_selection_cab_title">Photo selection</string>
2428 </resources>
--- /dev/null
+++ b/samples/Honeycomb-Gallery/res/values/styles.xml
@@ -0,0 +1,45 @@
1+<?xml version="1.0" encoding="utf-8"?>
2+<!--
3+ Copyright (C) 2011 The Android Open Source Project
4+
5+ Licensed under the Apache License, Version 2.0 (the "License");
6+ you may not use this file except in compliance with the License.
7+ You may obtain a copy of the License at
8+
9+ http://www.apache.org/licenses/LICENSE-2.0
10+
11+ Unless required by applicable law or agreed to in writing, software
12+ distributed under the License is distributed on an "AS IS" BASIS,
13+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ See the License for the specific language governing permissions and
15+ limitations under the License.
16+ -->
17+<resources>
18+ <style name="ActionBar" parent="@android:style/Widget.Holo.ActionBar" />
19+
20+ <style name="ActionBar.Light" parent="@style/ActionBar">
21+ <item name="android:background">@color/actionbar_background_light</item>
22+ </style>
23+
24+ <style name="ActionBar.Dark" parent="@style/ActionBar">
25+ <item name="android:background">@color/actionbar_background_dark</item>
26+ </style>
27+
28+ <style name="AppTheme.Light" parent="@android:style/Theme.Holo.Light">
29+ <item name="android:actionBarStyle">@style/ActionBar.Light</item>
30+ <item name="android:windowActionBarOverlay">true</item>
31+ <item name="listDragShadowBackground">@android:color/background_light</item>
32+ <item name="menuIconCamera">@drawable/ic_menu_camera_holo_light</item>
33+ <item name="menuIconToggle">@drawable/ic_menu_toggle_holo_light</item>
34+ <item name="menuIconShare">@drawable/ic_menu_share_holo_light</item>
35+ </style>
36+
37+ <style name="AppTheme.Dark" parent="@android:style/Theme.Holo">
38+ <item name="android:actionBarStyle">@style/ActionBar.Dark</item>
39+ <item name="android:windowActionBarOverlay">true</item>
40+ <item name="listDragShadowBackground">@android:color/background_dark</item>
41+ <item name="menuIconCamera">@drawable/ic_menu_camera_holo_dark</item>
42+ <item name="menuIconToggle">@drawable/ic_menu_toggle_holo_dark</item>
43+ <item name="menuIconShare">@drawable/ic_menu_share_holo_dark</item>
44+ </style>
45+</resources>
--- 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 @@
1616
1717 package com.example.android.hcgallery;
1818
19-import java.util.StringTokenizer;
20-
2119 import android.app.ActionBar;
20+import android.app.Activity;
2221 import android.app.Fragment;
2322 import android.content.ClipData;
24-import android.content.ClipDescription;
2523 import android.content.ClipData.Item;
24+import android.content.ClipDescription;
25+import android.content.Intent;
2626 import android.graphics.Bitmap;
2727 import android.graphics.Color;
28+import android.net.Uri;
29+import android.os.AsyncTask;
2830 import android.os.Bundle;
31+import android.view.ActionMode;
2932 import android.view.DragEvent;
3033 import android.view.LayoutInflater;
34+import android.view.Menu;
35+import android.view.MenuInflater;
36+import android.view.MenuItem;
3137 import android.view.View;
32-import android.view.ViewGroup;
3338 import android.view.View.OnClickListener;
39+import android.view.ViewGroup;
3440 import android.widget.ImageView;
35-import android.view.Window;
36-import android.view.WindowManager;
41+import android.widget.Toast;
42+
43+import java.io.File;
44+import java.io.FileNotFoundException;
45+import java.io.FileOutputStream;
46+import java.io.IOException;
47+import java.util.StringTokenizer;
3748
3849 public class ContentFragment extends Fragment {
50+ private View mContentView;
51+
3952 // The bitmap currently used by ImageView
4053 private Bitmap mBitmap = null;
4154
55+ // Current action mode (contextual action bar, a.k.a. CAB)
56+ private ActionMode mCurrentActionMode;
57+
4258 @Override
4359 public void onActivityCreated(Bundle savedInstanceState) {
4460 super.onActivityCreated(savedInstanceState);
@@ -47,47 +63,86 @@ public class ContentFragment extends Fragment {
4763 @Override
4864 public View onCreateView(LayoutInflater inflater, ViewGroup container,
4965 Bundle savedInstanceState) {
50- final View view = inflater.inflate(R.layout.content_welcome, null);
51- final ImageView imageView = (ImageView) view.findViewById(R.id.image);
52- view.setDrawingCacheEnabled(false);
66+ mContentView = inflater.inflate(R.layout.content_welcome, null);
67+ final ImageView imageView = (ImageView) mContentView.findViewById(R.id.image);
68+ mContentView.setDrawingCacheEnabled(false);
5369
54- view.setOnDragListener(new View.OnDragListener() {
70+ mContentView.setOnDragListener(new View.OnDragListener() {
5571 public boolean onDrag(View v, DragEvent event) {
5672 switch (event.getAction()) {
57- case DragEvent.ACTION_DRAG_ENTERED:
58- view.setBackgroundColor(Color.LTGRAY);
59- break;
60- case DragEvent.ACTION_DRAG_EXITED:
61- view.setBackgroundColor(Color.TRANSPARENT);
62- break;
63- case DragEvent.ACTION_DRAG_STARTED:
64- return processDragStarted(event);
65- case DragEvent.ACTION_DROP:
66- view.setBackgroundColor(Color.TRANSPARENT);
67- return processDrop(event, imageView);
73+ case DragEvent.ACTION_DRAG_ENTERED:
74+ mContentView.setBackgroundColor(
75+ getResources().getColor(R.color.drag_active_color));
76+ break;
77+
78+ case DragEvent.ACTION_DRAG_EXITED:
79+ mContentView.setBackgroundColor(Color.TRANSPARENT);
80+ break;
81+
82+ case DragEvent.ACTION_DRAG_STARTED:
83+ return processDragStarted(event);
84+
85+ case DragEvent.ACTION_DROP:
86+ mContentView.setBackgroundColor(Color.TRANSPARENT);
87+ return processDrop(event, imageView);
6888 }
6989 return false;
7090 }
7191 });
7292
73- view.setOnClickListener(new OnClickListener() {
93+ // Keep the action bar visibility in sync with the system status bar. That is, when entering
94+ // 'lights out mode,' hide the action bar, and when exiting this mode, show the action bar.
95+
96+ final Activity activity = getActivity();
97+ mContentView.setOnSystemUiVisibilityChangeListener(
98+ new View.OnSystemUiVisibilityChangeListener() {
99+ public void onSystemUiVisibilityChange(int visibility) {
100+ ActionBar actionBar = activity.getActionBar();
101+ if (actionBar != null) {
102+ mContentView.setSystemUiVisibility(visibility);
103+ if (visibility == View.STATUS_BAR_VISIBLE) {
104+ actionBar.show();
105+ } else {
106+ actionBar.hide();
107+ }
108+ }
109+ }
110+ });
74111
112+ // Show/hide the system status bar when single-clicking a photo. This is also called
113+ // 'lights out mode.' Activating and deactivating this mode also invokes the listener
114+ // defined above, which will show or hide the action bar accordingly.
75115
116+ mContentView.setOnClickListener(new OnClickListener() {
76117 public void onClick(View v) {
77- ActionBar bar = getActivity().getActionBar();
78- if (bar != null) {
79- if (bar.isShowing()) {
80- bar.hide();
81- } else {
82- bar.show();
83- }
118+ if (mContentView.getSystemUiVisibility() == View.STATUS_BAR_VISIBLE) {
119+ mContentView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
120+ } else {
121+ mContentView.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
84122 }
85123 }
86124 });
87- return view;
125+
126+ // When long-pressing a photo, activate the action mode for selection, showing the
127+ // contextual action bar (CAB).
128+
129+ mContentView.setOnLongClickListener(new View.OnLongClickListener() {
130+ public boolean onLongClick(View view) {
131+ if (mCurrentActionMode != null) {
132+ return false;
133+ }
134+
135+ mCurrentActionMode = getActivity().startActionMode(
136+ mContentSelectionActionModeCallback);
137+ mContentView.setSelected(true);
138+ return true;
139+ }
140+ });
141+
142+ return mContentView;
88143 }
89144
90- boolean processDragStarted(DragEvent event) {
145+ boolean processDragStarted(DragEvent event) {
91146 // Determine whether to continue processing drag and drop based on the
92147 // plain text mime type.
93148 ClipDescription clipDesc = event.getClipDescription();
@@ -97,7 +152,7 @@ public class ContentFragment extends Fragment {
97152 return false;
98153 }
99154
100- private boolean processDrop(DragEvent event, ImageView imageView) {
155+ boolean processDrop(DragEvent event, ImageView imageView) {
101156 // Attempt to parse clip data with expected format: category||entry_id.
102157 // Ignore event if data does not conform to this format.
103158 ClipData data = event.getClipData();
@@ -130,16 +185,115 @@ public class ContentFragment extends Fragment {
130185 return false;
131186 }
132187
133- public void updateContentAndRecycleBitmap(int category, int position) {
134- // Get the bitmap that needs to be drawn and update the ImageView
135- Bitmap next = Directory.getCategory(category).getEntry(position)
136- .getBitmap(getResources());
137- ((ImageView) getView().findViewById(R.id.image)).setImageBitmap(next);
188+ void updateContentAndRecycleBitmap(int category, int position) {
189+ if (mCurrentActionMode != null) {
190+ mCurrentActionMode.finish();
191+ }
192+
138193 if (mBitmap != null) {
139194 // This is an advanced call and should be used if you
140195 // are working with a lot of bitmaps. The bitmap is dead
141196 // after this call.
142197 mBitmap.recycle();
143198 }
199+
200+ // Get the bitmap that needs to be drawn and update the ImageView
201+ mBitmap = Directory.getCategory(category).getEntry(position)
202+ .getBitmap(getResources());
203+ ((ImageView) getView().findViewById(R.id.image)).setImageBitmap(mBitmap);
204+ }
205+
206+ void shareCurrentPhoto() {
207+ File externalCacheDir = getActivity().getExternalCacheDir();
208+ if (externalCacheDir == null) {
209+ Toast.makeText(getActivity(), "Error writing to USB/external storage.",
210+ Toast.LENGTH_SHORT).show();
211+ return;
212+ }
213+
214+ // Prevent media scanning of the cache directory.
215+ final File noMediaFile = new File(externalCacheDir, ".nomedia");
216+ try {
217+ noMediaFile.createNewFile();
218+ } catch (IOException e) {
219+ }
220+
221+ // Write the bitmap to temporary storage in the external storage directory (e.g. SD card).
222+ // We perform the actual disk write operations on a separate thread using the
223+ // {@link AsyncTask} class, thus avoiding the possibility of stalling the main (UI) thread.
224+
225+ final File tempFile = new File(externalCacheDir, "tempfile.jpg");
226+
227+ new AsyncTask<Void, Void, Boolean>() {
228+ /**
229+ * Compress and write the bitmap to disk on a separate thread.
230+ * @return TRUE if the write was successful, FALSE otherwise.
231+ */
232+ protected Boolean doInBackground(Void... voids) {
233+ try {
234+ FileOutputStream fo = new FileOutputStream(tempFile, false);
235+ if (!mBitmap.compress(Bitmap.CompressFormat.JPEG, 60, fo)) {
236+ Toast.makeText(getActivity(), "Error writing bitmap data.",
237+ Toast.LENGTH_SHORT).show();
238+ return Boolean.FALSE;
239+ }
240+ return Boolean.TRUE;
241+
242+ } catch (FileNotFoundException e) {
243+ Toast.makeText(getActivity(), "Error writing to USB/external storage.",
244+ Toast.LENGTH_SHORT).show();
245+ return Boolean.FALSE;
246+ }
247+ }
248+
249+ /**
250+ * After doInBackground completes (either successfully or in failure), we invoke an
251+ * intent to share the photo. This code is run on the main (UI) thread.
252+ */
253+ protected void onPostExecute(Boolean result) {
254+ if (result != Boolean.TRUE) {
255+ return;
256+ }
257+
258+ Intent shareIntent = new Intent(Intent.ACTION_SEND);
259+ shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
260+ shareIntent.setType("image/jpeg");
261+ startActivity(Intent.createChooser(shareIntent, "Share photo"));
262+ }
263+ }.execute();
144264 }
265+
266+ /**
267+ * The callback for the 'photo selected' {@link ActionMode}. In this action mode, we can
268+ * provide contextual actions for the selected photo. We currently only provide the 'share'
269+ * action, but we could also add clipboard functions such as cut/copy/paste here as well.
270+ */
271+ private ActionMode.Callback mContentSelectionActionModeCallback = new ActionMode.Callback() {
272+ public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
273+ actionMode.setTitle(R.string.photo_selection_cab_title);
274+
275+ MenuInflater inflater = getActivity().getMenuInflater();
276+ inflater.inflate(R.menu.photo_context_menu, menu);
277+ return true;
278+ }
279+
280+ public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
281+ return false;
282+ }
283+
284+ public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
285+ switch (menuItem.getItemId()) {
286+ case R.id.share:
287+ shareCurrentPhoto();
288+ actionMode.finish();
289+ return true;
290+ }
291+ return false;
292+ }
293+
294+ public void onDestroyActionMode(ActionMode actionMode) {
295+ mContentView.setSelected(false);
296+ mCurrentActionMode = null;
297+ }
298+ };
145299 }
--- /dev/null
+++ b/samples/Honeycomb-Gallery/src/com/example/android/hcgallery/FitCenterFrameLayout.java
@@ -0,0 +1,108 @@
1+/*
2+ * Copyright (C) 2011 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.hcgallery;
18+
19+import android.content.Context;
20+import android.util.AttributeSet;
21+import android.view.View;
22+import android.view.ViewGroup;
23+
24+/**
25+ * A simple layout that fits and centers each child view, maintaining aspect ratio.
26+ */
27+public class FitCenterFrameLayout extends ViewGroup {
28+ public FitCenterFrameLayout(Context context) {
29+ super(context);
30+ }
31+
32+ public FitCenterFrameLayout(Context context, AttributeSet attrs) {
33+ super(context, attrs);
34+ }
35+
36+ @Override
37+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
38+ // We purposely disregard child measurements.
39+ final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
40+ final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
41+ setMeasuredDimension(width, height);
42+
43+ int childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.UNSPECIFIED);
44+ int childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED);
45+
46+ int childCount = getChildCount();
47+ for (int i = 0; i < childCount; i++) {
48+ getChildAt(i).measure(childWidthSpec, childHeightSpec);
49+ }
50+ }
51+
52+ @Override
53+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
54+ final int childCount = getChildCount();
55+
56+ final int parentLeft = getPaddingLeft();
57+ final int parentTop = getPaddingTop();
58+ final int parentRight = r - l - getPaddingRight();
59+ final int parentBottom = b - t - getPaddingBottom();
60+
61+ final int parentWidth = parentRight - parentLeft;
62+ final int parentHeight = parentBottom - parentTop;
63+
64+ int unpaddedWidth, unpaddedHeight, parentUnpaddedWidth, parentUnpaddedHeight;
65+ int childPaddingLeft, childPaddingTop, childPaddingRight, childPaddingBottom;
66+
67+ for (int i = 0; i < childCount; i++) {
68+ final View child = getChildAt(i);
69+ if (child.getVisibility() == GONE) {
70+ continue;
71+ }
72+
73+ // Fit and center the child within the parent. Make sure not to consider padding
74+ // as part of the child's aspect ratio.
75+
76+ childPaddingLeft = child.getPaddingLeft();
77+ childPaddingTop = child.getPaddingTop();
78+ childPaddingRight = child.getPaddingRight();
79+ childPaddingBottom = child.getPaddingBottom();
80+
81+ unpaddedWidth = child.getMeasuredWidth() - childPaddingLeft - childPaddingRight;
82+ unpaddedHeight = child.getMeasuredHeight() - childPaddingTop - childPaddingBottom;
83+
84+ parentUnpaddedWidth = parentWidth - childPaddingLeft - childPaddingRight;
85+ parentUnpaddedHeight = parentHeight - childPaddingTop - childPaddingBottom;
86+
87+ if (parentUnpaddedWidth * unpaddedHeight > parentUnpaddedHeight * unpaddedWidth) {
88+ // The child view should be left/right letterboxed.
89+ final int scaledChildWidth = unpaddedWidth * parentUnpaddedHeight
90+ / unpaddedHeight + childPaddingLeft + childPaddingRight;
91+ child.layout(
92+ parentLeft + (parentWidth - scaledChildWidth) / 2,
93+ parentTop,
94+ parentRight - (parentWidth - scaledChildWidth) / 2,
95+ parentBottom);
96+ } else {
97+ // The child view should be top/bottom letterboxed.
98+ final int scaledChildHeight = unpaddedHeight * parentUnpaddedWidth
99+ / unpaddedWidth + childPaddingTop + childPaddingBottom;
100+ child.layout(
101+ parentLeft,
102+ parentTop + (parentHeight - scaledChildHeight) / 2,
103+ parentRight,
104+ parentTop + (parentHeight + scaledChildHeight) / 2);
105+ }
106+ }
107+ }
108+}
--- 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;
2828 import android.app.DialogFragment;
2929 import android.app.FragmentManager;
3030 import android.app.FragmentTransaction;
31+import android.app.Notification;
32+import android.app.NotificationManager;
33+import android.app.PendingIntent;
3134 import android.content.DialogInterface;
3235 import android.content.Intent;
3336 import android.content.res.Configuration;
34-import android.graphics.drawable.ColorDrawable;
37+import android.content.res.Resources;
38+import android.graphics.Bitmap;
39+import android.graphics.BitmapFactory;
3540 import android.os.Bundle;
3641 import android.view.Menu;
3742 import android.view.MenuInflater;
@@ -39,9 +44,13 @@ import android.view.MenuItem;
3944 import android.view.View;
4045 import android.view.ViewGroup;
4146 import android.view.Window;
47+import android.widget.RemoteViews;
4248
4349 public class MainActivity extends Activity implements ActionBar.TabListener {
4450
51+ private static final int NOTIFICATION_DEFAULT = 1;
52+ private static final String ACTION_DIALOG = "com.example.android.hcgallery.action.DIALOG";
53+
4554 private View mActionBarView;
4655 private Animator mCurrentTitlesAnimator;
4756 private String[] mToggleLabels = {"Show Titles", "Hide Titles"};
@@ -51,26 +60,18 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
5160 @Override
5261 public void onCreate(Bundle savedInstanceState) {
5362 super.onCreate(savedInstanceState);
63+
5464 if(savedInstanceState != null && savedInstanceState.getInt("theme", -1) != -1) {
5565 mThemeId = savedInstanceState.getInt("theme");
5666 this.setTheme(mThemeId);
5767 }
5868
59- requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
6069 setContentView(R.layout.main);
6170
6271 Directory.initializeDirectory();
6372
6473 ActionBar bar = getActionBar();
6574
66- if (mThemeId == android.R.style.Theme_Holo_Light || mThemeId == -1) {
67- bar.setBackgroundDrawable(
68- new ColorDrawable(getResources().getColor(R.color.actionbar_background_light)));
69- } else {
70- bar.setBackgroundDrawable(
71- new ColorDrawable(getResources().getColor(R.color.actionbar_background_dark)));
72- }
73-
7475 int i;
7576 for (i = 0; i < Directory.getCategoryCount(); i++) {
7677 bar.addTab(bar.newTab().setText(Directory.getCategory(i).getName())
@@ -122,21 +123,30 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
122123 intent.putExtra("theme", mThemeId);
123124 startActivity(intent);
124125 return true;
126+
125127 case R.id.toggleTitles:
126128 toggleVisibleTitles();
127129 return true;
128130
129131 case R.id.toggleTheme:
130- if (mThemeId == android.R.style.Theme_Holo) {
131- mThemeId = android.R.style.Theme_Holo_Light;
132+ if (mThemeId == R.style.AppTheme_Dark) {
133+ mThemeId = R.style.AppTheme_Light;
132134 } else {
133- mThemeId = android.R.style.Theme_Holo;
135+ mThemeId = R.style.AppTheme_Dark;
134136 }
135137 this.recreate();
136138 return true;
137139
138140 case R.id.showDialog:
139- showDialog();
141+ showDialog("This is indeed an awesome dialog.");
142+ return true;
143+
144+ case R.id.showStandardNotification:
145+ showNotification(false);
146+ return true;
147+
148+ case R.id.showCustomNotification:
149+ showNotification(true);
140150 return true;
141151
142152 default:
@@ -225,21 +235,84 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
225235 mCurrentTitlesAnimator = objectAnimator;
226236
227237 invalidateOptionsMenu();
238+
239+ // Manually trigger onNewIntent to check for ACTION_DIALOG.
240+ onNewIntent(getIntent());
228241 }
229242
230- void showDialog() {
243+ @Override
244+ protected void onNewIntent(Intent intent) {
245+ if (ACTION_DIALOG.equals(intent.getAction())) {
246+ showDialog(intent.getStringExtra(Intent.EXTRA_TEXT));
247+ }
248+ }
231249
250+ void showDialog(String text) {
232251 // DialogFragment.show() will take care of adding the fragment
233252 // in a transaction. We also want to remove any currently showing
234253 // dialog, so make our own transaction and take care of that here.
235254 FragmentTransaction ft = getFragmentManager().beginTransaction();
236255
237- DialogFragment newFragment = MyDialogFragment.newInstance("The Dialog Of Awesome");
256+ DialogFragment newFragment = MyDialogFragment.newInstance(text);
238257
239- // Create and show the dialog.
258+ // Show the dialog.
240259 newFragment.show(ft, "dialog");
241260 }
242261
262+ void showNotification(boolean custom) {
263+ final Resources res = getResources();
264+ final NotificationManager notificationManager = (NotificationManager) getSystemService(
265+ NOTIFICATION_SERVICE);
266+
267+ Notification.Builder builder = new Notification.Builder(this)
268+ .setSmallIcon(R.drawable.ic_stat_notify_example)
269+ .setAutoCancel(true)
270+ .setTicker(getString(R.string.notification_text))
271+ .setContentIntent(getDialogPendingIntent("Tapped the notification entry."));
272+
273+ if (custom) {
274+ // Sets a custom content view for the notification, including an image button.
275+ RemoteViews layout = new RemoteViews(getPackageName(), R.layout.notification);
276+ layout.setTextViewText(R.id.notification_title, getString(R.string.app_name));
277+ layout.setOnClickPendingIntent(R.id.notification_button,
278+ getDialogPendingIntent("Tapped the 'dialog' button in the notification."));
279+ builder.setContent(layout);
280+
281+ // Notifications in Android 3.0 now have a standard mechanism for displaying large
282+ // bitmaps such as contact avatars. Here, we load an example image and resize it to the
283+ // appropriate size for large bitmaps in notifications.
284+ Bitmap largeIconTemp = BitmapFactory.decodeResource(res,
285+ R.drawable.notification_default_largeicon);
286+ Bitmap largeIcon = Bitmap.createScaledBitmap(
287+ largeIconTemp,
288+ res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
289+ res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height),
290+ false);
291+ largeIconTemp.recycle();
292+
293+ builder.setLargeIcon(largeIcon);
294+
295+ } else {
296+ builder
297+ .setNumber(7) // An example number.
298+ .setContentTitle(getString(R.string.app_name))
299+ .setContentText(getString(R.string.notification_text));
300+ }
301+
302+ notificationManager.notify(NOTIFICATION_DEFAULT, builder.getNotification());
303+ }
304+
305+ PendingIntent getDialogPendingIntent(String dialogText) {
306+ return PendingIntent.getActivity(
307+ this,
308+ dialogText.hashCode(), // Otherwise previous PendingIntents with the same
309+ // requestCode may be overwritten.
310+ new Intent(ACTION_DIALOG)
311+ .putExtra(Intent.EXTRA_TEXT, dialogText)
312+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
313+ 0);
314+ }
315+
243316 @Override
244317 public boolean onPrepareOptionsMenu(Menu menu) {
245318 menu.getItem(1).setTitle(mToggleLabels[mLabelIndex]);
@@ -261,24 +334,19 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
261334 public static MyDialogFragment newInstance(String title) {
262335 MyDialogFragment frag = new MyDialogFragment();
263336 Bundle args = new Bundle();
264- args.putString("title", title);
337+ args.putString("text", title);
265338 frag.setArguments(args);
266339 return frag;
267340 }
268341
269342 @Override
270343 public Dialog onCreateDialog(Bundle savedInstanceState) {
271- String title = getArguments().getString("title");
344+ String text = getArguments().getString("text");
272345
273346 return new AlertDialog.Builder(getActivity())
274- .setTitle(title)
275- .setPositiveButton("OK",
276- new DialogInterface.OnClickListener() {
277- public void onClick(DialogInterface dialog, int whichButton) {
278- }
279- }
280- )
281- .setNegativeButton("Cancel",
347+ .setTitle("A Dialog of Awesome")
348+ .setMessage(text)
349+ .setPositiveButton(android.R.string.ok,
282350 new DialogInterface.OnClickListener() {
283351 public void onClick(DialogInterface dialog, int whichButton) {
284352 }
--- 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;
2020 import android.app.FragmentManager;
2121 import android.app.ListFragment;
2222 import android.content.ClipData;
23+import android.content.res.Resources;
24+import android.content.res.TypedArray;
2325 import android.graphics.Canvas;
2426 import android.graphics.Color;
2527 import android.graphics.drawable.ColorDrawable;
@@ -28,6 +30,7 @@ import android.graphics.Paint;
2830 import android.graphics.Typeface;
2931 import android.os.Bundle;
3032 import android.text.TextPaint;
33+import android.util.TypedValue;
3134 import android.view.View;
3235 import android.widget.AdapterView;
3336 import android.widget.ArrayAdapter;
@@ -53,47 +56,40 @@ public class TitlesFragment extends ListFragment {
5356 populateTitles(mCategory);
5457 ListView lv = getListView();
5558 lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
56- selectPosition(mCurPosition);
57- lv.setCacheColorHint(Color.WHITE);
59+ lv.setCacheColorHint(Color.TRANSPARENT);
5860 lv.setOnItemLongClickListener(new OnItemLongClickListener() {
59-
60- public boolean onItemLongClick(AdapterView<?> av, View v, int pos,
61- long id) {
61+ public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
6262 final String title = (String) ((TextView) v).getText();
6363
6464 // Set up clip data with the category||entry_id format.
6565 final String textData = String.format("%d||%d", mCategory, pos);
6666 ClipData data = ClipData.newPlainText(title, textData);
67-
68- v.startDrag(data, new MyDragShadowBuilder(v, title), null, 0);
67+ v.startDrag(data, new MyDragShadowBuilder(v), null, 0);
6968 return true;
7069 }
7170 });
71+
72+ selectPosition(mCurPosition);
7273 }
7374
74- private static class MyDragShadowBuilder extends View.DragShadowBuilder {
75- private static Drawable mShadow;
76- private static String mLabel;
77- private static int mViewHeight;
78-
79- public MyDragShadowBuilder(View v, String label) {
75+ private class MyDragShadowBuilder extends View.DragShadowBuilder {
76+ private Drawable mShadow;
77+
78+ public MyDragShadowBuilder(View v) {
8079 super(v);
81- mShadow = new ColorDrawable(Color.BLUE);
80+
81+ final TypedArray a = v.getContext().obtainStyledAttributes(R.styleable.AppTheme);
82+ mShadow = a.getDrawable(R.styleable.AppTheme_listDragShadowBackground);
83+ mShadow.setCallback(v);
8284 mShadow.setBounds(0, 0, v.getWidth(), v.getHeight());
83- mLabel = label;
84- mViewHeight = v.getHeight();
85+ a.recycle();
8586 }
8687
8788 @Override
8889 public void onDrawShadow(Canvas canvas) {
8990 super.onDrawShadow(canvas);
9091 mShadow.draw(canvas);
91- Paint paint = new TextPaint();
92- paint.setTextSize(20);
93- paint.setColor(Color.LTGRAY);
94- paint.setTypeface(Typeface.DEFAULT_BOLD);
95- paint.setAntiAlias(true);
96- canvas.drawText(mLabel, 20, (float) (mViewHeight * .6), paint);
92+ getView().draw(canvas);
9793 }
9894 }
9995
@@ -116,13 +112,13 @@ public class TitlesFragment extends ListFragment {
116112 ContentFragment frag = (ContentFragment) getFragmentManager()
117113 .findFragmentById(R.id.frag_content);
118114 frag.updateContentAndRecycleBitmap(mCategory, position);
115+ mCurPosition = position;
119116 }
120117
121118 public void selectPosition(int position) {
122119 ListView lv = getListView();
123120 lv.setItemChecked(position, true);
124121 updateImage(position);
125-
126122 }
127123
128124 @Override