Merge "Show the see more item when scrolling is disabled on long list"
diff --git a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
index d845b72..336c5d6 100644
--- a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
+++ b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SampleSliceProvider.java
@@ -46,6 +46,8 @@
  */
 public class SampleSliceProvider extends SliceProvider {
 
+    private static final boolean TEST_CUSTOM_SEE_MORE = false;
+
     public static final String ACTION_WIFI_CHANGED =
             "com.example.androidx.slice.action.WIFI_CHANGED";
     public static final String ACTION_TOAST =
@@ -414,18 +416,50 @@
                 state = ""; // just don't show anything?
                 break;
         }
+
+        // Set the first row as a toggle
         boolean finalWifiEnabled = wifiEnabled;
         SliceAction primaryAction = new SliceAction(getIntent(Settings.ACTION_WIFI_SETTINGS),
                 Icon.createWithResource(getContext(), R.drawable.ic_wifi), "Wi-fi Settings");
-        return new ListBuilder(getContext(), sliceUri)
+        ListBuilder lb = new ListBuilder(getContext(), sliceUri)
                 .setColor(0xff4285f4)
                 .addRow(b -> b
                     .setTitle("Wi-fi")
                     .setSubtitle(state)
                     .addEndItem(new SliceAction(getBroadcastIntent(ACTION_WIFI_CHANGED, null),
                             "Toggle wifi", finalWifiEnabled))
-                    .setPrimaryAction(primaryAction))
-                .build();
+                    .setPrimaryAction(primaryAction));
+
+        // Add fake wifi networks
+        int[] wifiIcons = new int[] {R.drawable.ic_wifi_full, R.drawable.ic_wifi_low,
+                R.drawable.ic_wifi_fair};
+        for (int i = 0; i < 10; i++) {
+            final int iconId = wifiIcons[i % wifiIcons.length];
+            Icon icon = Icon.createWithResource(getContext(), iconId);
+            final String networkName = "Network" + i;
+            ListBuilder.RowBuilder rb = new ListBuilder.RowBuilder(lb);
+            rb.setTitleItem(icon)
+                .setTitle("Network" + networkName);
+            boolean locked = i % 3 == 0;
+            if (locked) {
+                rb.addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_lock));
+            }
+            String message = locked ? "Open wifi password dialog" : "Connect to " + networkName;
+            rb.setPrimaryAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, message), icon,
+                    message));
+            lb.addRow(rb);
+        }
+
+        // Add see more intent
+        if (TEST_CUSTOM_SEE_MORE) {
+            lb.addSeeMoreRow(rb -> rb
+                    .setTitle("See all available networks")
+                    .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_right_caret))
+                    .setPrimaryAction(primaryAction));
+        } else {
+            lb.addSeeMoreAction(primaryAction.getAction());
+        }
+        return lb.build();
     }
 
     private Slice createStarRatingInputRange(Uri sliceUri) {
diff --git a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
index d9d0284..02ba3cb 100644
--- a/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
+++ b/samples/SupportSliceDemos/src/main/java/com/example/androidx/slice/demos/SliceBrowser.java
@@ -67,6 +67,7 @@
     private static final String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
     private static final boolean TEST_INTENT = false;
     private static final boolean TEST_THEMES = false;
+    private static final boolean SCROLLING_ENABLED = true;
 
     private ArrayList<Uri> mSliceUris = new ArrayList<Uri>();
     private int mSelectedMode;
@@ -289,6 +290,7 @@
         if (mSliceLiveData != null) {
             mSliceLiveData.removeObservers(this);
         }
+        v.setScrollable(SCROLLING_ENABLED);
         return v;
     }
 }
