cherrypick from master cl Change-Id: I45f91fd9cfe0cb89789017deec63565e4757063e
Adding the NewsReader sample.

This sample demonstrates how to design a UI for multiple screens and
is part of the "Designing for Multiple Screens" AndroidU lesson.

Change-Id: I462261933c68b3a40f9611fcf7153c25abdfcd5d
diff --git a/samples/training/multiscreen/newsreader/AndroidManifest.xml b/samples/training/multiscreen/newsreader/AndroidManifest.xml
new file mode 100644
index 0000000..04ddf29
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?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.newsreader"
+      android:versionCode="1"
+      android:versionName="1.0">
+    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14" />
+
+    <application android:icon="@drawable/icon" android:label="@string/app_name"
+                 android:logo="@drawable/logo" android:theme="@style/NewsReaderStyle">
+        <activity android:name=".NewsReaderActivity" android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".ArticleActivity"
+                  android:theme="@style/NewsReaderStyle_NoActionBar" />
+    </application>
+    <supports-screens
+        android:smallScreens="true"
+        android:normalScreens="true"
+        android:largeScreens="true"
+        android:xlargeScreens="true"
+    />
+</manifest>
diff --git a/samples/training/multiscreen/newsreader/proguard.cfg b/samples/training/multiscreen/newsreader/proguard.cfg
new file mode 100644
index 0000000..b1cdf17
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+    native <methods>;
+}
+
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+    public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+   public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+  public static final android.os.Parcelable$Creator *;
+}
diff --git a/samples/training/multiscreen/newsreader/project.properties b/samples/training/multiscreen/newsreader/project.properties
new file mode 100644
index 0000000..730e911
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/project.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-14
diff --git a/samples/training/multiscreen/newsreader/res/drawable-hdpi/button_normal.9.png b/samples/training/multiscreen/newsreader/res/drawable-hdpi/button_normal.9.png
new file mode 100644
index 0000000..1f53bc9
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-hdpi/button_normal.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-hdpi/button_pressed.9.png b/samples/training/multiscreen/newsreader/res/drawable-hdpi/button_pressed.9.png
new file mode 100644
index 0000000..71d157e
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-hdpi/button_pressed.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-hdpi/icon.png b/samples/training/multiscreen/newsreader/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..a40bd0e
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-hdpi/logo.png b/samples/training/multiscreen/newsreader/res/drawable-hdpi/logo.png
new file mode 100644
index 0000000..858562a
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-hdpi/logo.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-hdpi/tab_bg_normal.9.png b/samples/training/multiscreen/newsreader/res/drawable-hdpi/tab_bg_normal.9.png
new file mode 100644
index 0000000..51799f8
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-hdpi/tab_bg_normal.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-hdpi/tab_bg_selected.9.png b/samples/training/multiscreen/newsreader/res/drawable-hdpi/tab_bg_selected.9.png
new file mode 100644
index 0000000..f6873f3
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-hdpi/tab_bg_selected.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-ldpi/button_pressed.9.png b/samples/training/multiscreen/newsreader/res/drawable-ldpi/button_pressed.9.png
new file mode 100644
index 0000000..be34147
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-ldpi/button_pressed.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-ldpi/icon.png b/samples/training/multiscreen/newsreader/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..4a733c5
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-ldpi/logo.png b/samples/training/multiscreen/newsreader/res/drawable-ldpi/logo.png
new file mode 100644
index 0000000..58cc2b7
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-ldpi/logo.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-ldpi/tab_bg_normal.9.png b/samples/training/multiscreen/newsreader/res/drawable-ldpi/tab_bg_normal.9.png
new file mode 100644
index 0000000..64eefea
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-ldpi/tab_bg_normal.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-ldpi/tab_bg_selected.9.png b/samples/training/multiscreen/newsreader/res/drawable-ldpi/tab_bg_selected.9.png
new file mode 100644
index 0000000..23cbccc
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-ldpi/tab_bg_selected.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-mdpi/button_normal.9.png b/samples/training/multiscreen/newsreader/res/drawable-mdpi/button_normal.9.png
new file mode 100644
index 0000000..23733d7
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-mdpi/button_normal.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-mdpi/button_pressed.9.png b/samples/training/multiscreen/newsreader/res/drawable-mdpi/button_pressed.9.png
new file mode 100644
index 0000000..d228e60
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-mdpi/button_pressed.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-mdpi/icon.png b/samples/training/multiscreen/newsreader/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..6b42690
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-mdpi/logo.png b/samples/training/multiscreen/newsreader/res/drawable-mdpi/logo.png
new file mode 100644
index 0000000..397f96a
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-mdpi/logo.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-mdpi/tab_bg_normal.9.png b/samples/training/multiscreen/newsreader/res/drawable-mdpi/tab_bg_normal.9.png
new file mode 100644
index 0000000..5406bb3
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-mdpi/tab_bg_normal.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-mdpi/tab_bg_selected.9.png b/samples/training/multiscreen/newsreader/res/drawable-mdpi/tab_bg_selected.9.png
new file mode 100644
index 0000000..c6d3a7c
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-mdpi/tab_bg_selected.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-xhdpi/button_normal.9.png b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/button_normal.9.png
new file mode 100644
index 0000000..2bd3843
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/button_normal.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-xhdpi/button_pressed.9.png b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/button_pressed.9.png
new file mode 100644
index 0000000..50921cb
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/button_pressed.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-xhdpi/icon.png b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/icon.png
new file mode 100644
index 0000000..76a8868
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/icon.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-xhdpi/logo.png b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/logo.png
new file mode 100644
index 0000000..3400164
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/logo.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-xhdpi/tab_bg_normal.9.png b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/tab_bg_normal.9.png
new file mode 100644
index 0000000..028afde
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/tab_bg_normal.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable-xhdpi/tab_bg_selected.9.png b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/tab_bg_selected.9.png
new file mode 100644
index 0000000..5de99e9
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable-xhdpi/tab_bg_selected.9.png
Binary files differ
diff --git a/samples/training/multiscreen/newsreader/res/drawable/button_bg.xml b/samples/training/multiscreen/newsreader/res/drawable/button_bg.xml
new file mode 100644
index 0000000..cf7b9d5
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable/button_bg.xml
@@ -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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+          android:drawable="@drawable/button_pressed" />
+    <item android:state_focused="true"
+          android:drawable="@drawable/button_pressed" />
+    <item android:state_selected="true"
+          android:drawable="@drawable/button_pressed" />
+    <item android:drawable="@drawable/button_normal" />
+</selector>
\ No newline at end of file
diff --git a/samples/training/multiscreen/newsreader/res/drawable/tab_bg.xml b/samples/training/multiscreen/newsreader/res/drawable/tab_bg.xml
new file mode 100644
index 0000000..39a8119
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/drawable/tab_bg.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<selector
+  xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true"
+          android:drawable="@drawable/tab_bg_selected" />
+    <item android:drawable="@drawable/tab_bg_normal" />
+</selector>
diff --git a/samples/training/multiscreen/newsreader/res/layout/actionbar_list_item.xml b/samples/training/multiscreen/newsreader/res/layout/actionbar_list_item.xml
new file mode 100644
index 0000000..452d16b
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/layout/actionbar_list_item.xml
@@ -0,0 +1,24 @@
+<?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="wrap_content"
+  android:textSize="14sp"
+  android:textColor="#01511a"
+  android:padding="5dp">
+</TextView>
diff --git a/samples/training/multiscreen/newsreader/res/layout/headline_item.xml b/samples/training/multiscreen/newsreader/res/layout/headline_item.xml
new file mode 100644
index 0000000..980e43c
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/layout/headline_item.xml
@@ -0,0 +1,24 @@
+<?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="wrap_content"
+  android:textSize="16sp"
+  android:textColor="#01511a"
+  android:padding="10dp">
+</TextView>
diff --git a/samples/training/multiscreen/newsreader/res/layout/onepane.xml b/samples/training/multiscreen/newsreader/res/layout/onepane.xml
new file mode 100644
index 0000000..83eeb86
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/layout/onepane.xml
@@ -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.
+-->
+
+<LinearLayout
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:orientation="vertical"
+  android:layout_width="match_parent"
+  android:layout_height="match_parent">
+
+  <fragment android:id="@+id/headlines" android:layout_height="fill_parent"
+    android:name="com.example.android.newsreader.HeadlinesFragment"
+    android:layout_width="match_parent" />
+
+</LinearLayout>
diff --git a/samples/training/multiscreen/newsreader/res/layout/onepane_with_bar.xml b/samples/training/multiscreen/newsreader/res/layout/onepane_with_bar.xml
new file mode 100644
index 0000000..0ff3a24
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/layout/onepane_with_bar.xml
@@ -0,0 +1,32 @@
+<?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">
+    <LinearLayout android:layout_width="match_parent" android:id="@+id/linearLayout1"  android:gravity="center" android:layout_height="50dp">
+        <ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/logo" android:paddingRight="30dp" android:layout_gravity="left" android:layout_weight="0"></ImageView>
+        <View android:layout_height="wrap_content" android:id="@+id/view1" android:layout_width="wrap_content" android:layout_weight="1"></View>
+        <Button android:id="@+id/categorybutton" android:text="one" android:background="@drawable/button_bg" android:layout_height="match_parent" android:layout_weight="0" android:layout_width="120dp" style="@style/CategoryButtonStyle"/>
+    </LinearLayout>
+
+    <fragment android:id="@+id/headlines" android:layout_height="fill_parent"
+              android:name="com.example.android.newsreader.HeadlinesFragment"
+              android:layout_width="match_parent" />
+
+</LinearLayout>
diff --git a/samples/training/multiscreen/newsreader/res/layout/twopanes.xml b/samples/training/multiscreen/newsreader/res/layout/twopanes.xml
new file mode 100644
index 0000000..96c958a
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/layout/twopanes.xml
@@ -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.
+-->
+
+<LinearLayout
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:layout_width="fill_parent"
+  android:layout_height="fill_parent" android:orientation="horizontal">
+    <fragment android:id="@+id/headlines" android:layout_height="fill_parent"
+              android:name="com.example.android.newsreader.HeadlinesFragment"
+              android:layout_width="400dp" android:layout_marginRight="10dp"/>
+    <fragment android:id="@+id/article" android:layout_height="fill_parent"
+              android:name="com.example.android.newsreader.ArticleFragment"
+              android:layout_width="fill_parent" />
+</LinearLayout>
diff --git a/samples/training/multiscreen/newsreader/res/layout/twopanes_narrow.xml b/samples/training/multiscreen/newsreader/res/layout/twopanes_narrow.xml
new file mode 100644
index 0000000..98d9516
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/layout/twopanes_narrow.xml
@@ -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.
+-->
+
+<LinearLayout
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:layout_width="fill_parent"
+  android:layout_height="fill_parent" android:orientation="horizontal">
+    <fragment android:id="@+id/headlines" android:layout_height="fill_parent"
+              android:name="com.example.android.newsreader.HeadlinesFragment"
+              android:layout_width="200dp" android:layout_marginRight="10dp"/>
+    <fragment android:id="@+id/article" android:layout_height="fill_parent"
+              android:name="com.example.android.newsreader.ArticleFragment"
+              android:layout_width="fill_parent" />
+</LinearLayout>
diff --git a/samples/training/multiscreen/newsreader/res/values-sw600dp-land/main.xml b/samples/training/multiscreen/newsreader/res/values-sw600dp-land/main.xml
new file mode 100644
index 0000000..85e5966
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values-sw600dp-land/main.xml
@@ -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.
+-->
+
+<resources>
+    <item name="main_layout" type="layout">@layout/twopanes</item>
+    <string name="has_two_panes">true</string>
+</resources>
diff --git a/samples/training/multiscreen/newsreader/res/values-sw600dp-port/main.xml b/samples/training/multiscreen/newsreader/res/values-sw600dp-port/main.xml
new file mode 100644
index 0000000..4d032dd
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values-sw600dp-port/main.xml
@@ -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.
+-->
+
+<resources>
+    <item name="main_layout" type="layout">@layout/onepane</item>
+    <string name="has_two_panes">false</string>
+</resources>
diff --git a/samples/training/multiscreen/newsreader/res/values-v11/main.xml b/samples/training/multiscreen/newsreader/res/values-v11/main.xml
new file mode 100644
index 0000000..cb82bb8
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values-v11/main.xml
@@ -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>
+    <item name="main_layout" type="layout">@layout/onepane</item>
+</resources>
diff --git a/samples/training/multiscreen/newsreader/res/values-v11/style.xml b/samples/training/multiscreen/newsreader/res/values-v11/style.xml
new file mode 100644
index 0000000..566a689
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values-v11/style.xml
@@ -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.
+-->
+
+<resources>
+<style name="CustomActionBarTabTextStyle">
+    <item name="android:textColor">#017729</item>
+    <item name="android:textSize">20sp</item>
+    <item name="android:typeface">sans</item>
+</style>
+<style name="CustomActionBarTabStyle" parent="android:style/Widget.Holo.Light.ActionBar.TabView">
+    <item name="android:background">@drawable/tab_bg</item>
+    <item name="android:paddingLeft">20dp</item>
+    <item name="android:paddingRight">20dp</item>
+</style>
+<style name="NewsReaderStyle" parent="android:Theme.Holo.Light">
+    <item name="android:actionBarTabTextStyle">@style/CustomActionBarTabTextStyle</item>
+    <item name="android:actionBarTabStyle">@style/CustomActionBarTabStyle</item>
+</style>
+
+<style name="NewsReaderStyle_NoActionBar" parent="android:Theme.Holo.Light.NoActionBar">
+</style>
+
+</resources>
diff --git a/samples/training/multiscreen/newsreader/res/values-xlarge-land/main.xml b/samples/training/multiscreen/newsreader/res/values-xlarge-land/main.xml
new file mode 100644
index 0000000..85e5966
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values-xlarge-land/main.xml
@@ -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.
+-->
+
+<resources>
+    <item name="main_layout" type="layout">@layout/twopanes</item>
+    <string name="has_two_panes">true</string>
+</resources>
diff --git a/samples/training/multiscreen/newsreader/res/values-xlarge-port/main.xml b/samples/training/multiscreen/newsreader/res/values-xlarge-port/main.xml
new file mode 100644
index 0000000..90e6a4a
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values-xlarge-port/main.xml
@@ -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.
+-->
+
+<resources>
+    <item name="main_layout" type="layout">@layout/twopanes_narrow</item>
+    <string name="has_two_panes">true</string>
+</resources>
diff --git a/samples/training/multiscreen/newsreader/res/values/main.xml b/samples/training/multiscreen/newsreader/res/values/main.xml
new file mode 100644
index 0000000..c598762
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values/main.xml
@@ -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.
+-->
+
+<resources>
+    <item name="main_layout" type="layout">@layout/onepane_with_bar</item>
+    <string name="has_two_panes">false</string>
+</resources>
diff --git a/samples/training/multiscreen/newsreader/res/values/strings.xml b/samples/training/multiscreen/newsreader/res/values/strings.xml
new file mode 100644
index 0000000..e4c4fe2
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values/strings.xml
@@ -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.
+-->
+
+<resources>
+    <string name="hello">Hello World, NewsReaderActivity!</string>
+    <string name="app_name">NewsReader</string>
+</resources>
diff --git a/samples/training/multiscreen/newsreader/res/values/style.xml b/samples/training/multiscreen/newsreader/res/values/style.xml
new file mode 100644
index 0000000..ddbd1c0
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/res/values/style.xml
@@ -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.
+-->
+
+<resources>
+<style name="NewsReaderStyle" parent="android:Theme.Light.NoTitleBar">
+</style>
+
+<style name="NewsReaderStyle_NoActionBar" parent="android:Theme.Light.NoTitleBar">
+</style>
+
+<style name="CategoryButtonStyle" parent="@android:style/Widget.Button">
+    <item name="android:textColor">#ffffff</item>
+</style>
+
+</resources>
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/ArticleActivity.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/ArticleActivity.java
new file mode 100644
index 0000000..2aff792
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/ArticleActivity.java
@@ -0,0 +1,67 @@
+/*
+ * 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.newsreader;
+
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+/**
+ * Activity that displays a particular news article onscreen.
+ *
+ * This activity is started only when the screen is not large enough for a two-pane layout, in
+ * which case this separate activity is shown in order to display the news article. This activity
+ * kills itself if the display is reconfigured into a shape that allows a two-pane layout, since
+ * in that case the news article will be displayed by the {@link NewsReaderActivity} and this
+ * Activity therefore becomes unnecessary.
+ */
+public class ArticleActivity extends FragmentActivity {
+    // The news category index and the article index for the article we are to display
+    int mCatIndex, mArtIndex;
+
+    /**
+     * Sets up the activity.
+     *
+     * Setting up the activity means reading the category/article index from the Intent that
+     * fired this Activity and loading it onto the UI. We also detect if there has been a
+     * screen configuration change (in particular, a rotation) that makes this activity
+     * unnecessary, in which case we do the honorable thing and get out of the way.
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mCatIndex = getIntent().getExtras().getInt("catIndex", 0);
+        mArtIndex = getIntent().getExtras().getInt("artIndex", 0);
+
+        // If we are in two-pane layout mode and the device is in landscape orientation, we are
+        // no longer necessary
+        if (getResources().getString(R.string.has_two_panes).equals("true") &&
+                    getResources().getConfiguration().orientation ==
+                    Configuration.ORIENTATION_LANDSCAPE) {
+            finish();
+            return;
+        }
+
+        // Place an ArticleFragment as our content pane
+        ArticleFragment f = new ArticleFragment();
+        getSupportFragmentManager().beginTransaction().add(android.R.id.content, f).commit();
+
+        // Display the correct news article on the fragment
+        NewsArticle article = NewsSource.getInstance().getCategory(mCatIndex).getArticle(mArtIndex);
+        f.displayArticle(article);
+    }
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/ArticleFragment.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/ArticleFragment.java
new file mode 100644
index 0000000..075e54f
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/ArticleFragment.java
@@ -0,0 +1,73 @@
+/*
+ * 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.newsreader;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebView;
+
+/**
+ * Fragment that displays a news article.
+ */
+public class ArticleFragment extends Fragment {
+    // The webview where we display the article (our only view)
+    WebView mWebView;
+
+    // The article we are to display
+    NewsArticle mNewsArticle = null;
+
+    // Parameterless constructor is needed by framework
+    public ArticleFragment() {
+        super();
+    }
+
+    /**
+     * Sets up the UI. It consists if a single WebView.
+     */
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        mWebView = new WebView(getActivity());
+        loadWebView();
+        return mWebView;
+    }
+
+    /**
+     * Displays a particular article.
+     *
+     * @param article the article to display
+     */
+    public void displayArticle(NewsArticle article) {
+        mNewsArticle = article;
+        loadWebView();
+    }
+
+    /**
+     * Loads article data into the webview.
+     *
+     * This method is called internally to update the webview's contents to the appropriate
+     * article's text.
+     */
+    void loadWebView() {
+        if (mWebView != null) {
+            mWebView.loadData(mNewsArticle == null ? "" : mNewsArticle.getBody(), "text/html",
+                        "utf-8");
+        }
+    }
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/CompatActionBarNavHandler.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/CompatActionBarNavHandler.java
new file mode 100644
index 0000000..e9bad7e
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/CompatActionBarNavHandler.java
@@ -0,0 +1,88 @@
+/*
+ * 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.newsreader;
+
+import android.app.ActionBar.OnNavigationListener;
+import android.app.ActionBar.Tab;
+import android.app.ActionBar.TabListener;
+import android.app.FragmentTransaction;
+
+/**
+ * Adapter for action bar navigation events.
+ *
+ * This class implements an adapter that facilitates handling of action bar navigation events.
+ * An instance of this class must be installed as a TabListener or OnNavigationListener on an
+ * Action Bar, and it will relay the navigation events to a configured listener
+ * (a {@link CompatActionBarNavListener}).
+ *
+ * This class should only be instanced and used on Android platforms that support the Action Bar,
+ * that is, SDK level 11 and above.
+ */
+public class CompatActionBarNavHandler implements TabListener, OnNavigationListener {
+    // The listener that we notify of navigation events
+    CompatActionBarNavListener mNavListener;
+
+    /**
+     * Constructs an instance with the given listener.
+     *
+     * @param listener the listener to notify when a navigation event occurs.
+     */
+    public CompatActionBarNavHandler(CompatActionBarNavListener listener) {
+        mNavListener = listener;
+    }
+
+    /**
+     * Called by framework when a tab is selected.
+     *
+     * This will cause a navigation event to be delivered to the configured listener.
+     */
+    @Override
+    public void onTabSelected(Tab tab, FragmentTransaction ft) {
+        // TODO Auto-generated method stub
+        mNavListener.onCategorySelected(tab.getPosition());
+    }
+
+    /**
+     * Called by framework when a item on the navigation menu is selected.
+     *
+     * This will cause a navigation event to be delivered to the configured listener.
+     */
+    @Override
+    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
+        mNavListener.onCategorySelected(itemPosition);
+        return true;
+    }
+
+
+    /**
+     * Called by framework when a tab is re-selected. That is, it was already selected and is
+     * tapped on again. This is not used in our app.
+     */
+    @Override
+    public void onTabReselected(Tab tab, FragmentTransaction ft) {
+        // we don't care
+    }
+
+    /**
+     * Called by framework when a tab is unselected. Not used in our app.
+     */
+    @Override
+    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
+        // we don't care
+    }
+
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/CompatActionBarNavListener.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/CompatActionBarNavListener.java
new file mode 100644
index 0000000..9a3f933
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/CompatActionBarNavListener.java
@@ -0,0 +1,30 @@
+/*
+ * 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.newsreader;
+
+/**
+ * A listener that listens to navigation events.
+ *
+ * Represents a listener for navigation events delivered by {@link CompatActionBarNavHandler}.
+ */
+public interface CompatActionBarNavListener {
+    /**
+     * Signals that the given news category was selected.
+     * @param catIndex the selected category's index.
+     */
+    public void onCategorySelected(int catIndex);
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/HeadlinesFragment.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/HeadlinesFragment.java
new file mode 100644
index 0000000..99d02fa
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/HeadlinesFragment.java
@@ -0,0 +1,125 @@
+/*
+ * 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.newsreader;
+
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Fragment that displays the news headlines for a particular news category.
+ *
+ * This Fragment displays a list with the news headlines for a particular news category.
+ * When an item is selected, it notifies the configured listener that a headlines was selected.
+ */
+public class HeadlinesFragment extends ListFragment implements OnItemClickListener {
+    // The list of headlines that we are displaying
+    List<String> mHeadlinesList = new ArrayList<String>();
+
+    // The list adapter for the list we are displaying
+    ArrayAdapter<String> mListAdapter;
+
+    // The listener we are to notify when a headline is selected
+    OnHeadlineSelectedListener mHeadlineSelectedListener = null;
+
+    /**
+     * Represents a listener that will be notified of headline selections.
+     */
+    public interface OnHeadlineSelectedListener {
+        /**
+         * Called when a given headline is selected.
+         * @param index the index of the selected headline.
+         */
+        public void onHeadlineSelected(int index);
+    }
+
+    /**
+     * Default constructor required by framework.
+     */
+    public HeadlinesFragment() {
+        super();
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        setListAdapter(mListAdapter);
+        getListView().setOnItemClickListener(this);
+        loadCategory(0);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mListAdapter = new ArrayAdapter<String>(getActivity(), R.layout.headline_item,
+                mHeadlinesList);
+    }
+
+    /**
+     * Sets the listener that should be notified of headline selection events.
+     * @param listener the listener to notify.
+     */
+    public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener listener) {
+        mHeadlineSelectedListener = listener;
+    }
+
+    /**
+     * Load and display the headlines for the given news category.
+     * @param categoryIndex the index of the news category to display.
+     */
+    public void loadCategory(int categoryIndex) {
+        mHeadlinesList.clear();
+        int i;
+        NewsCategory cat = NewsSource.getInstance().getCategory(categoryIndex);
+        for (i = 0; i < cat.getArticleCount(); i++) {
+            mHeadlinesList.add(cat.getArticle(i).getHeadline());
+        }
+        mListAdapter.notifyDataSetChanged();
+    }
+
+    /**
+     * Handles a click on a headline.
+     *
+     * This causes the configured listener to be notified that a headline was selected.
+     */
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        if (null != mHeadlineSelectedListener) {
+            mHeadlineSelectedListener.onHeadlineSelected(position);
+        }
+    }
+
+    /** Sets choice mode for the list
+     *
+     * @param selectable whether list is to be selectable.
+     */
+    public void setSelectable(boolean selectable) {
+        if (selectable) {
+            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        }
+        else {
+            getListView().setChoiceMode(ListView.CHOICE_MODE_NONE);
+        }
+    }
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsArticle.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsArticle.java
new file mode 100644
index 0000000..9feaee2
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsArticle.java
@@ -0,0 +1,63 @@
+/*
+ * 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.newsreader;
+
+/**
+ * A news article.
+ *
+ * An article consists of a headline and a body. In this example app, article text is dynamically
+ * generated nonsense.
+ */
+public class NewsArticle {
+    // How many sentences in each paragraph?
+    final int SENTENCES_PER_PARAGRAPH = 20;
+
+    // How many paragraphs in each article?
+    final int PARAGRAPHS_PER_ARTICLE = 5;
+
+    // Headline and body
+    String mHeadline, mBody;
+
+    /**
+     * Create a news article with randomly generated text.
+     * @param ngen the nonsense generator to use.
+     */
+    public NewsArticle(NonsenseGenerator ngen) {
+        mHeadline = ngen.makeHeadline();
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("<html><body>");
+        sb.append("<h1>" + mHeadline + "</h1>");
+        int i;
+        for (i = 0; i < PARAGRAPHS_PER_ARTICLE; i++) {
+            sb.append("<p>").append(ngen.makeText(SENTENCES_PER_PARAGRAPH)).append("</p>");
+        }
+
+        sb.append("</body></html>");
+        mBody = sb.toString();
+    }
+
+    /** Returns the headline. */
+    public String getHeadline() {
+        return mHeadline;
+    }
+
+    /** Returns the article body (HTML)*/
+    public String getBody() {
+        return mBody;
+    }
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsCategory.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsCategory.java
new file mode 100644
index 0000000..75c7b22
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsCategory.java
@@ -0,0 +1,52 @@
+/*
+ * 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.newsreader;
+
+/**
+ * A news category (collection of articles).
+ */
+public class NewsCategory {
+    // how many articles?
+    final int ARTICLES_PER_CATEGORY = 20;
+
+    // array of our articles
+    NewsArticle[] mArticles;
+
+    /**
+     * Create a news category.
+     *
+     * The articles are dynamically generated with fun and random nonsense.
+     */
+    public NewsCategory() {
+        NonsenseGenerator ngen = new NonsenseGenerator();
+        mArticles = new NewsArticle[ARTICLES_PER_CATEGORY];
+        int i;
+        for (i = 0; i < mArticles.length; i++) {
+            mArticles[i] = new NewsArticle(ngen);
+        }
+    }
+
+    /** Returns how many articles exist in this category. */
+    public int getArticleCount() {
+        return mArticles.length;
+    }
+
+    /** Gets a particular article by index. */
+    public NewsArticle getArticle(int index) {
+        return mArticles[index];
+    }
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsReaderActivity.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsReaderActivity.java
new file mode 100644
index 0000000..30ae0ae
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsReaderActivity.java
@@ -0,0 +1,253 @@
+/*
+ * 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.newsreader;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.SpinnerAdapter;
+
+/**
+ * Main activity: shows headlines list and articles, if layout permits.
+ *
+ * This is the main activity of the application. It can have several different layouts depending
+ * on the SDK version, screen size and orientation. The configurations are divided in two large
+ * groups: single-pane layouts and dual-pane layouts.
+ *
+ * In single-pane mode, this activity shows a list of headlines using a {@link HeadlinesFragment}.
+ * When the user clicks on a headline, a separate activity (a {@link ArticleActivity}) is launched
+ * to show the news article.
+ *
+ * In dual-pane mode, this activity shows a {@HeadlinesFragment} on the left side and an
+ * {@ArticleFragment} on the right side. When the user selects a headline on the left, the
+ * corresponding article is shown on the right.
+ *
+ * If an Action Bar is available (large enough screen and SDK version 11 or up), navigation
+ * controls are shown in the Action Bar (whether to show tabs or a list depends on the layout).
+ * If an Action Bar is not available, a regular image and button are shown in the top area of
+ * the screen, emulating an Action Bar.
+ */
+public class NewsReaderActivity extends FragmentActivity
+        implements HeadlinesFragment.OnHeadlineSelectedListener,
+                   CompatActionBarNavListener,
+                   OnClickListener  {
+
+    // Whether or not we are in dual-pane mode
+    boolean mIsDualPane = false;
+
+    // The fragment where the headlines are displayed
+    HeadlinesFragment mHeadlinesFragment;
+
+    // The fragment where the article is displayed (null if absent)
+    ArticleFragment mArticleFragment;
+
+    // The news category and article index currently being displayed
+    int mCatIndex = 0;
+    int mArtIndex = 0;
+    NewsCategory mCurrentCat;
+
+    // List of category titles
+    final String CATEGORIES[] = { "Top Stories", "Politics", "Economy", "Technology" };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main_layout);
+
+        // find our fragments
+        mHeadlinesFragment = (HeadlinesFragment) getSupportFragmentManager().findFragmentById(
+                R.id.headlines);
+        mArticleFragment = (ArticleFragment) getSupportFragmentManager().findFragmentById(
+                R.id.article);
+
+        // Determine whether we are in single-pane or dual-pane mode by testing the visibility
+        // of the article view.
+        View articleView = findViewById(R.id.article);
+        mIsDualPane = articleView != null && articleView.getVisibility() == View.VISIBLE;
+
+        // Register ourselves as the listener for the headlines fragment events.
+        mHeadlinesFragment.setOnHeadlineSelectedListener(this);
+
+        // Set up the Action Bar (or not, if one is not available)
+        int catIndex = savedInstanceState == null ? 0 : savedInstanceState.getInt("catIndex", 0);
+        setUpActionBar(mIsDualPane, catIndex);
+
+        // Set up headlines fragment
+        mHeadlinesFragment.setSelectable(mIsDualPane);
+        restoreSelection(savedInstanceState);
+
+        // Set up the category button (shown if an Action Bar is not available)
+        Button catButton = (Button) findViewById(R.id.categorybutton);
+        if (catButton != null) {
+            catButton.setOnClickListener(this);
+        }
+    }
+
+    /** Restore category/article selection from saved state. */
+    void restoreSelection(Bundle savedInstanceState) {
+        if (savedInstanceState != null) {
+            setNewsCategory(savedInstanceState.getInt("catIndex", 0));
+            if (mIsDualPane) {
+                int artIndex = savedInstanceState.getInt("artIndex", 0);
+                mHeadlinesFragment.setSelection(artIndex);
+                onHeadlineSelected(artIndex);
+            }
+        }
+    }
+
+    @Override
+    public void onRestoreInstanceState(Bundle savedInstanceState) {
+        restoreSelection(savedInstanceState);
+    }
+
+    /** Sets up Action Bar (if present).
+     *
+     * @param showTabs whether to show tabs (if false, will show list).
+     * @param selTab the selected tab or list item.
+     */
+    public void setUpActionBar(boolean showTabs, int selTab) {
+        if (Build.VERSION.SDK_INT < 11) {
+            // No action bar for you!
+            // But do not despair. In this case the layout includes a bar across the
+            // top that looks and feels like an action bar, but is made up of regular views.
+            return;
+        }
+
+        android.app.ActionBar actionBar = getActionBar();
+        actionBar.setDisplayShowTitleEnabled(false);
+
+        // Set up a CompatActionBarNavHandler to deliver us the Action Bar nagivation events
+        CompatActionBarNavHandler handler = new CompatActionBarNavHandler(this);
+        if (showTabs) {
+            actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_TABS);
+            int i;
+            for (i = 0; i < CATEGORIES.length; i++) {
+                actionBar.addTab(actionBar.newTab().setText(CATEGORIES[i]).setTabListener(handler));
+            }
+            actionBar.setSelectedNavigationItem(selTab);
+        }
+        else {
+            actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_LIST);
+            SpinnerAdapter adap = new ArrayAdapter<String>(this, R.layout.actionbar_list_item,
+                    CATEGORIES);
+            actionBar.setListNavigationCallbacks(adap, handler);
+        }
+
+        // Show logo instead of icon+title.
+        actionBar.setDisplayUseLogoEnabled(true);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        setNewsCategory(0);
+    }
+
+    /** Sets the displayed news category.
+     *
+     * This causes the headlines fragment to be repopulated with the appropriate headlines.
+     */
+    void setNewsCategory(int categoryIndex) {
+        mCatIndex = categoryIndex;
+        mCurrentCat = NewsSource.getInstance().getCategory(categoryIndex);
+        mHeadlinesFragment.loadCategory(categoryIndex);
+
+        // If we are displaying the article on the right, we have to update that too
+        if (mIsDualPane) {
+            mArticleFragment.displayArticle(mCurrentCat.getArticle(0));
+        }
+
+        // If we are displaying a "category" button (on the ActionBar-less UI), we have to update
+        // its text to reflect the current category.
+        Button catButton = (Button) findViewById(R.id.categorybutton);
+        if (catButton != null) {
+            catButton.setText(CATEGORIES[mCatIndex]);
+        }
+    }
+
+    /** Called when a headline is selected.
+     *
+     * This is called by the HeadlinesFragment (via its listener interface) to notify us that a
+     * headline was selected in the Action Bar. The way we react depends on whether we are in
+     * single or dual-pane mode. In single-pane mode, we launch a new activity to display the
+     * selected article; in dual-pane mode we simply display it on the article fragment.
+     *
+     * @param index the index of the selected headline.
+     */
+    @Override
+    public void onHeadlineSelected(int index) {
+        mArtIndex = index;
+        if (mIsDualPane) {
+            // display it on the article fragment
+            mArticleFragment.displayArticle(mCurrentCat.getArticle(index));
+        }
+        else {
+            // use separate activity
+            Intent i = new Intent(this, ArticleActivity.class);
+            i.putExtra("catIndex", mCatIndex);
+            i.putExtra("artIndex", index);
+            startActivity(i);
+        }
+    }
+
+    /** Called when a news category is selected.
+     *
+     * This is called by our CompatActionBarNavHandler in response to the user selecting a
+     * news category in the Action Bar. We react by loading and displaying the headlines for
+     * that category.
+     *
+     * @param catIndex the index of the selected news category.
+     */
+    @Override
+    public void onCategorySelected(int catIndex) {
+        setNewsCategory(catIndex);
+    }
+
+    /** Save instance state. Saves current category/article index. */
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        outState.putInt("catIndex", mCatIndex);
+        outState.putInt("artIndex", mArtIndex);
+        super.onSaveInstanceState(outState);
+    }
+
+    /** Called when news category button is clicked.
+     *
+     * This is the button that we display on UIs that don't have an action bar. This button
+     * calls up a list of news categories and switches to the given category.
+     */
+    @Override
+    public void onClick(View v) {
+        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+        builder.setTitle("Select a Category");
+        builder.setItems(CATEGORIES, new DialogInterface.OnClickListener() {
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                setNewsCategory(which);
+            }
+        });
+        AlertDialog d = builder.create();
+        d.show();
+    }
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsSource.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsSource.java
new file mode 100644
index 0000000..18cbe8b
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NewsSource.java
@@ -0,0 +1,59 @@
+/*
+ * 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.newsreader;
+
+/**
+ * Source of strange and wonderful news.
+ *
+ * This singleton functions as the repository for the news we display.
+ */
+public class NewsSource {
+    // the instance
+    static NewsSource instance = null;
+
+    // the category names
+    final String[] CATEGORIES = { "Top Stories", "US", "Politics", "Economy" };
+
+    // category objects, representing each category
+    NewsCategory[] mCategory;
+
+    /** Returns the singleton instance of this class. */
+    public static NewsSource getInstance() {
+        if (instance == null) {
+            instance = new NewsSource();
+        }
+        return instance;
+    }
+
+    public NewsSource() {
+        int i;
+        mCategory = new NewsCategory[CATEGORIES.length];
+        for (i = 0; i < CATEGORIES.length; i++) {
+            mCategory[i] = new NewsCategory();
+        }
+    }
+
+    /** Returns the list of news categories. */
+    public String[] getCategories() {
+        return CATEGORIES;
+    }
+
+    /** Returns a category by index. */
+    public NewsCategory getCategory(int categoryIndex) {
+        return mCategory[categoryIndex];
+    }
+}
diff --git a/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NonsenseGenerator.java b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NonsenseGenerator.java
new file mode 100644
index 0000000..e38b777
--- /dev/null
+++ b/samples/training/multiscreen/newsreader/src/com/example/android/newsreader/NonsenseGenerator.java
@@ -0,0 +1,174 @@
+/*
+ * 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.newsreader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/** Generator of random news. More fun than "lorem ipsum", isn't it?
+ *
+ * This generator can construct headlines and news articles by randomly composing sentences.
+ * Any resemblance to actual events (or, actually, any resemblance to anything that makes sense)
+ * is merely coincidental!
+ */
+public class NonsenseGenerator {
+    Random mRandom;
+
+    static final String[] THINGS = { "bottle", "bowl", "brick", "building",
+            "bunny", "cake", "car", "cat", "cup", "desk", "dog", "duck",
+            "elephant", "engineer", "fork", "glass", "griffon", "hat", "key", "knife", "lawyer",
+            "llama", "manual", "meat", "monitor", "mouse", "tangerine", "paper", "pear", "pen",
+            "pencil", "phone", "physicist", "planet", "potato", "road", "salad", "shoe", "slipper",
+            "soup", "spoon", "star", "steak", "table", "terminal", "treehouse", "truck",
+            "watermelon", "window" };
+
+    static final String[] ADJECTIVES = { "red", "green", "yellow", "gray", "solid", "fierce",
+            "friendly", "cowardly", "convenient", "foreign", "national", "tall",
+            "short", "metallic", "golden", "silver", "sweet", "nationwide", "competitive",
+            "stable", "municipal", "famous" };
+
+    static final String[] VERBS_PAST = { "accused", "threatened", "warned", "spoke to",
+            "has met with",
+            "was seen in the company of", "advanced towards", "collapsed on",
+            "signed a partnership with", "was converted into", "became", "was authorized to sell",
+            "sold", "bought", "rented", "allegedly spoke to", "leased", "is now investing on",
+            "is expected to buy", "is expected to sell", "was reported to have met with",
+            "will work together with", "plans to cease fire against", "started a war with",
+            "signed a truce with", "is now managing", "is investigating" };
+
+    static final String[] VERBS_PRESENT = { "accuses", "threatens", "warns", "speaks to",
+            "meets with",
+            "seen with", "advances towards", "collapses on",
+            "signs partnership with", "converts into", "becomes", "is authorized to sell",
+            "sells", "buys", "rents", "allegedly speaks to", "leases", "invests on",
+            "expected to buy", "expected to sell", "reported to have met with",
+            "works together with", "plans cease fire against", "starts war with",
+            "signs truce with", "now manages" };
+
+    public NonsenseGenerator() {
+        mRandom = new Random();
+    }
+
+    /** Produces something that reads like a headline. */
+    public String makeHeadline() {
+        return makeSentence(true);
+    }
+
+    /** Produces a sentence.
+     *
+     * @param isHeadline whether the sentence should look like a headline or not.
+     * @return the generated sentence.
+     */
+    public String makeSentence(boolean isHeadline) {
+        List<String> words = new ArrayList<String>();
+        generateSentence(words, isHeadline);
+        words.set(0, String.valueOf(Character.toUpperCase(words.get(0).charAt(0))) +
+                words.get(0).substring(1));
+        return joinWords(words);
+    }
+
+    /** Produces news article text.
+     *
+     * @param numSentences how many sentences the text is to contain.
+     * @return the generated text.
+     */
+    public String makeText(int numSentences) {
+        StringBuilder sb = new StringBuilder();
+        while (numSentences-- > 0) {
+            sb.append(makeSentence(false) + ".");
+            if (numSentences > 0) {
+                sb.append(" ");
+            }
+        }
+        return sb.toString();
+    }
+
+    /** Generates a sentence.
+     *
+     * @param words the list of words to which the sentence will be appended.
+     * @param isHeadline whether the sentence must look like a headline or not.
+     */
+    private void generateSentence(List<String> words, boolean isHeadline) {
+        if (!isHeadline && mRandom.nextInt(4) == 0)
+            generateTimeClause(words, isHeadline);
+        generateAgent(words, isHeadline);
+        generatePredicate(words, isHeadline);
+    }
+
+    private void generateTimeClause(List<String> words, boolean isHeadline) {
+        if (mRandom.nextInt(2) == 0) {
+            words.add(pickOneOf("today", "yesterday", "this afternoon", "this morning",
+                    "last evening"));
+        }
+        else {
+            words.add(pickOneOf("this", "last"));
+            words.add(pickOneOf("Monday", "Tuesday", "Wednesday", "Thursday"));
+            words.add(pickOneOf("morning", "afternoon", "evening"));
+        }
+    }
+
+    private void generateAgent(List<String> words, boolean isHeadline) {
+       if (!isHeadline) {
+           words.add(pickOneOf("a", "the"));
+       }
+       if (mRandom.nextInt(3) != 0) {
+           words.add(pickOneOf(ADJECTIVES));
+       }
+       words.add(pickOneOf(THINGS));
+    }
+
+    private void generatePredicate(List<String> words, boolean isHeadline) {
+        words.add(pickOneOf(isHeadline ? VERBS_PRESENT : VERBS_PAST));
+        if (!isHeadline)
+            words.add(pickOneOf("a", "the"));
+        if (mRandom.nextInt(3) != 0) {
+            words.add(pickOneOf(ADJECTIVES));
+        }
+        words.add(pickOneOf(THINGS));
+
+        if (mRandom.nextInt(3) == 0) {
+            words.add(isHeadline ? pickOneOf(", claims", ", says") :
+                 pickOneOf(", claimed", ", said", ", reported"));
+            if (!isHeadline)
+                words.add(pickOneOf("a", "the"));
+            if (mRandom.nextInt(3) != 0) {
+                words.add(pickOneOf(ADJECTIVES));
+            }
+            words.add(pickOneOf(THINGS));
+        }
+    }
+
+    private String pickOneOf(String ... options) {
+        return options[mRandom.nextInt(options.length)];
+    }
+
+    private static String joinWords(List<String> words) {
+        int i;
+        if (words.size() == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append(words.get(0));
+        for (i = 1; i < words.size(); i++) {
+            if (!words.get(i).startsWith(",")) {
+                sb.append(" ");
+            }
+            sb.append(words.get(i));
+        }
+        return sb.toString();
+    }
+}