Merge "Added Honeycomb Gallery sample application." into honeycomb
@@ -160,6 +160,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/JetBoy samples/${PLATFORM_NAME}/JetBoy
|
||||
development/samples/LunarLander samples/${PLATFORM_NAME}/LunarLander
|
||||
development/samples/MultiResolution samples/${PLATFORM_NAME}/MultiResolution
|
||||
|
||||
16
samples/Honeycomb-Gallery/Android.mk
Normal file
@@ -0,0 +1,16 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
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_SDK_VERSION := current
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
|
||||
# Use the following include to make our test apk.
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
||||
58
samples/Honeycomb-Gallery/AndroidManifest.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.android.hcgallery" android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-sdk android:minSdkVersion="Honeycomb" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<application android:label="@string/app_name"
|
||||
android:icon="@drawable/icon"
|
||||
android:logo="@drawable/logo"
|
||||
android:theme="@android:style/Theme.Holo.Light"
|
||||
android:hardwareAccelerated="true"
|
||||
android:debuggable="true">
|
||||
|
||||
<activity android:name=".MainActivity" android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- CameraSample -->
|
||||
<activity android:name=".CameraSample"
|
||||
android:label="@string/camera_sample"
|
||||
android:screenOrientation="landscape" />
|
||||
|
||||
<!-- StackView widget sample code -->
|
||||
<receiver android:name=".widget.WidgetProvider"
|
||||
android:label="@string/app_widget_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_info" />
|
||||
</receiver>
|
||||
<service android:name=".widget.WidgetService"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
37
samples/Honeycomb-Gallery/_index.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<p>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.</p>
|
||||
|
||||
<p>The application includes the following classes:<p>
|
||||
<ul>
|
||||
<li><a href="src/com/example/android/hcgallery/ContentFragment.html">ContentFragment</a>
|
||||
A fragment responsible for containing the "content" of the application.
|
||||
Displays images, receives drag/drop events from other fragments.</li>
|
||||
<li><a href="src/com/example/android/hcgallery/TitlesFragment.html">TitlesFragment</a>
|
||||
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
|
||||
list to the content area. The list of photos displayed depends on the
|
||||
category selected in the ActionBar.</li>
|
||||
<li><a href="src/com/example/android/hcgallery/MainActivity.html">MainActivity</a>
|
||||
This is the main entry point of the application. MainActivity is
|
||||
responsible for initialization of the ActionBar, TitlesFragment, and
|
||||
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).
|
||||
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
|
||||
in your application.</li>
|
||||
<li><a href="src/com/example/android/hcgallery/widget/WidgetProvider.html">WidgetProvider</a>
|
||||
The WidgetProvider class is an implementation of the AppWidgetProvider
|
||||
class, which is a view that can be embedded in other applications.
|
||||
This class is responsible for handling when the instance of this widget
|
||||
is enabled, disabled, created, deleted, or updated.</li>
|
||||
<li><a href="src/com/example/android/hcgallery/widget/WidgetService.html">WidgetService</a>
|
||||
The WidgetService is an implementation of the RemoteViewsService class,
|
||||
which is used to populate the collection view (in this case, a stack
|
||||
widget)</li> </ul>
|
||||
|
||||
<img alt="Screenshot" src="../images/hcgallery.png" />
|
||||
BIN
samples/Honeycomb-Gallery/res/drawable-hdpi/android_logo.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_camera.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-hdpi/ic_menu_toggle.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-hdpi/icon.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-hdpi/logo.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-ldpi/icon.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_camera.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-mdpi/ic_menu_toggle.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-mdpi/icon.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-mdpi/logo.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/big_droid.JPG
Normal file
|
After Width: | Height: | Size: 178 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/blue_balloon.JPG
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/blue_bike.JPG
Normal file
|
After Width: | Height: | Size: 220 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/chrome_wheel.JPG
Normal file
|
After Width: | Height: | Size: 189 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/cupcake.JPG
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/donut.JPG
Normal file
|
After Width: | Height: | Size: 304 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/eclair.JPG
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/froyo.JPG
Normal file
|
After Width: | Height: | Size: 196 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/green_balloon.JPG
Normal file
|
After Width: | Height: | Size: 131 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/punk_droid.JPG
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/rainbow_bike.JPG
Normal file
|
After Width: | Height: | Size: 264 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/red_balloon.JPG
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/stargazer_droid.JPG
Normal file
|
After Width: | Height: | Size: 213 KiB |
BIN
samples/Honeycomb-Gallery/res/drawable-nodpi/widget_preview.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<gradient android:startColor="#ff666666" android:endColor="#ff333333" android:angle="270" />
|
||||
</shape>
|
||||
34
samples/Honeycomb-Gallery/res/layout-port/main.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/frags">
|
||||
|
||||
<fragment class="com.example.android.hcgallery.TitlesFragment"
|
||||
android:id="@+id/frag_title"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/titles_size"/>
|
||||
|
||||
<fragment class="com.example.android.hcgallery.ContentFragment"
|
||||
android:id="@+id/frag_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
24
samples/Honeycomb-Gallery/res/layout/action_bar_custom.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">Hello Action Bar</TextView>
|
||||
</LinearLayout>
|
||||
28
samples/Honeycomb-Gallery/res/layout/camera_sample.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<fragment android:name="com.example.android.hcgallery.CameraFragment"
|
||||
android:id="@+id/camera_frag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
||||
27
samples/Honeycomb-Gallery/res/layout/content_welcome.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="12dp">
|
||||
<ImageView android:id="@+id/image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_gravity="center" />
|
||||
</FrameLayout>
|
||||
34
samples/Honeycomb-Gallery/res/layout/main.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/frags">
|
||||
|
||||
<fragment class="com.example.android.hcgallery.TitlesFragment"
|
||||
android:id="@+id/frag_title"
|
||||
android:visibility="gone"
|
||||
android:layout_width="@dimen/titles_size"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<fragment class="com.example.android.hcgallery.ContentFragment"
|
||||
android:id="@+id/frag_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
25
samples/Honeycomb-Gallery/res/layout/title_list_item.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp"
|
||||
android:gravity="bottom"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:background="?android:attr/activatedBackgroundIndicator" >
|
||||
</TextView>
|
||||
25
samples/Honeycomb-Gallery/res/layout/widget_item.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/widget_item"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/widget_item_background"
|
||||
android:textColor="#ffffff"
|
||||
android:textStyle="bold"
|
||||
android:textSize="44sp" />
|
||||
36
samples/Honeycomb-Gallery/res/layout/widget_layout.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<StackView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/stack_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:loopViews="true" />
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/empty_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/widget_item_background"
|
||||
android:textColor="#ffffff"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/widget_empty_view_text"
|
||||
android:textSize="20sp" />
|
||||
</FrameLayout>
|
||||
20
samples/Honeycomb-Gallery/res/menu/camera_menu.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/switch_cam" android:title="Switch Camera" />
|
||||
</menu>
|
||||
30
samples/Honeycomb-Gallery/res/menu/main_menu.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/camera"
|
||||
android:title="Camera"
|
||||
android:icon="@drawable/ic_menu_camera"
|
||||
android:showAsAction="ifRoom" />
|
||||
<item android:id="@+id/toggleTitles"
|
||||
android:icon="@drawable/ic_menu_toggle"
|
||||
android:title="Toggle Titles"
|
||||
android:showAsAction="ifRoom|withText" />
|
||||
<item android:id="@+id/toggleTheme"
|
||||
android:title="Day/Night"
|
||||
android:showAsAction="ifRoom|withText" />
|
||||
</menu>
|
||||
19
samples/Honeycomb-Gallery/res/values-port/dimens.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<resources>
|
||||
<dimen name="titles_size">200dp</dimen>
|
||||
</resources>
|
||||
19
samples/Honeycomb-Gallery/res/values/dimens.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<resources>
|
||||
<dimen name="titles_size">300dp</dimen>
|
||||
</resources>
|
||||
24
samples/Honeycomb-Gallery/res/values/strings.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2010 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.
|
||||
-->
|
||||
<resources>
|
||||
<string name="app_name">Honeycomb Example</string>
|
||||
<string name="camera_sample">Camera Example</string>
|
||||
<string name="clip_label">Clip Label</string>
|
||||
|
||||
<string name="app_widget_name">Honeycomb Example Widget</string>
|
||||
<string name="widget_empty_view_text">Touch to show data</string>
|
||||
</resources>
|
||||
23
samples/Honeycomb-Gallery/res/xml/widget_info.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="150dp"
|
||||
android:minHeight="150dp"
|
||||
android:updatePeriodMillis="3600000"
|
||||
android:initialLayout="@layout/widget_layout"
|
||||
android:previewImage="@drawable/widget_preview"
|
||||
android:autoAdvanceViewId="@id/stack_view" />
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* 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 java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.Activity;
|
||||
import android.app.ActionBar;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.CameraInfo;
|
||||
import android.hardware.Camera.Size;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
public class CameraFragment extends Fragment {
|
||||
|
||||
private Preview mPreview;
|
||||
Camera mCamera;
|
||||
int mNumberOfCameras;
|
||||
int cameraCurrentlyLocked;
|
||||
|
||||
// The first rear facing camera
|
||||
int defaultCameraId;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Add an up arrow to the "home" button, indicating that the button will go "up"
|
||||
// one activity in the app's Activity heirarchy.
|
||||
Activity activity = this.getActivity();
|
||||
ActionBar actionBar = activity.getActionBar();
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// Create a RelativeLayout container that will hold a SurfaceView,
|
||||
// and set it as the content of our activity.
|
||||
mPreview = new Preview(this.getActivity());
|
||||
|
||||
// Find the total number of cameras available
|
||||
mNumberOfCameras = Camera.getNumberOfCameras();
|
||||
|
||||
// Find the ID of the default camera
|
||||
CameraInfo cameraInfo = new CameraInfo();
|
||||
for (int i = 0; i < mNumberOfCameras; i++) {
|
||||
Camera.getCameraInfo(i, cameraInfo);
|
||||
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
|
||||
defaultCameraId = i;
|
||||
}
|
||||
}
|
||||
setHasOptionsMenu(mNumberOfCameras > 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return mPreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
// Open the default i.e. the first rear facing camera.
|
||||
mCamera = Camera.open(defaultCameraId);
|
||||
cameraCurrentlyLocked = defaultCameraId;
|
||||
mPreview.setCamera(mCamera);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
// Because the Camera object is a shared resource, it's very
|
||||
// important to release it when the activity is paused.
|
||||
if (mCamera != null) {
|
||||
mPreview.setCamera(null);
|
||||
mCamera.release();
|
||||
mCamera = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
if (mNumberOfCameras > 1) {
|
||||
// Inflate our menu which can gather user input for switching camera
|
||||
inflater.inflate(R.menu.camera_menu, menu);
|
||||
} else {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle item selection
|
||||
switch (item.getItemId()) {
|
||||
case R.id.switch_cam:
|
||||
// Release this camera -> cameraCurrentlyLocked
|
||||
if (mCamera != null) {
|
||||
mCamera.stopPreview();
|
||||
mPreview.setCamera(null);
|
||||
mCamera.release();
|
||||
mCamera = null;
|
||||
}
|
||||
|
||||
// Acquire the next camera and request Preview to reconfigure
|
||||
// parameters.
|
||||
mCamera = Camera
|
||||
.open((cameraCurrentlyLocked + 1) % mNumberOfCameras);
|
||||
cameraCurrentlyLocked = (cameraCurrentlyLocked + 1)
|
||||
% mNumberOfCameras;
|
||||
mPreview.switchCamera(mCamera);
|
||||
|
||||
// Start the preview
|
||||
mCamera.startPreview();
|
||||
return true;
|
||||
case android.R.id.home:
|
||||
Intent intent = new Intent(this.getActivity(), MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
startActivity(intent);
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A simple wrapper around a Camera and a SurfaceView that renders a centered
|
||||
* preview of the Camera to the surface. We need to center the SurfaceView
|
||||
* because not all devices have cameras that support preview sizes at the same
|
||||
* aspect ratio as the device's display.
|
||||
*/
|
||||
class Preview extends ViewGroup implements SurfaceHolder.Callback {
|
||||
private final String TAG = "Preview";
|
||||
|
||||
SurfaceView mSurfaceView;
|
||||
SurfaceHolder mHolder;
|
||||
Size mPreviewSize;
|
||||
List<Size> mSupportedPreviewSizes;
|
||||
Camera mCamera;
|
||||
|
||||
Preview(Context context) {
|
||||
super(context);
|
||||
|
||||
mSurfaceView = new SurfaceView(context);
|
||||
addView(mSurfaceView);
|
||||
|
||||
// Install a SurfaceHolder.Callback so we get notified when the
|
||||
// underlying surface is created and destroyed.
|
||||
mHolder = mSurfaceView.getHolder();
|
||||
mHolder.addCallback(this);
|
||||
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||
}
|
||||
|
||||
public void setCamera(Camera camera) {
|
||||
mCamera = camera;
|
||||
if (mCamera != null) {
|
||||
mSupportedPreviewSizes = mCamera.getParameters()
|
||||
.getSupportedPreviewSizes();
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public void switchCamera(Camera camera) {
|
||||
setCamera(camera);
|
||||
try {
|
||||
camera.setPreviewDisplay(mHolder);
|
||||
} catch (IOException exception) {
|
||||
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
|
||||
}
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
|
||||
requestLayout();
|
||||
|
||||
camera.setParameters(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// We purposely disregard child measurements because act as a
|
||||
// wrapper to a SurfaceView that centers the camera preview instead
|
||||
// of stretching it.
|
||||
final int width = resolveSize(getSuggestedMinimumWidth(),
|
||||
widthMeasureSpec);
|
||||
final int height = resolveSize(getSuggestedMinimumHeight(),
|
||||
heightMeasureSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
|
||||
if (mSupportedPreviewSizes != null) {
|
||||
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width,
|
||||
height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
if (changed && getChildCount() > 0) {
|
||||
final View child = getChildAt(0);
|
||||
|
||||
final int width = r - l;
|
||||
final int height = b - t;
|
||||
|
||||
int previewWidth = width;
|
||||
int previewHeight = height;
|
||||
if (mPreviewSize != null) {
|
||||
previewWidth = mPreviewSize.width;
|
||||
previewHeight = mPreviewSize.height;
|
||||
}
|
||||
|
||||
// Center the child SurfaceView within the parent.
|
||||
if (width * previewHeight > height * previewWidth) {
|
||||
final int scaledChildWidth = previewWidth * height
|
||||
/ previewHeight;
|
||||
child.layout((width - scaledChildWidth) / 2, 0,
|
||||
(width + scaledChildWidth) / 2, height);
|
||||
} else {
|
||||
final int scaledChildHeight = previewHeight * width
|
||||
/ previewWidth;
|
||||
child.layout(0, (height - scaledChildHeight) / 2, width,
|
||||
(height + scaledChildHeight) / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
// The Surface has been created, acquire the camera and tell it where
|
||||
// to draw.
|
||||
try {
|
||||
if (mCamera != null) {
|
||||
mCamera.setPreviewDisplay(holder);
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
// Surface will be destroyed when we return, so stop the preview.
|
||||
if (mCamera != null) {
|
||||
mCamera.stopPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
|
||||
final double ASPECT_TOLERANCE = 0.1;
|
||||
double targetRatio = (double) w / h;
|
||||
if (sizes == null)
|
||||
return null;
|
||||
|
||||
Size optimalSize = null;
|
||||
double minDiff = Double.MAX_VALUE;
|
||||
|
||||
int targetHeight = h;
|
||||
|
||||
// Try to find an size match aspect ratio and size
|
||||
for (Size size : sizes) {
|
||||
double ratio = (double) size.width / size.height;
|
||||
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
|
||||
continue;
|
||||
if (Math.abs(size.height - targetHeight) < minDiff) {
|
||||
optimalSize = size;
|
||||
minDiff = Math.abs(size.height - targetHeight);
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot find the one match the aspect ratio, ignore the requirement
|
||||
if (optimalSize == null) {
|
||||
minDiff = Double.MAX_VALUE;
|
||||
for (Size size : sizes) {
|
||||
if (Math.abs(size.height - targetHeight) < minDiff) {
|
||||
optimalSize = size;
|
||||
minDiff = Math.abs(size.height - targetHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
return optimalSize;
|
||||
}
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
// Now that the size is known, set up the camera parameters and begin
|
||||
// the preview.
|
||||
Camera.Parameters parameters = mCamera.getParameters();
|
||||
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
|
||||
requestLayout();
|
||||
|
||||
mCamera.setParameters(parameters);
|
||||
mCamera.startPreview();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class CameraSample extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
int themeId = this.getIntent().getExtras().getInt("theme");
|
||||
this.setTheme(themeId);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.camera_sample);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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 java.util.StringTokenizer;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.Fragment;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipDescription;
|
||||
import android.content.ClipData.Item;
|
||||
import android.os.Bundle;
|
||||
import android.view.DragEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
|
||||
public class ContentFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
view.setOnDragListener(new View.OnDragListener() {
|
||||
public boolean onDrag(View v, DragEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case DragEvent.ACTION_DRAG_STARTED:
|
||||
return processDragStarted(event);
|
||||
case DragEvent.ACTION_DROP:
|
||||
return processDrop(event, imageView);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
view.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ActionBar bar = ContentFragment.this.getActivity()
|
||||
.getActionBar();
|
||||
if (bar != null) {
|
||||
if (bar.isShowing()) {
|
||||
bar.hide();
|
||||
} else {
|
||||
bar.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
|
||||
boolean processDragStarted(DragEvent event) {
|
||||
// Determine whether to continue processing drag and drop based on the
|
||||
// plain text mime type.
|
||||
ClipDescription clipDesc = event.getClipDescription();
|
||||
if (clipDesc != null) {
|
||||
return clipDesc.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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();
|
||||
if (data != null) {
|
||||
if (data.getItemCount() > 0) {
|
||||
Item item = data.getItemAt(0);
|
||||
String textData = (String) item.getText();
|
||||
if (textData != null) {
|
||||
StringTokenizer tokenizer = new StringTokenizer(textData, "||");
|
||||
if (tokenizer.countTokens() != 2) {
|
||||
return false;
|
||||
}
|
||||
int category = -1;
|
||||
int entryId = -1;
|
||||
try {
|
||||
category = Integer.parseInt(tokenizer.nextToken());
|
||||
entryId = Integer.parseInt(tokenizer.nextToken());
|
||||
} catch (NumberFormatException exception) {
|
||||
return false;
|
||||
}
|
||||
imageView.setImageBitmap(
|
||||
Directory.getCategory(category)
|
||||
.getEntry(entryId)
|
||||
.getBitmap(getResources()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public class Directory {
|
||||
private static DirectoryCategory[] categories;
|
||||
|
||||
public static void initializeDirectory() {
|
||||
categories = new DirectoryCategory[] {
|
||||
new DirectoryCategory("Balloons", new DirectoryEntry[] {
|
||||
new DirectoryEntry("Green Balloon", R.drawable.green_balloon),
|
||||
new DirectoryEntry("Red Balloon", R.drawable.red_balloon),
|
||||
new DirectoryEntry("Blue Balloon", R.drawable.blue_balloon)}),
|
||||
new DirectoryCategory("Bikes", new DirectoryEntry[] {
|
||||
new DirectoryEntry("Old school huffy", R.drawable.blue_bike),
|
||||
new DirectoryEntry("New Bikes", R.drawable.rainbow_bike),
|
||||
new DirectoryEntry("Chrome Fast", R.drawable.chrome_wheel)}),
|
||||
new DirectoryCategory("Androids", new DirectoryEntry[] {
|
||||
new DirectoryEntry("Steampunk Android", R.drawable.punk_droid),
|
||||
new DirectoryEntry("Stargazing Android", R.drawable.stargazer_droid),
|
||||
new DirectoryEntry("Big Android", R.drawable.big_droid) }),
|
||||
new DirectoryCategory("Pastries", new DirectoryEntry[] {
|
||||
new DirectoryEntry("Cupcake", R.drawable.cupcake),
|
||||
new DirectoryEntry("Donut", R.drawable.donut),
|
||||
new DirectoryEntry("Eclair", R.drawable.eclair),
|
||||
new DirectoryEntry("Froyo", R.drawable.froyo), }), };
|
||||
|
||||
}
|
||||
|
||||
public static int getCategoryCount() {
|
||||
return categories.length;
|
||||
}
|
||||
|
||||
public static DirectoryCategory getCategory(int i) {
|
||||
return categories[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
public class DirectoryCategory {
|
||||
private String name;
|
||||
private DirectoryEntry[] entries;
|
||||
|
||||
public DirectoryCategory(String name, DirectoryEntry[] entries) {
|
||||
this.name = name;
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getEntryCount() {
|
||||
return entries.length;
|
||||
}
|
||||
|
||||
public DirectoryEntry getEntry(int i) {
|
||||
return entries[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class DirectoryEntry {
|
||||
private String name;
|
||||
private int resID;
|
||||
|
||||
public DirectoryEntry(String name, int resID) {
|
||||
this.name = name;
|
||||
this.resID = resID;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Drawable getDrawable(Resources res) {
|
||||
return res.getDrawable(resID);
|
||||
}
|
||||
|
||||
public Bitmap getBitmap(Resources res) {
|
||||
return BitmapFactory.decodeResource(res, resID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
public class MainActivity extends Activity implements ActionBar.TabListener {
|
||||
|
||||
private View mActionBarView;
|
||||
private Animator mCurrentTitlesAnimator;
|
||||
private String[] mToggleLabels = {"Show Titles", "Hide Titles"};
|
||||
private int mLabelIndex = 1;
|
||||
private int mThemeId = -1;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if(savedInstanceState != null && savedInstanceState.getInt("theme", -1) != -1) {
|
||||
mThemeId = savedInstanceState.getInt("theme");
|
||||
this.setTheme(mThemeId);
|
||||
}
|
||||
setContentView(R.layout.main);
|
||||
|
||||
Directory.initializeDirectory();
|
||||
|
||||
ActionBar bar = getActionBar();
|
||||
|
||||
int i;
|
||||
for (i = 0; i < Directory.getCategoryCount(); i++)
|
||||
bar.addTab(bar.newTab().setText(Directory.getCategory(i).getName())
|
||||
.setTabListener(this));
|
||||
|
||||
mActionBarView = getLayoutInflater().inflate(
|
||||
R.layout.action_bar_custom, null);
|
||||
|
||||
bar.setCustomView(mActionBarView);
|
||||
bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_USE_LOGO);
|
||||
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||
bar.setDisplayShowHomeEnabled(true);
|
||||
|
||||
// If category is not saved to the savedInstanceState,
|
||||
// 0 is returned by default.
|
||||
if(savedInstanceState != null) {
|
||||
int category = savedInstanceState.getInt("category");
|
||||
bar.selectTab(bar.getTabAt(category));
|
||||
}
|
||||
}
|
||||
|
||||
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
TitlesFragment titleFrag = (TitlesFragment) getFragmentManager()
|
||||
.findFragmentById(R.id.frag_title);
|
||||
titleFrag.populateTitles(tab.getPosition());
|
||||
|
||||
titleFrag.selectPosition(0);
|
||||
}
|
||||
|
||||
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
}
|
||||
|
||||
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.main_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.camera:
|
||||
Intent intent = new Intent(this, CameraSample.class);
|
||||
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;
|
||||
} else {
|
||||
mThemeId = android.R.style.Theme_Holo;
|
||||
}
|
||||
this.recreate();
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleVisibleTitles() {
|
||||
// Use these for custom animations.
|
||||
final FragmentManager fm = getFragmentManager();
|
||||
final TitlesFragment f = (TitlesFragment) fm
|
||||
.findFragmentById(R.id.frag_title);
|
||||
final View titlesView = f.getView();
|
||||
mLabelIndex = 1 - mLabelIndex;
|
||||
|
||||
// Determine if we're in portrait, and whether we're showing or hiding the titles
|
||||
// with this toggle.
|
||||
final boolean isPortrait = getResources().getConfiguration().orientation ==
|
||||
Configuration.ORIENTATION_PORTRAIT;
|
||||
|
||||
final boolean shouldShow = f.isHidden() || mCurrentTitlesAnimator != null;
|
||||
|
||||
// Cancel the current titles animation if there is one.
|
||||
if (mCurrentTitlesAnimator != null)
|
||||
mCurrentTitlesAnimator.cancel();
|
||||
|
||||
// Begin setting up the object animator. We'll animate the bottom or right edge of the
|
||||
// titles view, as well as its alpha for a fade effect.
|
||||
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(
|
||||
titlesView,
|
||||
PropertyValuesHolder.ofInt(
|
||||
isPortrait ? "bottom" : "right",
|
||||
shouldShow ? getResources().getDimensionPixelSize(R.dimen.titles_size)
|
||||
: 0),
|
||||
PropertyValuesHolder.ofFloat("alpha", shouldShow ? 1 : 0)
|
||||
);
|
||||
|
||||
// At each step of the animation, we'll perform layout by calling setLayoutParams.
|
||||
final ViewGroup.LayoutParams lp = titlesView.getLayoutParams();
|
||||
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(ValueAnimator valueAnimator) {
|
||||
// *** WARNING ***: triggering layout at each animation frame highly impacts
|
||||
// performance so you should only do this for simple layouts. More complicated
|
||||
// layouts can be better served with individual animations on child views to
|
||||
// avoid the performance penalty of layout.
|
||||
if (isPortrait) {
|
||||
lp.height = (Integer) valueAnimator.getAnimatedValue();
|
||||
} else {
|
||||
lp.width = (Integer) valueAnimator.getAnimatedValue();
|
||||
}
|
||||
titlesView.setLayoutParams(lp);
|
||||
}
|
||||
});
|
||||
|
||||
if (shouldShow) {
|
||||
fm.beginTransaction().show(f).commit();
|
||||
objectAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
mCurrentTitlesAnimator = null;
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
objectAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
boolean canceled;
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
canceled = true;
|
||||
super.onAnimationCancel(animation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
if (canceled)
|
||||
return;
|
||||
mCurrentTitlesAnimator = null;
|
||||
fm.beginTransaction().hide(f).commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Start the animation.
|
||||
objectAnimator.start();
|
||||
mCurrentTitlesAnimator = objectAnimator;
|
||||
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
menu.getItem(1).setTitle(mToggleLabels[mLabelIndex]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState (Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
ActionBar bar = getActionBar();
|
||||
int category = bar.getSelectedTab().getPosition();
|
||||
outState.putInt("category", category);
|
||||
outState.putInt("theme", mThemeId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.app.ListFragment;
|
||||
import android.content.ClipData;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
|
||||
public class TitlesFragment extends ListFragment {
|
||||
private int mCategory = 0;
|
||||
private int mCurPosition = 0;
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
//Current position should survive screen rotations.
|
||||
if (savedInstanceState != null) {
|
||||
mCategory = savedInstanceState.getInt("category");
|
||||
mCurPosition = savedInstanceState.getInt("listPosition");
|
||||
}
|
||||
|
||||
populateTitles(mCategory);
|
||||
ListView lv = getListView();
|
||||
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
|
||||
selectPosition(mCurPosition);
|
||||
lv.setCacheColorHint(Color.WHITE);
|
||||
|
||||
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
|
||||
|
||||
@Override
|
||||
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), null, 0);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class MyDragShadowBuilder extends View.DragShadowBuilder {
|
||||
private static Drawable shadow;
|
||||
|
||||
public MyDragShadowBuilder(View v) {
|
||||
super(v);
|
||||
shadow = new ColorDrawable(Color.BLUE);
|
||||
shadow.setBounds(0, 0, v.getWidth(), v.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawShadow(Canvas canvas) {
|
||||
shadow.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
public void populateTitles(int category) {
|
||||
DirectoryCategory cat = Directory.getCategory(category);
|
||||
String[] items = new String[cat.getEntryCount()];
|
||||
for (int i = 0; i < cat.getEntryCount(); i++)
|
||||
items[i] = cat.getEntry(i).getName();
|
||||
setListAdapter(new ArrayAdapter<String>(getActivity(),
|
||||
R.layout.title_list_item, items));
|
||||
mCategory = category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onListItemClick(ListView l, View v, int position, long id) {
|
||||
updateImage(position);
|
||||
}
|
||||
|
||||
private void updateImage(int position) {
|
||||
ImageView iv = (ImageView) getFragmentManager().findFragmentById(
|
||||
R.id.frag_content).getView().findViewById(R.id.image);
|
||||
iv.setImageDrawable(Directory.getCategory(mCategory).getEntry(position)
|
||||
.getDrawable(getResources()));
|
||||
mCurPosition = position;
|
||||
}
|
||||
|
||||
public void selectPosition(int position) {
|
||||
ListView lv = getListView();
|
||||
lv.setItemChecked(position, true);
|
||||
updateImage(position);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState (Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt("listPosition", mCurPosition);
|
||||
outState.putInt("category", mCategory);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.widget;
|
||||
|
||||
public class WidgetItem {
|
||||
public String text;
|
||||
|
||||
public WidgetItem(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2007 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.widget;
|
||||
|
||||
import com.example.android.hcgallery.R;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class WidgetProvider extends AppWidgetProvider {
|
||||
public static String TOAST_ACTION = "com.example.android.widget.action.TOAST";
|
||||
|
||||
@Override
|
||||
public void onDeleted(Context context, int[] appWidgetIds) {
|
||||
super.onDeleted(context, appWidgetIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisabled(Context context) {
|
||||
super.onDisabled(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnabled(Context context) {
|
||||
super.onEnabled(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
AppWidgetManager mgr = AppWidgetManager.getInstance(context);
|
||||
if (intent.getAction().equals(TOAST_ACTION)) {
|
||||
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||
int viewIndex = intent.getIntExtra("numberToToast", 0);
|
||||
Toast.makeText(context, "Touched view " + viewIndex, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
super.onReceive(context, intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||
// update each of the widgets with the remote adapter
|
||||
for (int i = 0; i < appWidgetIds.length; ++i) {
|
||||
|
||||
// Here we setup the intent which points to the StackViewService which will
|
||||
// provide the views for this collection.
|
||||
Intent intent = new Intent(context, WidgetService.class);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
|
||||
// When intents are compared, the extras are ignored, so we need to embed the extras
|
||||
// into the data so that the extras will not be ignored.
|
||||
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
|
||||
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
|
||||
rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent);
|
||||
|
||||
// The empty view is displayed when the collection has no items. It should be a sibling
|
||||
// of the collection view.
|
||||
rv.setEmptyView(R.id.stack_view, R.id.empty_view);
|
||||
|
||||
// Here we setup the a pending intent template. Individuals items of a collection
|
||||
// cannot setup their own pending intents, instead, the collection as a whole can
|
||||
// setup a pending intent template, and the individual items can set a fillInIntent
|
||||
// to create unique before on an item to item basis.
|
||||
Intent toastIntent = new Intent(context, WidgetProvider.class);
|
||||
toastIntent.setAction(WidgetProvider.TOAST_ACTION);
|
||||
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
|
||||
toastIntent.setData(Uri.parse("widgetid" + appWidgetIds[i]));
|
||||
PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent);
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
|
||||
}
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2007 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.widget;
|
||||
|
||||
import com.example.android.hcgallery.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.RemoteViewsService;
|
||||
|
||||
public class WidgetService extends RemoteViewsService {
|
||||
|
||||
private class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
|
||||
private static final int mCount = 10;
|
||||
private List<WidgetItem> mWidgetItems = new ArrayList<WidgetItem>();
|
||||
private Context mContext;
|
||||
private int mAppWidgetId;
|
||||
|
||||
public StackRemoteViewsFactory(Context context, Intent intent) {
|
||||
mContext = context;
|
||||
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||
}
|
||||
|
||||
public void onCreate() {
|
||||
// In onCreate() you setup any connections / cursors to your data source. Heavy lifting,
|
||||
// for example downloading or creating content etc, should be deferred to getViewAt() or
|
||||
// onDataSetChanged(). Taking more than 20 seconds in this call will result in an ANR.
|
||||
for (int i = 0; i < mCount; i++) {
|
||||
mWidgetItems.add(new WidgetItem(i + "!"));
|
||||
}
|
||||
|
||||
// We sleep for 3 seconds here to show how the empty view appears in the interim.
|
||||
// The empty view is set in the WidgetProvider and should be a sibling of the
|
||||
// collection view.
|
||||
try {
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
// In onDestroy() you should tear down anything that was setup for your data source,
|
||||
// eg. cursors, connections, etc.
|
||||
mWidgetItems.clear();
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mCount;
|
||||
}
|
||||
|
||||
public RemoteViews getViewAt(int position) {
|
||||
// position will always range from 0 to getCount() - 1.
|
||||
|
||||
// We construct a remote views item based on our widget item xml file, and set the
|
||||
// text based on the position.
|
||||
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
|
||||
rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text);
|
||||
|
||||
// Next, we set an intent so that clicking on this view will result in a toast message
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
|
||||
extras.putInt("numberToToast", position);
|
||||
Intent fillInIntent = new Intent();
|
||||
fillInIntent.putExtras(extras);
|
||||
rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
|
||||
|
||||
// You can do heaving lifting in here, synchronously. For example, if you need to
|
||||
// process an image, fetch something from the network, etc., it is ok to do it here,
|
||||
// synchronously. A loading view will show up in lieu of the actual contents in the
|
||||
// interim.
|
||||
try {
|
||||
Log.d("WidgetService/getViewAt", "Loading view " + position);
|
||||
// Simulating a time-consuming operation. NO NEED to include this call in your app!
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Return our remote views object.
|
||||
return rv;
|
||||
}
|
||||
|
||||
public RemoteViews getLoadingView() {
|
||||
// You can create a custom loading view (for instance when getViewAt() is slow. If you
|
||||
// return null here, you will get the default loading view.
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getViewTypeCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onDataSetChanged() {
|
||||
// This is triggered when you call AppWidgetManager notifyAppWidgetViewDataChanged
|
||||
// on the collection view corresponding to this factory. You can do heaving lifting in
|
||||
// here, synchronously. For example, if you need to process an image, fetch something
|
||||
// from the network, etc., it is ok to do it here, synchronously. The widget will remain
|
||||
// in its current state while work is being done here, so you don't need to worry about
|
||||
// locking up the widget.
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteViewsFactory onGetViewFactory(Intent intent) {
|
||||
return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
|
||||
}
|
||||
}
|
||||