diff --git a/samples/SupportSliceDemos/src/main/res/drawable/ic_lock.xml b/samples/SupportSliceDemos/src/main/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..7a79428
--- /dev/null
+++ b/samples/SupportSliceDemos/src/main/res/drawable/ic_lock.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector android:height="16dp" android:viewportHeight="24.0"
+    android:viewportWidth="24.0" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1s3.1,1.39 3.1,3.1v2L8.9,8L8.9,6zM18,20L6,20L6,10h12v10z"/>
+</vector>
diff --git a/samples/SupportSliceDemos/src/main/res/drawable/ic_more.xml b/samples/SupportSliceDemos/src/main/res/drawable/ic_more.xml
new file mode 100644
index 0000000..a4f9d06
--- /dev/null
+++ b/samples/SupportSliceDemos/src/main/res/drawable/ic_more.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M6,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
+</vector>
diff --git a/samples/SupportSliceDemos/src/main/res/drawable/ic_right_caret.xml b/samples/SupportSliceDemos/src/main/res/drawable/ic_right_caret.xml
new file mode 100644
index 0000000..3310e62
--- /dev/null
+++ b/samples/SupportSliceDemos/src/main/res/drawable/ic_right_caret.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
+</vector>
diff --git a/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_fair.xml b/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_fair.xml
new file mode 100644
index 0000000..4e92a64
--- /dev/null
+++ b/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_fair.xml
@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.01,21.49L23.64,7c-0.45,-0.34 -4.93,-4 -11.64,-4C5.28,3 0.81,6.66 0.36,7l11.63,14.49 0.01,0.01 0.01,-0.01z"
+        android:fillAlpha=".3"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M3.53,10.95l8.46,10.54 0.01,0.01 0.01,-0.01 8.46,-10.54C20.04,10.62 16.81,8 12,8c-4.81,0 -8.04,2.62 -8.47,2.95z"/>
+</vector>
diff --git a/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_full.xml b/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_full.xml
new file mode 100644
index 0000000..0b37310
--- /dev/null
+++ b/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_full.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.01,21.49L23.64,7c-0.45,-0.34 -4.93,-4 -11.64,-4C5.28,3 0.81,6.66 0.36,7l11.63,14.49 0.01,0.01 0.01,-0.01z"/>
+</vector>
diff --git a/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_low.xml b/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_low.xml
new file mode 100644
index 0000000..87c84ce
--- /dev/null
+++ b/samples/SupportSliceDemos/src/main/res/drawable/ic_wifi_low.xml
@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.01,21.49L23.64,7c-0.45,-0.34 -4.93,-4 -11.64,-4C5.28,3 0.81,6.66 0.36,7l11.63,14.49 0.01,0.01 0.01,-0.01z"
+        android:fillAlpha=".3"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M6.67,14.86L12,21.49v0.01l0.01,-0.01 5.33,-6.63C17.06,14.65 15.03,13 12,13s-5.06,1.65 -5.33,1.86z"/>
+</vector>
diff --git a/slices/builders/src/main/java/androidx/app/slice/builders/impl/ListBuilderV1Impl.java b/slices/builders/src/main/java/androidx/app/slice/builders/impl/ListBuilderV1Impl.java
index 0a73f34..054c499 100644
--- a/slices/builders/src/main/java/androidx/app/slice/builders/impl/ListBuilderV1Impl.java
+++ b/slices/builders/src/main/java/androidx/app/slice/builders/impl/ListBuilderV1Impl.java
@@ -140,7 +140,8 @@
         getBuilder().addSubSlice(
                 new Slice.Builder(getBuilder())
                         .addHints(HINT_SEE_MORE)
-                        .addAction(intent, new Slice.Builder(getBuilder()).build(), null)
+                        .addAction(intent, new Slice.Builder(getBuilder())
+                                .addHints(HINT_SEE_MORE).build(), null)
                         .build());
     }
 
diff --git a/slices/view/src/androidTest/java/androidx/app/slice/render/SliceCreator.java b/slices/view/src/androidTest/java/androidx/app/slice/render/SliceCreator.java
index 546f1e3..5e91022 100644
--- a/slices/view/src/androidTest/java/androidx/app/slice/render/SliceCreator.java
+++ b/slices/view/src/androidTest/java/androidx/app/slice/render/SliceCreator.java
@@ -48,7 +48,7 @@
             "com.example.androidx.slice.action.TOAST";
     public static final String EXTRA_TOAST_MESSAGE = "com.example.androidx.extra.TOAST_MESSAGE";
 
-    public static final String[] URI_PATHS = {"message", "wifi", "note", "ride", "toggle",
+    public static final String[] URI_PATHS = {"message", "wifi", "wifi2", "note", "ride", "toggle",
             "toggle2", "contact", "gallery", "weather"};
 
     private final Context mContext;
@@ -78,7 +78,9 @@
             case "/message":
                 return createMessagingSlice(sliceUri);
             case "/wifi":
-                return createWifiSlice(sliceUri);
+                return createWifiSlice(sliceUri, false /* customSeeMore */);
+            case "/wifi2":
+                return createWifiSlice(sliceUri, true /* customSeeMore */);
             case "/note":
                 return createNoteSlice(sliceUri);
             case "/ride":
@@ -283,7 +285,7 @@
                 .build();
     }
 
