am 11b83fd9: Merge "Added Honeycomb Gallery sample application." into honeycomb
* commit '11b83fd9f791496410a28f3db95bb27c0873c6fd': Added Honeycomb Gallery sample application.
@@ -160,6 +160,7 @@ development/samples/ContactManager samples/${PLATFORM_NAME}/ContactMan
|
|||||||
development/samples/CrossCompatibility samples/${PLATFORM_NAME}/CrossCompatibility
|
development/samples/CrossCompatibility samples/${PLATFORM_NAME}/CrossCompatibility
|
||||||
development/samples/CubeLiveWallpaper samples/${PLATFORM_NAME}/CubeLiveWallpaper
|
development/samples/CubeLiveWallpaper samples/${PLATFORM_NAME}/CubeLiveWallpaper
|
||||||
development/samples/Home samples/${PLATFORM_NAME}/Home
|
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/JetBoy samples/${PLATFORM_NAME}/JetBoy
|
||||||
development/samples/LunarLander samples/${PLATFORM_NAME}/LunarLander
|
development/samples/LunarLander samples/${PLATFORM_NAME}/LunarLander
|
||||||
development/samples/MultiResolution samples/${PLATFORM_NAME}/MultiResolution
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||