summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2025-01-20 08:28:22 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-01-20 08:28:22 -0800
commitc334f5a238f06e6742992f9fef353c00b039f9e7 (patch)
treec50448c418e4da447e2a1617503c63c73ffef89f
parent2ee220bce44b5af3bc4c663acae5dce92e1d13a7 (diff)
parent89c4d019dab08a2bc098ea95d9a9daa7952c176c (diff)
Merge "[DocsUI M3] Add navigation rail layout for medium size screen" into main
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/color/nav_rail_item_text_color.xml21
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_background.xml23
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_icon_background.xml145
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_icon_mask.xml21
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/fragment_nav_rail_roots.xml25
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_item_root.xml55
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml129
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/dimens.xml2
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/layouts.xml20
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values-w900dp/dimens.xml1
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml5
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml20
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml5
-rw-r--r--src/com/android/documentsui/BaseActivity.java15
-rw-r--r--src/com/android/documentsui/DrawerController.java5
-rw-r--r--src/com/android/documentsui/files/FilesActivity.java9
-rw-r--r--src/com/android/documentsui/picker/PickActivity.java10
-rw-r--r--src/com/android/documentsui/sidebar/AppItem.java13
-rw-r--r--src/com/android/documentsui/sidebar/NavRailAppItem.java48
-rw-r--r--src/com/android/documentsui/sidebar/NavRailProfileItem.java47
-rw-r--r--src/com/android/documentsui/sidebar/NavRailRootAndAppItem.java40
-rw-r--r--src/com/android/documentsui/sidebar/NavRailRootItem.java52
-rw-r--r--src/com/android/documentsui/sidebar/ProfileItem.java7
-rw-r--r--src/com/android/documentsui/sidebar/RootAndAppItem.java17
-rw-r--r--src/com/android/documentsui/sidebar/RootItem.java12
-rw-r--r--src/com/android/documentsui/sidebar/RootsFragment.java128
26 files changed, 851 insertions, 24 deletions
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/color/nav_rail_item_text_color.xml b/res/flag(com.android.documentsui.flags.use_material3)/color/nav_rail_item_text_color.xml
new file mode 100644
index 000000000..ec5aecb33
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/color/nav_rail_item_text_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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_activated="true" android:color="?attr/colorSecondary" />
+ <item android:color="?attr/colorOnSurfaceVariant" />
+</selector>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_background.xml b/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_background.xml
new file mode 100644
index 000000000..7809766cd
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_background.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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">
+ <!-- By default the nav rail item has a grey background when it's focused, but we need the
+ background to be put on the icon inside, so we override the focus background color to be
+ transparent here.
+ -->
+ <item android:state_focused="true" android:drawable="@android:color/transparent" />
+</selector> \ No newline at end of file
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_icon_background.xml b/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_icon_background.xml
new file mode 100644
index 000000000..7864321af
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_icon_background.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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.
+-->
+
+<ripple
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:color="@color/item_root_ripple_color">
+
+ <!-- The mask below only works for the ripple itself, doesn't work for other <item>s, we
+ need to explicitly apply the drawable if the other items also need this mask. -->
+ <item
+ android:id="@android:id/mask"
+ android:drawable="@drawable/nav_rail_item_icon_mask"/>
+
+ <item>
+ <selector>
+ <!-- Selected (activated). -->
+ <!-- Highlight: when dragging files over the item. -->
+ <item
+ android:state_activated="true"
+ app:state_highlighted="true">
+ <layer-list>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ </shape>
+ </item>
+ <item>
+ <shape android:tint="?attr/colorOnSecondaryContainer">
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="@color/overlay_color_percentage_10" />
+ </shape>
+ </item>
+ </layer-list>
+ </item>
+ <item
+ android:state_activated="true"
+ android:state_pressed="true">
+ <layer-list>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ </shape>
+ </item>
+ <item>
+ <shape android:tint="?attr/colorOnSecondaryContainer">
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="@color/overlay_color_percentage_10" />
+ </shape>
+ </item>
+ </layer-list>
+ </item>
+ <item
+ android:state_activated="true"
+ android:state_focused="true">
+ <layer-list>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ </shape>
+ </item>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <stroke
+ android:width="@dimen/focus_ring_width"
+ android:color="?attr/colorSecondary" />
+ </shape>
+ </item>
+ </layer-list>
+ </item>
+ <item
+ android:state_activated="true"
+ android:state_hovered="true">
+ <layer-list>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ </shape>
+ </item>
+ <item>
+ <shape android:tint="?attr/colorOnSecondaryContainer">
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="@color/overlay_color_percentage_10" />
+ </shape>
+ </item>
+ </layer-list>
+ </item>
+ <item android:state_activated="true">
+ <shape>
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ </shape>
+ </item>
+
+ <!-- Unselected. -->
+ <item app:state_highlighted="true">
+ <shape android:tint="?attr/colorOnSurface">
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="@color/overlay_color_percentage_10" />
+ </shape>
+ </item>
+ <item android:state_pressed="true">
+ <shape android:tint="?attr/colorOnSurface">
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="@color/overlay_color_percentage_10" />
+ </shape>
+ </item>
+ <item android:state_focused="true">
+ <shape>
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <stroke
+ android:width="@dimen/focus_ring_width"
+ android:color="?attr/colorSecondary" />
+ </shape>
+ </item>
+ <item android:state_hovered="true">
+ <shape android:tint="?attr/colorOnSurface">
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius" />
+ <solid android:color="@color/overlay_color_percentage_10" />
+ </shape>
+ </item>
+
+ <!-- Default: use the container background. -->
+ <item android:drawable="@android:color/transparent" />
+ </selector>
+ </item>
+</ripple> \ No newline at end of file
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_icon_mask.xml b/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_icon_mask.xml
new file mode 100644
index 000000000..fd2a14b8d
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/drawable/nav_rail_item_icon_mask.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners android:radius="@dimen/nav_rail_item_icon_bg_radius"/>
+ <!-- The color here doesn't matter, it's just being used as a mask. -->
+ <solid android:color="@android:color/white" />
+</shape> \ No newline at end of file
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/fragment_nav_rail_roots.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/fragment_nav_rail_roots.xml
new file mode 100644
index 000000000..7848dea0b
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/fragment_nav_rail_roots.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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.
+-->
+
+<com.android.documentsui.sidebar.RootsList xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/roots_list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:keyboardNavigationCluster="true"
+ android:divider="@null"
+ android:focusable="false"
+ android:descendantFocusability="afterDescendants"
+ style="@style/NavRailStyle"/>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_item_root.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_item_root.xml
new file mode 100644
index 000000000..461027c73
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_item_root.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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.
+-->
+
+<com.android.documentsui.sidebar.RootItemView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/nav_rail_item_height"
+ android:gravity="center_horizontal"
+ android:orientation="vertical"
+ android:baselineAligned="false"
+ android:clickable="true"
+ android:focusable="true"
+ style="@style/NavRailItemStyle">
+
+ <LinearLayout
+ android:layout_width="@dimen/nav_rail_item_icon_bg_width"
+ android:layout_height="@dimen/nav_rail_item_icon_bg_height"
+ android:gravity="center"
+ android:duplicateParentState="true"
+ android:background="@drawable/nav_rail_item_icon_background">
+
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="@dimen/root_icon_size"
+ android:layout_height="@dimen/root_icon_size"
+ android:scaleType="centerInside"
+ android:contentDescription="@null" />
+
+ </LinearLayout>
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textAlignment="center"
+ android:duplicateParentState="true"
+ style="@style/NavRailItemTextStyle" />
+
+</com.android.documentsui.sidebar.RootItemView>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml
new file mode 100644
index 000000000..5d753f336
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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.
+-->
+
+<!-- CoordinatorLayout is necessary for various components (e.g. Snackbars, and
+ floating action buttons) to operate correctly. -->
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/coordinator_layout">
+
+ <androidx.drawerlayout.widget.DrawerLayout
+ android:id="@+id/drawer_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <!-- Main section -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:baselineAligned="false"
+ android:paddingTop="@dimen/layout_padding_top"
+ android:paddingBottom="@dimen/layout_padding_bottom"
+ android:paddingEnd="@dimen/layout_padding_end"
+ android:background="?attr/colorSurfaceContainer">
+
+ <!-- Navigation rail: left hand side. -->
+ <FrameLayout
+ android:id="@+id/nav_rail_container_roots"
+ android:layout_width="144dp"
+ android:layout_height="match_parent"
+ />
+
+ <!-- Main container for the right hand side. -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@drawable/main_container_background"
+ android:paddingTop="@dimen/main_container_padding_top">
+
+ <com.google.android.material.appbar.MaterialToolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:layout_marginTop="@dimen/action_bar_margin"
+ android:touchscreenBlocksFocus="false">
+
+ <TextView
+ android:id="@+id/searchbar_title"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:gravity="center_vertical"
+ android:text="@string/search_bar_hint"
+ android:textAppearance="@style/SearchBarTitle" />
+
+ </com.google.android.material.appbar.MaterialToolbar>
+
+ <include layout="@layout/directory_header" />
+
+ <!-- Main list area (file list/grid or search results). -->
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <FrameLayout
+ android:id="@+id/container_directory"
+ android:clipToPadding="false"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <FrameLayout
+ android:id="@+id/container_search_fragment"
+ android:clipToPadding="false"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </FrameLayout>
+
+ <!-- Footer of right hand side: Breadcrumbs and Picker footer. -->
+ <com.android.documentsui.HorizontalBreadcrumb
+ android:id="@+id/horizontal_breadcrumb"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <androidx.coordinatorlayout.widget.CoordinatorLayout
+ android:id="@+id/container_save"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?android:attr/colorBackgroundFloating"
+ android:elevation="8dp" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <!-- Drawer section -->
+ <LinearLayout
+ android:id="@+id/drawer_roots"
+ android:layout_width="256dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="start"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:id="@+id/container_roots"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ </androidx.drawerlayout.widget.DrawerLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/dimens.xml b/res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/dimens.xml
index 4707991f6..2781026e9 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/dimens.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/dimens.xml
@@ -23,7 +23,7 @@
we zero here, to avoid pushing the title further. -->
<dimen name="search_bar_text_margin_start">0dp</dimen>
- <dimen name="toolbar_padding_start">@dimen/main_container_padding_start</dimen>
+ <dimen name="toolbar_padding_start">@dimen/space_small_3</dimen>
<dimen name="list_container_padding">@dimen/space_extra_small_6</dimen>
</resources>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/layouts.xml b/res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/layouts.xml
new file mode 100644
index 000000000..4b0634d54
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values-w600dp/layouts.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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="documents_activity" type="layout">@layout/nav_rail_layout</item>
+ <item name="files_activity" type="layout">@layout/nav_rail_layout</item>
+</resources>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values-w900dp/dimens.xml b/res/flag(com.android.documentsui.flags.use_material3)/values-w900dp/dimens.xml
index 51b1f7bdc..d37f3af68 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values-w900dp/dimens.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values-w900dp/dimens.xml
@@ -32,6 +32,7 @@
<dimen name="main_container_padding_top">@dimen/space_extra_small_6</dimen>
+ <dimen name="toolbar_padding_start">@dimen/main_container_padding_start</dimen>
<dimen name="toolbar_padding_end">@dimen/space_small_3</dimen>
<dimen name="drawer_padding_top">@dimen/space_small_1</dimen>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml b/res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml
index 47d0049a4..2c2d54f34 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml
@@ -81,6 +81,11 @@
<dimen name="drawer_item_text_margin_start">12dp</dimen>
<dimen name="drawer_item_action_icon_margin_start">4dp</dimen>
+ <dimen name="nav_rail_item_height">64dp</dimen>
+ <dimen name="nav_rail_item_icon_bg_radius">16dp</dimen>
+ <dimen name="nav_rail_item_icon_bg_width">56dp</dimen>
+ <dimen name="nav_rail_item_icon_bg_height">32dp</dimen>
+
<dimen name="drag_shadow_width">176dp</dimen>
<dimen name="drag_shadow_height">64dp</dimen>
<dimen name="drag_shadow_radius">4dp</dimen>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml b/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml
index 4c61e5152..5fde94ab8 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml
@@ -166,4 +166,24 @@
<item name="android:textAlignment">viewStart</item>
<item name="android:textAppearance">@style/FileItemLabelText</item>
</style>
+
+ <style name="NavRailStyle" parent="">
+ <item name="android:background">?attr/colorSurfaceContainer</item>
+ <item name="android:paddingHorizontal">@dimen/space_small_3</item>
+ <item name="android:paddingTop">@dimen/space_extra_small_6</item>
+ <item name="android:paddingBottom">@dimen/space_small_1</item>
+ <item name="android:scrollbarStyle">outsideOverlay</item>
+ <item name="android:clipToPadding">false</item>
+ </style>
+
+ <style name="NavRailItemStyle" parent="">
+ <item name="android:background">@drawable/nav_rail_item_background</item>
+ <item name="android:paddingVertical">6dp</item>
+ </style>
+
+ <style name="NavRailItemTextStyle" parent="">
+ <item name="android:layout_marginTop">4dp</item>
+ <item name="android:textColor">@color/nav_rail_item_text_color</item>
+ <item name="android:textAppearance">@style/NavRailItemTextAppearance</item>
+ </style>
</resources>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml b/res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml
index fb6d0e472..717295315 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml
@@ -141,4 +141,9 @@
<style name="Subhead" parent="@style/TextAppearance.Material3.BodyLarge">
<item name="fontFamily">@string/config_fontFamily</item>
</style>
+
+ <style name="NavRailItemTextAppearance" parent="@style/TextAppearance.Material3.LabelMedium">
+ <item name="fontFamily">@string/config_fontFamily</item>
+ </style>
+
</resources>
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index fe81fbf16..4c25b3608 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -358,6 +358,14 @@ public abstract class BaseActivity
if (roots != null) {
roots.onSelectedUserChanged();
}
+ if (useMaterial3()) {
+ final RootsFragment navRailRoots =
+ RootsFragment.getNavRail(getSupportFragmentManager());
+ if (navRailRoots != null) {
+ navRailRoots.onSelectedUserChanged();
+ }
+ }
+
if (mState.stack.size() <= 1) {
// We do not load cross-profile root if the stack contains two documents. The
@@ -690,6 +698,13 @@ public abstract class BaseActivity
if (roots != null) {
roots.onCurrentRootChanged();
}
+ if (useMaterial3()) {
+ final RootsFragment navRailRoots =
+ RootsFragment.getNavRail(getSupportFragmentManager());
+ if (navRailRoots != null) {
+ navRailRoots.onCurrentRootChanged();
+ }
+ }
String appName = getString(R.string.files_label);
String currentTitle = getTitle() != null ? getTitle().toString() : "";
diff --git a/src/com/android/documentsui/DrawerController.java b/src/com/android/documentsui/DrawerController.java
index a988635fd..88c41b3f2 100644
--- a/src/com/android/documentsui/DrawerController.java
+++ b/src/com/android/documentsui/DrawerController.java
@@ -127,7 +127,10 @@ public abstract class DrawerController implements DrawerListener {
if (activityConfig.dragAndDropEnabled()) {
View edge = layout.findViewById(R.id.drawer_edge);
- edge.setOnDragListener(new ItemDragListener<>(this, SPRING_TIMEOUT));
+ // nav_rail_layout also uses DrawerLayout, but it doesn't have drawer edge.
+ if (edge != null) {
+ edge.setOnDragListener(new ItemDragListener<>(this, SPRING_TIMEOUT));
+ }
}
}
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index 1ebe2374f..1da0d8f2b 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -17,6 +17,7 @@
package com.android.documentsui.files;
import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN;
+import static com.android.documentsui.flags.Flags.useMaterial3;
import android.app.ActivityManager.TaskDescription;
import android.content.Intent;
@@ -181,6 +182,14 @@ public class FilesActivity extends BaseActivity implements AbstractActionHandler
RootsFragment.show(getSupportFragmentManager(), /* includeApps= */ false,
/* intent= */ null);
+ if (useMaterial3()) {
+ View navRailRoots = findViewById(R.id.nav_rail_container_roots);
+ if (navRailRoots != null) {
+ // Medium layout, populate navigation rail layout.
+ RootsFragment.showNavRail(getSupportFragmentManager(), /* includeApps= */ false,
+ /* intent= */ null);
+ }
+ }
final Intent intent = getIntent();
diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java
index e9b91b1a0..481b67e77 100644
--- a/src/com/android/documentsui/picker/PickActivity.java
+++ b/src/com/android/documentsui/picker/PickActivity.java
@@ -21,6 +21,7 @@ import static com.android.documentsui.base.State.ACTION_GET_CONTENT;
import static com.android.documentsui.base.State.ACTION_OPEN;
import static com.android.documentsui.base.State.ACTION_OPEN_TREE;
import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;
+import static com.android.documentsui.flags.Flags.useMaterial3;
import android.content.Intent;
import android.content.res.Resources;
@@ -249,6 +250,15 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons {
RootsFragment.show(getSupportFragmentManager(),
/* includeApps= */ mState.action == ACTION_GET_CONTENT,
/* intent= */ moreApps);
+ if (useMaterial3()) {
+ View navRailRoots = findViewById(R.id.nav_rail_container_roots);
+ if (navRailRoots != null) {
+ // Medium layout, populate navigation rail layout.
+ RootsFragment.showNavRail(getSupportFragmentManager(),
+ /* includeApps= */ mState.action == ACTION_GET_CONTENT,
+ /* intent= */ moreApps);
+ }
+ }
}
}
diff --git a/src/com/android/documentsui/sidebar/AppItem.java b/src/com/android/documentsui/sidebar/AppItem.java
index b8abf8be9..c719241d2 100644
--- a/src/com/android/documentsui/sidebar/AppItem.java
+++ b/src/com/android/documentsui/sidebar/AppItem.java
@@ -26,6 +26,8 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.LayoutRes;
+
import com.android.documentsui.ActionHandler;
import com.android.documentsui.IconUtils;
import com.android.documentsui.R;
@@ -43,7 +45,16 @@ public class AppItem extends Item {
private final ActionHandler mActionHandler;
public AppItem(ResolveInfo info, String title, UserId userId, ActionHandler actionHandler) {
- super(R.layout.item_root, title, getStringId(info), userId);
+ this(R.layout.item_root, info, title, userId, actionHandler);
+ }
+
+ public AppItem(
+ @LayoutRes int layoutId,
+ ResolveInfo info,
+ String title,
+ UserId userId,
+ ActionHandler actionHandler) {
+ super(layoutId, title, getStringId(info), userId);
this.info = info;
mActionHandler = actionHandler;
}
diff --git a/src/com/android/documentsui/sidebar/NavRailAppItem.java b/src/com/android/documentsui/sidebar/NavRailAppItem.java
new file mode 100644
index 000000000..befddf0aa
--- /dev/null
+++ b/src/com/android/documentsui/sidebar/NavRailAppItem.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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.android.documentsui.sidebar;
+
+import android.content.pm.ResolveInfo;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.R;
+import com.android.documentsui.base.UserId;
+
+/**
+ * Similar to {@link AppItem} but only used in the navigation rail.
+ */
+public class NavRailAppItem extends AppItem {
+
+ public NavRailAppItem(
+ ResolveInfo info, String title, UserId userId, ActionHandler actionHandler) {
+ super(R.layout.nav_rail_item_root, info, title, userId, actionHandler);
+ }
+
+ @Override
+ public void bindView(View convertView) {
+ final ImageView icon = convertView.findViewById(android.R.id.icon);
+ final TextView titleView = convertView.findViewById(android.R.id.title);
+
+ titleView.setText(title);
+ titleView.setContentDescription(userId.getUserBadgedLabel(convertView.getContext(), title));
+
+ bindIcon(icon);
+ }
+}
diff --git a/src/com/android/documentsui/sidebar/NavRailProfileItem.java b/src/com/android/documentsui/sidebar/NavRailProfileItem.java
new file mode 100644
index 000000000..fe69c286f
--- /dev/null
+++ b/src/com/android/documentsui/sidebar/NavRailProfileItem.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 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.android.documentsui.sidebar;
+
+import android.content.pm.ResolveInfo;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.R;
+
+
+/**
+ * Similar to {@link ProfileItem} but only used in the navigation rail.
+ */
+public class NavRailProfileItem extends ProfileItem {
+
+ public NavRailProfileItem(ResolveInfo info, String title, ActionHandler actionHandler) {
+ super(R.layout.nav_rail_item_root, info, title, actionHandler);
+ }
+
+ @Override
+ public void bindView(View convertView) {
+ final ImageView icon = convertView.findViewById(android.R.id.icon);
+ final TextView titleView = convertView.findViewById(android.R.id.title);
+
+ titleView.setText(title);
+ titleView.setContentDescription(userId.getUserBadgedLabel(convertView.getContext(), title));
+
+ bindIcon(icon);
+ }
+}
diff --git a/src/com/android/documentsui/sidebar/NavRailRootAndAppItem.java b/src/com/android/documentsui/sidebar/NavRailRootAndAppItem.java
new file mode 100644
index 000000000..1bcc42f5c
--- /dev/null
+++ b/src/com/android/documentsui/sidebar/NavRailRootAndAppItem.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 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.android.documentsui.sidebar;
+
+import android.content.pm.ResolveInfo;
+import android.view.View;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.R;
+import com.android.documentsui.base.RootInfo;
+
+/**
+ * Similar to {@link RootAndAppItem} but only used in the navigation rail.
+ */
+public class NavRailRootAndAppItem extends RootAndAppItem {
+
+ public NavRailRootAndAppItem(
+ RootInfo root, ResolveInfo info, ActionHandler actionHandler, boolean maybeShowBadge) {
+ super(R.layout.nav_rail_item_root, root, info, actionHandler, maybeShowBadge);
+ }
+
+ @Override
+ public void bindView(View convertView) {
+ bindIconAndTitle(convertView);
+ }
+}
diff --git a/src/com/android/documentsui/sidebar/NavRailRootItem.java b/src/com/android/documentsui/sidebar/NavRailRootItem.java
new file mode 100644
index 000000000..3d4042f22
--- /dev/null
+++ b/src/com/android/documentsui/sidebar/NavRailRootItem.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 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.android.documentsui.sidebar;
+
+
+import android.view.View;
+
+import com.android.documentsui.ActionHandler;
+import com.android.documentsui.R;
+import com.android.documentsui.base.RootInfo;
+
+/**
+ * Similar to {@link RootItem} but only used in the navigation rail.
+ */
+public class NavRailRootItem extends RootItem {
+
+ public NavRailRootItem(RootInfo root, ActionHandler actionHandler, boolean maybeShowBadge) {
+ super(
+ R.layout.nav_rail_item_root,
+ root,
+ actionHandler,
+ "" /* packageName */,
+ maybeShowBadge);
+ }
+
+ public NavRailRootItem(
+ RootInfo root,
+ ActionHandler actionHandler,
+ String packageName,
+ boolean maybeShowBadge) {
+ super(R.layout.nav_rail_item_root, root, actionHandler, packageName, maybeShowBadge);
+ }
+
+ @Override
+ public void bindView(View convertView) {
+ bindIconAndTitle(convertView);
+ }
+}
diff --git a/src/com/android/documentsui/sidebar/ProfileItem.java b/src/com/android/documentsui/sidebar/ProfileItem.java
index 15068ad4b..779f54445 100644
--- a/src/com/android/documentsui/sidebar/ProfileItem.java
+++ b/src/com/android/documentsui/sidebar/ProfileItem.java
@@ -20,6 +20,8 @@ import android.content.pm.ResolveInfo;
import android.view.View;
import android.widget.ImageView;
+import androidx.annotation.LayoutRes;
+
import com.android.documentsui.ActionHandler;
import com.android.documentsui.base.UserId;
@@ -32,6 +34,11 @@ class ProfileItem extends AppItem {
super(info, title, UserId.CURRENT_USER, actionHandler);
}
+ ProfileItem(
+ @LayoutRes int layoutId, ResolveInfo info, String title, ActionHandler actionHandler) {
+ super(layoutId, info, title, UserId.CURRENT_USER, actionHandler);
+ }
+
@Override
protected void bindIcon(ImageView icon) {
icon.setImageResource(com.android.documentsui.R.drawable.ic_user_profile);
diff --git a/src/com/android/documentsui/sidebar/RootAndAppItem.java b/src/com/android/documentsui/sidebar/RootAndAppItem.java
index b893878f3..8861f6058 100644
--- a/src/com/android/documentsui/sidebar/RootAndAppItem.java
+++ b/src/com/android/documentsui/sidebar/RootAndAppItem.java
@@ -18,11 +18,11 @@ package com.android.documentsui.sidebar;
import android.content.Context;
import android.content.pm.ResolveInfo;
-import android.os.UserManager;
import android.provider.DocumentsProvider;
-import android.text.TextUtils;
import android.view.View;
+import androidx.annotation.LayoutRes;
+
import com.android.documentsui.ActionHandler;
import com.android.documentsui.R;
import com.android.documentsui.base.RootInfo;
@@ -36,9 +36,18 @@ class RootAndAppItem extends RootItem {
public final ResolveInfo resolveInfo;
- public RootAndAppItem(RootInfo root, ResolveInfo info, ActionHandler actionHandler,
+ RootAndAppItem(
+ RootInfo root, ResolveInfo info, ActionHandler actionHandler, boolean maybeShowBadge) {
+ this(R.layout.item_root, root, info, actionHandler, maybeShowBadge);
+ }
+
+ RootAndAppItem(
+ @LayoutRes int layoutId,
+ RootInfo root,
+ ResolveInfo info,
+ ActionHandler actionHandler,
boolean maybeShowBadge) {
- super(root, actionHandler, info.activityInfo.packageName, maybeShowBadge);
+ super(layoutId, root, actionHandler, info.activityInfo.packageName, maybeShowBadge);
this.resolveInfo = info;
}
diff --git a/src/com/android/documentsui/sidebar/RootItem.java b/src/com/android/documentsui/sidebar/RootItem.java
index 4b40d91b3..326f086e1 100644
--- a/src/com/android/documentsui/sidebar/RootItem.java
+++ b/src/com/android/documentsui/sidebar/RootItem.java
@@ -30,6 +30,7 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
+import androidx.annotation.LayoutRes;
import androidx.annotation.Nullable;
import com.android.documentsui.ActionHandler;
@@ -64,7 +65,16 @@ public class RootItem extends Item {
public RootItem(RootInfo root, ActionHandler actionHandler, String packageName,
boolean maybeShowBadge) {
- super(R.layout.item_root, root.title, getStringId(root), root.userId);
+ this(R.layout.item_root, root, actionHandler, packageName, maybeShowBadge);
+ }
+
+ public RootItem(
+ @LayoutRes int layoutId,
+ RootInfo root,
+ ActionHandler actionHandler,
+ String packageName,
+ boolean maybeShowBadge) {
+ super(layoutId, root.title, getStringId(root), root.userId);
this.root = root;
mActionHandler = actionHandler;
mPackageName = packageName;
diff --git a/src/com/android/documentsui/sidebar/RootsFragment.java b/src/com/android/documentsui/sidebar/RootsFragment.java
index 76df696ab..2ec4c1728 100644
--- a/src/com/android/documentsui/sidebar/RootsFragment.java
+++ b/src/com/android/documentsui/sidebar/RootsFragment.java
@@ -19,6 +19,7 @@ package com.android.documentsui.sidebar;
import static com.android.documentsui.base.Shared.compareToIgnoreCaseNullable;
import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.SharedMinimal.VERBOSE;
+import static com.android.documentsui.flags.Flags.useMaterial3;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
@@ -49,6 +50,7 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
+import androidx.annotation.IdRes;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
@@ -96,12 +98,23 @@ import java.util.stream.Collectors;
/**
* Display list of known storage backend roots.
+ * This fragment will be used in:
+ * * fixed_layout: as navigation tree (sidebar)
+ * * drawer_layout: as navigation drawer
+ * * nav_rail_layout: as navigation drawer and navigation rail.
*/
public class RootsFragment extends Fragment {
private static final String TAG = "RootsFragment";
private static final String EXTRA_INCLUDE_APPS = "includeApps";
private static final String EXTRA_INCLUDE_APPS_INTENT = "includeAppsIntent";
+ /**
+ * A key used to store the container id in the RootFragment.
+ * RootFragment is used in both navigation drawer and navigation rail, there are 2 instances
+ * of the fragment rendered on the page, we need to know which one is which to render different
+ * nav items inside.
+ */
+ private static final String EXTRA_CONTAINER_ID = "containerId";
private static final int CONTEXT_MENU_ITEM_TIMEOUT = 500;
private final OnItemClickListener mItemListener = new OnItemClickListener() {
@@ -135,41 +148,88 @@ public class RootsFragment extends Fragment {
private List<Item> mApplicationItemList;
+ // Weather the fragment is using nav_rail_container_roots as its container (in nav_rail_layout).
+ // This will always be false if useMaterial3() flag is off.
+ private boolean mUseRailAsContainer = false;
+
+ /**
+ * Show the RootsFragment inside the navigation drawer container.
+ */
+ public static RootsFragment show(FragmentManager fm, boolean includeApps, Intent intent) {
+ return showWithLayout(R.id.container_roots, fm, includeApps, intent);
+ }
+
+ /**
+ * Show the RootsFragment inside the navigation rail container.
+ */
+ public static RootsFragment showNavRail(FragmentManager fm, boolean includeApps,
+ Intent intent) {
+ return showWithLayout(R.id.nav_rail_container_roots, fm, includeApps, intent);
+ }
+
/**
* Shows the {@link RootsFragment}.
*
+ * @param containerId the container id where the {@link RootsFragment} will be rendered into
* @param fm the FragmentManager for interacting with fragments associated with this
* fragment's activity
* @param includeApps if {@code true}, query the intent from the system and include apps in
* the {@RootsFragment}.
* @param intent the intent to query for package manager
*/
- public static RootsFragment show(FragmentManager fm, boolean includeApps, Intent intent) {
+ private static RootsFragment showWithLayout(
+ @IdRes int containerId, FragmentManager fm, boolean includeApps, Intent intent) {
final Bundle args = new Bundle();
args.putBoolean(EXTRA_INCLUDE_APPS, includeApps);
args.putParcelable(EXTRA_INCLUDE_APPS_INTENT, intent);
+ if (useMaterial3()) {
+ args.putInt(EXTRA_CONTAINER_ID, containerId);
+ }
final RootsFragment fragment = new RootsFragment();
fragment.setArguments(args);
final FragmentTransaction ft = fm.beginTransaction();
- ft.replace(R.id.container_roots, fragment);
+ ft.replace(containerId, fragment);
ft.commitAllowingStateLoss();
return fragment;
}
+ /**
+ * Get the RootsFragment instance for the navigation drawer.
+ */
public static RootsFragment get(FragmentManager fm) {
return (RootsFragment) fm.findFragmentById(R.id.container_roots);
}
+ /**
+ * Get the RootsFragment instance for the navigation drawer.
+ */
+ public static RootsFragment getNavRail(FragmentManager fm) {
+ return (RootsFragment) fm.findFragmentById(R.id.nav_rail_container_roots);
+ }
+
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ if (useMaterial3()) {
+ mUseRailAsContainer =
+ getArguments() != null
+ && getArguments().getInt(EXTRA_CONTAINER_ID)
+ == R.id.nav_rail_container_roots;
+ }
+
mInjector = getBaseActivity().getInjector();
- final View view = inflater.inflate(R.layout.fragment_roots, container, false);
+ final View view =
+ inflater.inflate(
+ mUseRailAsContainer
+ ? R.layout.fragment_nav_rail_roots
+ : R.layout.fragment_roots,
+ container,
+ false);
mList = (ListView) view.findViewById(R.id.roots_list);
mList.setOnItemClickListener(mItemListener);
// ListView does not have right-click specific listeners, so we will have a
@@ -312,10 +372,17 @@ public class RootsFragment extends Fragment {
if (crossProfileResolveInfo != null && !Features.CROSS_PROFILE_TABS) {
// Add profile item if we don't support cross-profile tab.
sortedItems.add(new SpacerItem());
- sortedItems.add(new ProfileItem(crossProfileResolveInfo,
- crossProfileResolveInfo.loadLabel(
- getContext().getPackageManager()).toString(),
- mActionHandler));
+ if (mUseRailAsContainer) {
+ sortedItems.add(new NavRailProfileItem(crossProfileResolveInfo,
+ crossProfileResolveInfo.loadLabel(
+ getContext().getPackageManager()).toString(),
+ mActionHandler));
+ } else {
+ sortedItems.add(new ProfileItem(crossProfileResolveInfo,
+ crossProfileResolveInfo.loadLabel(
+ getContext().getPackageManager()).toString(),
+ mActionHandler));
+ }
}
// Disable drawer if only one root
@@ -414,15 +481,30 @@ public class RootsFragment extends Fragment {
if (root.isExternalStorageHome()) {
continue;
} else if (root.isLibrary() || root.isDownloads()) {
- item = new RootItem(root, mActionHandler, maybeShowBadge);
+ item =
+ mUseRailAsContainer
+ ? new NavRailRootItem(root, mActionHandler, maybeShowBadge)
+ : new RootItem(root, mActionHandler, maybeShowBadge);
librariesBuilder.add(item);
} else if (root.isStorage()) {
- item = new RootItem(root, mActionHandler, maybeShowBadge);
+ item =
+ mUseRailAsContainer
+ ? new NavRailRootItem(root, mActionHandler, maybeShowBadge)
+ : new RootItem(root, mActionHandler, maybeShowBadge);
storageProvidersBuilder.add(item);
} else {
- item = new RootItem(root, mActionHandler,
- providersAccess.getPackageName(root.userId, root.authority),
- maybeShowBadge);
+ item =
+ mUseRailAsContainer
+ ? new NavRailRootItem(
+ root,
+ mActionHandler,
+ providersAccess.getPackageName(root.userId, root.authority),
+ maybeShowBadge)
+ : new RootItem(
+ root,
+ mActionHandler,
+ providersAccess.getPackageName(root.userId, root.authority),
+ maybeShowBadge);
otherProviders.add(item);
}
}
@@ -566,8 +648,18 @@ public class RootsFragment extends Fragment {
appsMapping.put(userPackage, info);
if (!CrossProfileUtils.isCrossProfileIntentForwarderActivity(info)) {
- final Item item = new AppItem(info, info.loadLabel(pm).toString(), userId,
- mActionHandler);
+ final Item item =
+ mUseRailAsContainer
+ ? new NavRailAppItem(
+ info,
+ info.loadLabel(pm).toString(),
+ userId,
+ mActionHandler)
+ : new AppItem(
+ info,
+ info.loadLabel(pm).toString(),
+ userId,
+ mActionHandler);
appItems.put(userPackage, item);
if (VERBOSE) Log.v(TAG, "Adding handler app: " + item);
}
@@ -583,8 +675,12 @@ public class RootsFragment extends Fragment {
final Item item;
if (resolveInfo != null) {
- item = new RootAndAppItem(rootItem.root, resolveInfo, mActionHandler,
- maybeShowBadge);
+ item =
+ mUseRailAsContainer
+ ? new NavRailRootAndAppItem(
+ rootItem.root, resolveInfo, mActionHandler, maybeShowBadge)
+ : new RootAndAppItem(
+ rootItem.root, resolveInfo, mActionHandler, maybeShowBadge);
appItems.remove(userPackage);
} else {
item = rootItem;