-    private Slice createWifiSlice(Uri sliceUri) {
+    private Slice createWifiSlice(Uri sliceUri, boolean customSeeMore) {
         // Get wifi state
         WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
         int wifiState = wifiManager.getWifiState();
@@ -305,18 +307,46 @@
                 break;
         }
         boolean finalWifiEnabled = wifiEnabled;
-        ListBuilder b = new ListBuilder(getContext(), sliceUri);
+        ListBuilder lb = new ListBuilder(getContext(), sliceUri);
         SliceAction primaryAction = new SliceAction(getIntent(Settings.ACTION_WIFI_SETTINGS),
                 Icon.createWithResource(getContext(), R.drawable.ic_wifi), "Wi-fi Settings");
-        return b.setColor(0xff4285f4)
-                .addRow(new ListBuilder.RowBuilder(b)
-                    .setTitle("Wi-fi")
-                    .setTitleItem(Icon.createWithResource(getContext(), R.drawable.ic_wifi))
-                    .setSubtitle(state)
-                        .addEndItem(new SliceAction(getBroadcastIntent(ACTION_WIFI_CHANGED, null),
-                                "Toggle wifi", finalWifiEnabled))
-                    .setPrimaryAction(primaryAction))
-            .build();
+        lb.setColor(0xff4285f4);
+        lb.addRow(new ListBuilder.RowBuilder(lb)
+                .setTitle("Wi-fi")
+                .setTitleItem(Icon.createWithResource(getContext(), R.drawable.ic_wifi))
+                .setSubtitle(state)
+                .addEndItem(new SliceAction(getBroadcastIntent(ACTION_WIFI_CHANGED, null),
+                        "Toggle wifi", finalWifiEnabled))
+                .setPrimaryAction(primaryAction));
+
+        // Add fake wifi networks
+        int[] wifiIcons = new int[] {R.drawable.ic_wifi_full, R.drawable.ic_wifi_low,
+                R.drawable.ic_wifi_fair};
+        for (int i = 0; i < 10; i++) {
+            final int iconId = wifiIcons[i % wifiIcons.length];
+            Icon icon = Icon.createWithResource(getContext(), iconId);
+            final String networkName = "Network" + i;
+            ListBuilder.RowBuilder rb = new ListBuilder.RowBuilder(lb);
+            rb.setTitleItem(icon)
+                    .setTitle("Network" + networkName);
+            boolean locked = i % 3 == 0;
+            if (locked) {
+                rb.addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_lock));
+            }
+            String message = locked ? "Open wifi password dialog" : "Connect to " + networkName;
+            rb.setPrimaryAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, message), icon,
+                    message));
+            lb.addRow(rb);
+        }
+        if (customSeeMore) {
+            lb.addSeeMoreRow(new ListBuilder.RowBuilder(lb)
+                    .setTitle("See all available networks")
+                    .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_right_caret))
+                    .setPrimaryAction(primaryAction));
+        } else {
+            lb.addSeeMoreAction(primaryAction.getAction());
+        }
+        return lb.build();
     }
 
     private PendingIntent getIntent(String action) {
diff --git a/slices/view/src/androidTest/java/androidx/app/slice/render/SliceRenderer.java b/slices/view/src/androidTest/java/androidx/app/slice/render/SliceRenderer.java
index dc9196e..067e4c7 100644
--- a/slices/view/src/androidTest/java/androidx/app/slice/render/SliceRenderer.java
+++ b/slices/view/src/androidTest/java/androidx/app/slice/render/SliceRenderer.java
@@ -127,7 +127,13 @@
         }
         mDoneLatch = new CountDownLatch(SliceCreator.URI_PATHS.length);
         for (String slice : SliceCreator.URI_PATHS) {
-            doRender(slice, new File(output, String.format("%s.png", slice)));
+            doRender(slice, new File(output, String.format("%s.png", slice)),
+                    true /* scrollable */);
+            if (slice.equals("wifi") || slice.equals("wifi2")) {
+                // Test scrolling
+                doRender(slice, new File(output, String.format("%s-no-scroll.png", slice)),
+                        false /* scrollable */);
+            }
         }
         Log.d(TAG, "Wrote render to " + output.getAbsolutePath());
         mContext.runOnUiThread(new Runnable() {
@@ -142,7 +148,7 @@
         }
     }
 
-    private void doRender(final String slice, final File file) {
+    private void doRender(final String slice, final File file, final boolean scrollable) {
         Log.d(TAG, "Rendering " + slice + " to " + file.getAbsolutePath());
 
         final Slice s = mSliceCreator.onBindSlice(SliceCreator.getUri(slice, mContext));
@@ -154,6 +160,7 @@
                 mSV1.setSlice(s);
                 mSV2.setSlice(s);
                 mSV3.setSlice(s);
+                mSV3.setScrollable(scrollable);
                 mSV1.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                     @Override
                     public void onLayoutChange(View v, int left, int top, int right, int bottom,
diff --git a/slices/view/src/androidTest/res/drawable/ic_lock.xml b/slices/view/src/androidTest/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..7a79428
--- /dev/null
+++ b/slices/view/src/androidTest/res/drawable/ic_lock.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector android:height="16dp" android:viewportHeight="24.0"
+    android:viewportWidth="24.0" android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1s3.1,1.39 3.1,3.1v2L8.9,8L8.9,6zM18,20L6,20L6,10h12v10z"/>
+</vector>
diff --git a/slices/view/src/androidTest/res/drawable/ic_right_caret.xml b/slices/view/src/androidTest/res/drawable/ic_right_caret.xml
new file mode 100644
index 0000000..3310e62
--- /dev/null
+++ b/slices/view/src/androidTest/res/drawable/ic_right_caret.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
+</vector>
diff --git a/slices/view/src/androidTest/res/drawable/ic_wifi_fair.xml b/slices/view/src/androidTest/res/drawable/ic_wifi_fair.xml
new file mode 100644
index 0000000..4e92a64
--- /dev/null
+++ b/slices/view/src/androidTest/res/drawable/ic_wifi_fair.xml
@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.01,21.49L23.64,7c-0.45,-0.34 -4.93,-4 -11.64,-4C5.28,3 0.81,6.66 0.36,7l11.63,14.49 0.01,0.01 0.01,-0.01z"
+        android:fillAlpha=".3"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M3.53,10.95l8.46,10.54 0.01,0.01 0.01,-0.01 8.46,-10.54C20.04,10.62 16.81,8 12,8c-4.81,0 -8.04,2.62 -8.47,2.95z"/>
+</vector>
diff --git a/slices/view/src/androidTest/res/drawable/ic_wifi_full.xml b/slices/view/src/androidTest/res/drawable/ic_wifi_full.xml
new file mode 100644
index 0000000..0b37310
--- /dev/null
+++ b/slices/view/src/androidTest/res/drawable/ic_wifi_full.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.01,21.49L23.64,7c-0.45,-0.34 -4.93,-4 -11.64,-4C5.28,3 0.81,6.66 0.36,7l11.63,14.49 0.01,0.01 0.01,-0.01z"/>
+</vector>
diff --git a/slices/view/src/androidTest/res/drawable/ic_wifi_low.xml b/slices/view/src/androidTest/res/drawable/ic_wifi_low.xml
new file mode 100644
index 0000000..87c84ce
--- /dev/null
+++ b/slices/view/src/androidTest/res/drawable/ic_wifi_low.xml
@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12.01,21.49L23.64,7c-0.45,-0.34 -4.93,-4 -11.64,-4C5.28,3 0.81,6.66 0.36,7l11.63,14.49 0.01,0.01 0.01,-0.01z"
+        android:fillAlpha=".3"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M6.67,14.86L12,21.49v0.01l0.01,-0.01 5.33,-6.63C17.06,14.65 15.03,13 12,13s-5.06,1.65 -5.33,1.86z"/>
+</vector>
diff --git a/slices/view/src/main/java/androidx/app/slice/widget/LargeTemplateView.java b/slices/view/src/main/java/androidx/app/slice/widget/LargeTemplateView.java
index bdd1ac5..4ab6d0c 100644
--- a/slices/view/src/main/java/androidx/app/slice/widget/LargeTemplateView.java
+++ b/slices/view/src/main/java/androidx/app/slice/widget/LargeTemplateView.java
@@ -23,6 +23,7 @@
 import android.support.v7.widget.RecyclerView;
 import android.util.AttributeSet;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import androidx.app.slice.Slice;
@@ -40,6 +41,8 @@
     private Slice mSlice;
     private boolean mIsScrollable;
     private ListContent mListContent;
+    private List<SliceItem> mDisplayedItems = new ArrayList<>();
+    private int mDisplayedItemsHeight = 0;
 
     public LargeTemplateView(Context context) {
         super(context);
@@ -51,8 +54,18 @@
     }
 
     @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int height = MeasureSpec.getSize(heightMeasureSpec);
+        if (mDisplayedItems.size() > 0 && mDisplayedItemsHeight > height) {
+            // Need to resize
+            updateDisplayedItems(height);
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    @Override
     public int getActualHeight() {
-        return mListContent != null ? mListContent.getListHeight() : 0;
+        return mDisplayedItemsHeight;
     }
 
     @Override
@@ -93,23 +106,46 @@
 
     private void populate() {
         if (mSlice == null) {
+            resetView();
             return;
         }
         mListContent = new ListContent(getContext(), mSlice);
-        mAdapter.setSliceItems(mListContent.getRowItems(), mTintColor);
+        updateDisplayedItems(getMeasuredHeight());
     }
 
     /**
      * Whether or not the content in this template should be scrollable.
      */
     public void setScrollable(boolean isScrollable) {
-        // TODO -- restrict / enable how much this view can show
         mIsScrollable = isScrollable;
+        updateDisplayedItems(getMeasuredHeight());
+    }
+
+    private void updateDisplayedItems(int height) {
+        if (mListContent == null) {
+            return;
+        }
+        if (!mIsScrollable) {
+            // If we're not scrollable we must cap the number of items we're displaying such
+            // that they fit in the available space
+            if (height == 0) {
+                // Not measured, use default
+                mDisplayedItems = mListContent.getItemsForNonScrollingList(-1);
+            } else {
+                mDisplayedItems = mListContent.getItemsForNonScrollingList(height);
+            }
+        } else {
+            mDisplayedItems = mListContent.getRowItems();
+        }
+        mDisplayedItemsHeight = ListContent.getListHeight(getContext(), mDisplayedItems);
+        mAdapter.setSliceItems(mDisplayedItems, mTintColor);
     }
 
     @Override
     public void resetView() {
         mSlice = null;
+        mDisplayedItemsHeight = 0;
+        mDisplayedItems.clear();
         mAdapter.setSliceItems(null, -1);
         mListContent = null;
     }
diff --git a/slices/view/src/main/java/androidx/app/slice/widget/ListContent.java b/slices/view/src/main/java/androidx/app/slice/widget/ListContent.java
index 246ef0b..d280fe8 100644
--- a/slices/view/src/main/java/androidx/app/slice/widget/ListContent.java
+++ b/slices/view/src/main/java/androidx/app/slice/widget/ListContent.java
@@ -19,6 +19,7 @@
 import static android.app.slice.Slice.HINT_ACTIONS;
 import static android.app.slice.Slice.HINT_HORIZONTAL;
 import static android.app.slice.Slice.HINT_LIST_ITEM;
+import static android.app.slice.Slice.HINT_SEE_MORE;
 import static android.app.slice.Slice.HINT_SHORTCUT;
 import static android.app.slice.Slice.SUBTYPE_COLOR;
 import static android.app.slice.SliceItem.FORMAT_ACTION;
@@ -48,6 +49,7 @@
 
     private SliceItem mHeaderItem;
     private SliceItem mColorItem;
+    private SliceItem mSeeMoreItem;
     private ArrayList<SliceItem> mRowItems = new ArrayList<>();
     private List<SliceItem> mSliceActions;
     private Context mContext;
@@ -79,12 +81,13 @@
         if (mHeaderItem != null) {
             mRowItems.add(mHeaderItem);
         }
+        mSeeMoreItem = getSeeMoreItem(slice);
         // Filter + create row items
         List<SliceItem> children = slice.getItems();
         for (int i = 0; i < children.size(); i++) {
             final SliceItem child = children.get(i);
             final String format = child.getFormat();
-            if (!child.hasAnyHints(HINT_ACTIONS)
+            if (!child.hasAnyHints(HINT_ACTIONS, HINT_SEE_MORE)
                     && (FORMAT_ACTION.equals(format) || FORMAT_SLICE.equals(format))) {
                 if (mHeaderItem == null && !child.hasHint(HINT_LIST_ITEM)) {
                     mHeaderItem = child;
@@ -102,24 +105,70 @@
     }
 
     /**
-     * @return the total height of all the rows contained in this list.
+     * @return the total height of all the rows contained in the provided list.
      */
-    public int getListHeight() {
+    public static int getListHeight(Context context, List<SliceItem> listItems) {
         int height = 0;
-        for (int i = 0; i < mRowItems.size(); i++) {
-            SliceItem item = mRowItems.get(i);
-            if (item.hasHint(HINT_HORIZONTAL)) {
-                GridContent gc = new GridContent(mContext, item);
-                height += gc.getActualHeight();
-            } else {
-                RowContent rc = new RowContent(mContext, item, i == 0 /* isHeader */);
-                height += rc.getActualHeight();
-            }
+        for (int i = 0; i < listItems.size(); i++) {
+            height += getHeight(context, listItems.get(i), i == 0 /* isHeader */);
         }
         return height;
     }
 
     /**
+     * Returns a list of items that can be displayed in the provided height. If this list
+     * has a {@link #getSeeMoreItem()} this will be returned in the list if appropriate.
+     *
+     * @param height the height to restrict the items, -1 to use default sizings for non-scrolling
+     *               templates.
+     * @return the list of items that can be displayed in the provided  height.
+     */
+    @NonNull
+    public List<SliceItem> getItemsForNonScrollingList(int height) {
+        ArrayList<SliceItem> visibleItems = new ArrayList<>();
+        if (mRowItems == null || mRowItems.size() == 0) {
+            return visibleItems;
+        }
+        final int idealItemCount = hasHeader() ? 4 : 3;
+        final int minItemCount = hasHeader() ? 2 : 1;
+        int visibleHeight = 0;
+        // Need to show see more
+        if (mSeeMoreItem != null) {
+            RowContent rc = new RowContent(mContext, mSeeMoreItem, false /* isHeader */);
+            visibleHeight += rc.getActualHeight();
+        }
+        for (int i = 0; i < mRowItems.size(); i++) {
+            int itemHeight = getHeight(mContext, mRowItems.get(i), i == 0 /* isHeader */);
+            if ((height == -1 && i > idealItemCount)
+                    || (height > 0 && visibleHeight + itemHeight > height)) {
+                break;
+            } else {
+                visibleHeight += itemHeight;
+                visibleItems.add(mRowItems.get(i));
+            }
+        }
+        if (mSeeMoreItem != null && visibleItems.size() >= minItemCount) {
+            // Only add see more if we're at least showing one item and it's not the header
+            visibleItems.add(mSeeMoreItem);
+        }
+        if (visibleItems.size() == 0) {
+            // Didn't have enough space to show anything; should still show something
+            visibleItems.add(mRowItems.get(0));
+        }
+        return visibleItems;
+    }
+
+    private static int getHeight(Context context, SliceItem item, boolean isHeader) {
+        if (item.hasHint(HINT_HORIZONTAL)) {
+            GridContent gc = new GridContent(context, item);
+            return gc.getActualHeight();
+        } else {
+            RowContent rc = new RowContent(context, item, isHeader);
+            return rc.getActualHeight();
+        }
+    }
+
+    /**
      * @return whether this list has content that is valid to display.
      */
     public boolean isValid() {
@@ -141,6 +190,11 @@
         return mSliceActions;
     }
 
+    @Nullable
+    public SliceItem getSeeMoreItem() {
+        return mSeeMoreItem;
+    }
+
     public ArrayList<SliceItem> getRowItems() {
         return mRowItems;
     }
@@ -163,6 +217,21 @@
         return null;
     }
 
+    @Nullable
+    private static SliceItem getSeeMoreItem(@NonNull Slice slice) {
+        SliceItem item = SliceQuery.find(slice, null, HINT_SEE_MORE, null);
+        if (item != null && item.hasHint(HINT_SEE_MORE)) {
+            if (FORMAT_SLICE.equals(item.getFormat())) {
+                List<SliceItem> items = item.getSlice().getItems();
+                if (items.size() == 1 && FORMAT_ACTION.equals(items.get(0).getFormat())) {
+                    return items.get(0);
+                }
+                return item;
+            }
+        }
+        return null;
+    }
+
     private static boolean isValidHeader(SliceItem sliceItem) {
         if (FORMAT_SLICE.equals(sliceItem.getFormat()) && !sliceItem.hasHint(HINT_LIST_ITEM)
                 && !sliceItem.hasHint(HINT_ACTIONS)) {
diff --git a/slices/view/src/main/java/androidx/app/slice/widget/RowContent.java b/slices/view/src/main/java/androidx/app/slice/widget/RowContent.java
index a22a37d..0981d06 100644
--- a/slices/view/src/main/java/androidx/app/slice/widget/RowContent.java
+++ b/slices/view/src/main/java/androidx/app/slice/widget/RowContent.java
@@ -17,6 +17,7 @@
 package androidx.app.slice.widget;
 
 import static android.app.slice.Slice.HINT_ACTIONS;
+import static android.app.slice.Slice.HINT_SEE_MORE;
 import static android.app.slice.Slice.HINT_SHORTCUT;
 import static android.app.slice.Slice.HINT_SUMMARY;
 import static android.app.slice.Slice.HINT_TITLE;
@@ -31,6 +32,7 @@
 import static androidx.app.slice.core.SliceHints.SUBTYPE_RANGE;
 
 import android.content.Context;
+import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
 import android.text.TextUtils;
@@ -52,6 +54,7 @@
     private static final String TAG = "RowContent";
 
     private SliceItem mPrimaryAction;
+    private SliceItem mRowSlice;
     private SliceItem mStartItem;
     private SliceItem mTitleItem;
     private SliceItem mSubtitleItem;
@@ -75,6 +78,7 @@
      */
     public void reset() {
         mPrimaryAction = null;
+        mRowSlice = null;
         mStartItem = null;
         mTitleItem = null;
         mSubtitleItem = null;
@@ -89,6 +93,7 @@
     private boolean populate(SliceItem rowSlice, boolean isHeader) {
         reset();
         mIsHeader = isHeader;
+        mRowSlice = rowSlice;
         if (!isValidRow(rowSlice)) {
             Log.w(TAG, "Provided SliceItem is invalid for RowContent");
             return false;
@@ -173,6 +178,14 @@
     }
 
     /**
+     * @return the {@link SliceItem} used to populate this row.
+     */
+    @NonNull
+    public SliceItem getSlice() {
+        return mRowSlice;
+    }
+
+    /**
      * @return the {@link SliceItem} representing the range in the row; can be null.
      */
     @Nullable
@@ -181,30 +194,32 @@
     }
 
     /**
-     * @return whether this row has content that is valid to display.
+     * @return the {@link SliceItem} used for the main intent for this row; can be null.
      */
-    public boolean isValid() {
-        return mStartItem != null
-                || mTitleItem != null
-                || mSubtitleItem != null
-                || mEndItems.size() > 0;
-    }
-
     @Nullable
     public SliceItem getPrimaryAction() {
         return mPrimaryAction;
     }
 
+    /**
+     * @return the {@link SliceItem} to display at the start of this row; can be null.
+     */
     @Nullable
     public SliceItem getStartItem() {
         return mIsHeader ? null : mStartItem;
     }
 
+    /**
+     * @return the {@link SliceItem} representing the title text for this row; can be null.
+     */
     @Nullable
     public SliceItem getTitleItem() {
         return mTitleItem;
     }
 
+    /**
+     * @return the {@link SliceItem} representing the subtitle text for this row; can be null.
+     */
     @Nullable
     public SliceItem getSubtitleItem() {
         return mSubtitleItem;
@@ -215,6 +230,9 @@
         return mSummaryItem == null ? mSubtitleItem : mSummaryItem;
     }
 
+    /**
+     * @return the list of {@link SliceItem} that can be shown as items at the end of the row.
+     */
     public ArrayList<SliceItem> getEndItems() {
         return mEndItems;
     }
@@ -254,6 +272,26 @@
     }
 
     /**
+     * @return whether this row content represents a default see more item.
+     */
+    public boolean isDefaultSeeMore() {
+        return FORMAT_ACTION.equals(mRowSlice.getFormat())
+                && mRowSlice.getSlice().hasHint(HINT_SEE_MORE)
+                && mRowSlice.getSlice().getItems().isEmpty();
+    }
+
+    /**
+     * @return whether this row has content that is valid to display.
+     */
+    public boolean isValid() {
+        return mStartItem != null
+                || mTitleItem != null
+                || mSubtitleItem != null
+                || mEndItems.size() > 0
+                || isDefaultSeeMore();
+    }
+
+    /**
      * @return whether this is a valid item to use to populate a row of content.
      */
     private static boolean isValidRow(SliceItem rowSlice) {
@@ -270,10 +308,18 @@
                     return true;
                 }
             }
+            // Special case: default see more just has an action but no other items
+            if (rowSlice.hasHint(HINT_SEE_MORE) && rowItems.isEmpty()) {
+                return true;
+            }
         }
         return false;
     }
 
+    /**
+     * @return list of {@link SliceItem}s that are valid to display in a row according
+     * to {@link #isValidRowContent(SliceItem, SliceItem)}.
+     */
     private static ArrayList<SliceItem> filterInvalidItems(SliceItem rowSlice) {
         ArrayList<SliceItem> filteredList = new ArrayList<>();
         for (SliceItem i : rowSlice.getSlice().getItems()) {
diff --git a/slices/view/src/main/java/androidx/app/slice/widget/RowView.java b/slices/view/src/main/java/androidx/app/slice/widget/RowView.java
index bcd4f61..8e5bcc6 100644
--- a/slices/view/src/main/java/androidx/app/slice/widget/RowView.java
+++ b/slices/view/src/main/java/androidx/app/slice/widget/RowView.java
@@ -41,8 +41,10 @@
 import android.support.annotation.RestrictTo;
 import android.util.Log;
 import android.util.TypedValue;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Button;
 import android.widget.CompoundButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -84,6 +86,7 @@
     private LinearLayout mEndContainer;
     private SeekBar mSeekBar;
     private ProgressBar mProgressBar;
+    private View mSeeMoreView;
 
     private int mRowIndex;
     private RowContent mRowContent;
@@ -175,6 +178,11 @@
 
     private void populateViews() {
         resetView();
+        if (mRowContent.isDefaultSeeMore()) {
+            showSeeMore();
+            return;
+        }
+
         boolean showStart = false;
         final SliceItem startItem = mRowContent.getStartItem();
         if (startItem != null) {
@@ -456,6 +464,26 @@
         return addedView != null;
     }
 
+    private void showSeeMore() {
+        Button b = (Button) LayoutInflater.from(getContext()).inflate(
+                R.layout.abc_slice_row_show_more, this, false);
+        b.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    mRowContent.getSlice().getAction().send();
+                } catch (CanceledException e) {
+                    Log.w(TAG, "PendingIntent for slice cannot be sent", e);
+                }
+            }
+        });
+        if (mTintColor != -1) {
+            b.setTextColor(mTintColor);
+        }
+        mSeeMoreView = b;
+        addView(mSeeMoreView);
+    }
+
     @Override
     public void onClick(View view) {
         if (mRowAction != null && mRowAction.getActionItem() != null && !mRowAction.isToggle()) {
@@ -496,5 +524,8 @@
         mDivider.setVisibility(View.GONE);
         mSeekBar.setVisibility(View.GONE);
         mProgressBar.setVisibility(View.GONE);
+        if (mSeeMoreView != null) {
+            removeView(mSeeMoreView);
+        }
     }
 }
diff --git a/slices/view/src/main/java/androidx/app/slice/widget/SliceView.java b/slices/view/src/main/java/androidx/app/slice/widget/SliceView.java
index 6e1f0c0..35b8a9e 100644
--- a/slices/view/src/main/java/androidx/app/slice/widget/SliceView.java
+++ b/slices/view/src/main/java/androidx/app/slice/widget/SliceView.java
@@ -192,16 +192,17 @@
         final int heightAvailable = MeasureSpec.getSize(heightMeasureSpec);
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
         int height = heightAvailable;
-        if (heightAvailable >= sliceHeight) {
-            // Available space is larger than the slice
-            if (heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED) {
-                height = sliceHeight;
+        if (heightAvailable >= sliceHeight || heightMode == MeasureSpec.UNSPECIFIED) {
+            // Available space is larger than the slice or we be what we want
+            if (heightMode != MeasureSpec.EXACTLY) {
+                int maxHeight = mIsScrollable ? mMinLargeHeight + actionHeight : sliceHeight;
+                height = Math.min(maxHeight, sliceHeight);
             }
         } else {
             // Not enough space available for slice in current mode
             if (getMode() == MODE_LARGE && heightAvailable >= mMinLargeHeight + actionHeight) {
                 // It's just a slice with scrolling content; cap it to height available.
-                height = heightAvailable;
+                height = Math.min(mMinLargeHeight + actionHeight, heightAvailable);
             } else if (getMode() == MODE_SHORTCUT) {
                 // TODO: consider scaling the shortcut to fit if too small
                 height = mShortcutSize;
diff --git a/slices/view/src/main/res/layout/abc_slice_row_show_more.xml b/slices/view/src/main/res/layout/abc_slice_row_show_more.xml
new file mode 100644
index 0000000..ef65f85
--- /dev/null
+++ b/slices/view/src/main/res/layout/abc_slice_row_show_more.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2018 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.
+  -->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        style="?android:attr/borderlessButtonStyle"
+        android:text="@string/abc_slice_show_more"/>
\ No newline at end of file
diff --git a/slices/view/src/main/res/values/strings.xml b/slices/view/src/main/res/values/strings.xml
index b72c986..f73c6cc 100644
--- a/slices/view/src/main/res/values/strings.xml
+++ b/slices/view/src/main/res/values/strings.xml
@@ -18,4 +18,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Format string for indicating there is more content in a slice view -->
     <string name="abc_slice_more_content">+ <xliff:g id="number" example="5">%1$d</xliff:g></string>
+    <!-- String to indicate there is more content to display in a list [CHAR LIMIT=none] -->
+    <string name="abc_slice_show_more">Show more</string>
 </resources>
\ No newline at end of file