summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ben Reich <benreich@google.com> 2025-02-03 21:53:49 -0800
committer Ben Reich <benreich@google.com> 2025-02-04 16:54:54 +1100
commit616e5b91d2e7a10714b22cff37150e8c25a096b3 (patch)
tree6da602e641a173af7d6bf390fc26ad8ac46b29af
parentb4a53462e1feb20a73319c1f9b14e4ae02778000 (diff)
Revert^2 "Update the file list sort icon"
This reverts commit befc03bc2b03ca7df4a22eb051ff9bf3b5e78df8. Reason for revert: ag/31583362 should fix the fact that test filtering isn't working in the functional tests (specifically SortDocumentUiTest) Change-Id: I91e81e4936b6e10bd274bf24f0561882727e4de8
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_arrow_upward.xml14
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_arrow.xml2
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_icon.xml98
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml15
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/shared_cell_content.xml3
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml2
-rw-r--r--src/com/android/documentsui/sorting/HeaderCell.java16
-rw-r--r--src/com/android/documentsui/sorting/TableHeaderController.java22
-rw-r--r--tests/common/com/android/documentsui/bots/SortBot.java10
-rw-r--r--tests/functional/com/android/documentsui/SortDocumentUiTest.java32
10 files changed, 199 insertions, 15 deletions
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_arrow_upward.xml b/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_arrow_upward.xml
index 96fa93ade..dbee1c363 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_arrow_upward.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_arrow_upward.xml
@@ -15,14 +15,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
+ android:width="28dp"
+ android:height="32dp"
+ android:viewportHeight="32"
+ android:viewportWidth="28">
<path
- android:pathData="M0 0h24v24H0V0z" />
- <path
- android:fillColor="?android:textColorSecondary"
- android:pathData="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z" />
+ android:fillColor="?attr/colorOnSecondaryContainer"
+ android:pathData="M13.25 19.125V10.75c0-.208.07-.382.208-.52A.74.74 0 0 1 14 10c.208 0 .382.076.52.23.154.138.23.312.23.52v8.375l3.667-3.667a.718.718 0 0 1 .52-.229c.209 0 .39.077.542.23.153.152.23.333.23.541a.718.718 0 0 1-.23.52l-4.958 4.96a.786.786 0 0 1-.25.166.85.85 0 0 1-.271.041c-.097 0-.194-.013-.292-.041a.878.878 0 0 1-.229-.167l-4.958-4.958A.718.718 0 0 1 8.29 16a.822.822 0 0 1 .25-.542.718.718 0 0 1 .521-.229.74.74 0 0 1 .542.23l3.646 3.666Z" />
</vector> \ No newline at end of file
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_arrow.xml b/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_arrow.xml
index e54ee3158..ec23152ab 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_arrow.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_arrow.xml
@@ -16,7 +16,7 @@
-->
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/ic_arrow_upward"
+ android:drawable="@drawable/ic_sort_icon"
android:fromDegrees="0"
android:toDegrees="180"
android:pivotX="50%"
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_icon.xml b/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_icon.xml
new file mode 100644
index 000000000..52a265729
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/drawable/ic_sort_icon.xml
@@ -0,0 +1,98 @@
+<?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_focused="true"
+ android:state_hovered="true">
+ <layer-list>
+ <item>
+ <shape
+ android:background="?attr/colorSurfaceBright"
+ android:shape="rectangle"
+ android:tint="?attr/colorSecondaryContainer"
+ android:tintMode="multiply">
+ <corners android:radius="14dp" />
+ <size
+ android:width="28dp"
+ android:height="32dp" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ <stroke
+ android:width="@dimen/focus_ring_width"
+ android:color="?attr/colorSecondary" />
+ </shape>
+ </item>
+ <item android:drawable="@drawable/ic_arrow_upward" />
+ </layer-list>
+ </item>
+ <item
+ android:state_focused="false"
+ android:state_hovered="true">
+ <layer-list>
+ <item>
+ <shape
+ android:background="?attr/colorSurfaceBright"
+ android:shape="rectangle"
+ android:tint="?attr/colorSecondaryContainer"
+ android:tintMode="multiply">
+ <corners android:radius="14dp" />
+ <size
+ android:width="28dp"
+ android:height="32dp" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ </shape>
+ </item>
+ <item android:drawable="@drawable/ic_arrow_upward" />
+ </layer-list>
+ </item>
+ <item
+ android:state_focused="true"
+ android:state_hovered="false">
+ <layer-list>
+ <item>
+ <shape
+ android:background="?attr/colorSurfaceBright"
+ android:shape="rectangle">
+ <corners android:radius="14dp" />
+ <size
+ android:width="28dp"
+ android:height="32dp" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ <stroke
+ android:width="@dimen/focus_ring_width"
+ android:color="?attr/colorSecondary" />
+ </shape>
+ </item>
+ <item android:drawable="@drawable/ic_arrow_upward" />
+ </layer-list>
+ </item>
+ <item>
+ <layer-list>
+ <item>
+ <shape
+ android:background="?attr/colorSurfaceBright"
+ android:shape="rectangle">
+ <corners android:radius="14dp" />
+ <size
+ android:width="28dp"
+ android:height="32dp" />
+ <solid android:color="?attr/colorSecondaryContainer" />
+ </shape>
+ </item>
+ <item android:drawable="@drawable/ic_arrow_upward" />
+ </layer-list>
+ </item>
+</selector> \ No newline at end of file
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml
index c21f39c72..57fb74751 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml
@@ -54,7 +54,8 @@
android:layout_height="match_parent"
android:layout_weight="0.4"
android:layout_marginEnd="12dp"
- android:focusable="true"
+ android:clickable="true"
+ android:focusable="false"
android:gravity="center_vertical"
android:orientation="horizontal"
android:animateLayoutChanges="true">
@@ -68,7 +69,8 @@
android:layout_height="match_parent"
android:layout_weight="0"
android:layout_marginEnd="0dp"
- android:focusable="true"
+ android:clickable="true"
+ android:focusable="false"
android:gravity="center_vertical"
android:orientation="horizontal"
android:animateLayoutChanges="true">
@@ -82,7 +84,8 @@
android:layout_height="match_parent"
android:layout_weight="0.2"
android:layout_marginEnd="12dp"
- android:focusable="true"
+ android:clickable="true"
+ android:focusable="false"
android:gravity="center_vertical"
android:orientation="horizontal"
android:animateLayoutChanges="true">
@@ -96,7 +99,8 @@
android:layout_height="match_parent"
android:layout_weight="0.2"
android:layout_marginEnd="12dp"
- android:focusable="true"
+ android:clickable="true"
+ android:focusable="false"
android:gravity="center_vertical"
android:orientation="horizontal"
android:animateLayoutChanges="true">
@@ -110,7 +114,8 @@
android:layout_height="match_parent"
android:layout_weight="0.2"
android:layout_marginEnd="12dp"
- android:focusable="true"
+ android:clickable="true"
+ android:focusable="false"
android:gravity="center_vertical"
android:orientation="horizontal"
android:animateLayoutChanges="true">
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/shared_cell_content.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/shared_cell_content.xml
index 4702eada3..2cbd341ed 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/shared_cell_content.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/shared_cell_content.xml
@@ -32,6 +32,9 @@
android:layout_width="@dimen/doc_header_sort_icon_size"
android:layout_marginStart="3dp"
android:visibility="gone"
+ android:focusable="true"
+ android:clickable="true"
+ android:background="?attr/colorSurfaceBright"
android:src="@drawable/ic_sort_arrow"
android:contentDescription="@null"/>
</merge> \ No newline at end of file
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 7487421e5..7ca1ec25a 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
@@ -91,7 +91,7 @@
<dimen name="drag_shadow_radius">4dp</dimen>
<dimen name="drag_shadow_padding">8dp</dimen>
- <dimen name="doc_header_sort_icon_size">16dp</dimen>
+ <dimen name="doc_header_sort_icon_size">32dp</dimen>
<dimen name="doc_header_height">60dp</dimen>
<dimen name="dropdown_sort_widget_margin">12dp</dimen>
diff --git a/src/com/android/documentsui/sorting/HeaderCell.java b/src/com/android/documentsui/sorting/HeaderCell.java
index b0e79e93c..acdc45235 100644
--- a/src/com/android/documentsui/sorting/HeaderCell.java
+++ b/src/com/android/documentsui/sorting/HeaderCell.java
@@ -102,6 +102,22 @@ public class HeaderCell extends LinearLayout {
}
}
+ /**
+ * Sets a listener on the sort arrow image. When Material 3 is enabled, the Sort Arrow has
+ * "android:clickable" set to true (to enable a hover state). This stops the click listener from
+ * falling through to the cell click listener and thus the sort arrow will need to handle clicks
+ * itself.
+ */
+ public void setSortArrowListeners(
+ View.OnClickListener clickListener,
+ View.OnKeyListener keyListener,
+ SortDimension dimension) {
+ ImageView arrow = findViewById(R.id.sort_arrow);
+ arrow.setTag(dimension);
+ arrow.setOnKeyListener(keyListener);
+ arrow.setOnClickListener(clickListener);
+ }
+
private void showArrow(
ImageView arrow, @AnimatorRes int anim, @StringRes int contentDescriptionId) {
arrow.setVisibility(View.VISIBLE);
diff --git a/src/com/android/documentsui/sorting/TableHeaderController.java b/src/com/android/documentsui/sorting/TableHeaderController.java
index 17fe29c55..52fa465a9 100644
--- a/src/com/android/documentsui/sorting/TableHeaderController.java
+++ b/src/com/android/documentsui/sorting/TableHeaderController.java
@@ -16,6 +16,9 @@
package com.android.documentsui.sorting;
+import static com.android.documentsui.flags.Flags.useMaterial3;
+
+import android.view.KeyEvent;
import android.view.View;
import com.android.documentsui.R;
@@ -33,6 +36,7 @@ public final class TableHeaderController implements SortController.WidgetControl
// We assign this here porque each method reference creates a new object
// instance (which is wasteful).
private final View.OnClickListener mOnCellClickListener = this::onCellClicked;
+ private final View.OnKeyListener mOnCellKeyListener = this::onCellKeyEvent;
private final SortModel.UpdateListener mModelListener = this::onModelUpdate;
private final View mTableHeader;
@@ -88,8 +92,12 @@ public final class TableHeaderController implements SortController.WidgetControl
if (dimension.getVisibility() == View.VISIBLE
&& dimension.getSortCapability() != SortDimension.SORT_CAPABILITY_NONE) {
cell.setOnClickListener(mOnCellClickListener);
+ if (useMaterial3()) {
+ cell.setSortArrowListeners(mOnCellClickListener, mOnCellKeyListener, dimension);
+ }
} else {
cell.setOnClickListener(null);
+ if (useMaterial3()) cell.setSortArrowListeners(null, null, null);
}
}
@@ -98,4 +106,18 @@ public final class TableHeaderController implements SortController.WidgetControl
mModel.sortByUser(dimension.getId(), dimension.getNextDirection());
}
+
+ /** Sorts the column if the key pressed was Enter or Space. */
+ private boolean onCellKeyEvent(View v, int keyCode, KeyEvent event) {
+ if (!useMaterial3()) {
+ return false;
+ }
+ // Only the enter and space bar should trigger the sort header to engage.
+ if (event.getAction() == KeyEvent.ACTION_UP
+ && (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SPACE)) {
+ onCellClicked(v);
+ return true;
+ }
+ return false;
+ }
}
diff --git a/tests/common/com/android/documentsui/bots/SortBot.java b/tests/common/com/android/documentsui/bots/SortBot.java
index a2990d7d9..f72f16f86 100644
--- a/tests/common/com/android/documentsui/bots/SortBot.java
+++ b/tests/common/com/android/documentsui/bots/SortBot.java
@@ -101,6 +101,16 @@ public class SortBot extends Bots.BaseBot {
assertTrue(Matchers.present(ColumnSortBot.MATCHER));
}
+ /**
+ * Identify if the sort arrow in list mode is focused.
+ *
+ * @return True if the sort arrow in the file list is found.
+ */
+ public boolean isSortIconFocused() {
+ UiObject2 sortArrow = mDevice.findObject(By.res(mTargetPackage + ":id/sort_arrow"));
+ return sortArrow.isFocused();
+ }
+
private boolean sortByMenu(int id, @SortDirection int direction) {
assert (direction != SortDimension.SORT_DIRECTION_NONE);
diff --git a/tests/functional/com/android/documentsui/SortDocumentUiTest.java b/tests/functional/com/android/documentsui/SortDocumentUiTest.java
index 53bc372e0..399867b89 100644
--- a/tests/functional/com/android/documentsui/SortDocumentUiTest.java
+++ b/tests/functional/com/android/documentsui/SortDocumentUiTest.java
@@ -16,7 +16,11 @@
package com.android.documentsui;
+import static com.android.documentsui.flags.Flags.FLAG_USE_MATERIAL3;
+
import android.net.Uri;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.view.KeyEvent;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -256,4 +260,32 @@ public class SortDocumentUiTest extends ActivityTestJunit4<FilesActivity> {
SortModel.SORT_DIMENSION_ID_FILE_TYPE, SortDimension.SORT_DIRECTION_DESCENDING);
bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_TYPE_DESC);
}
+
+ @Test
+ @RequiresFlagsEnabled(FLAG_USE_MATERIAL3)
+ public void testSortByArrowIcon() throws Exception {
+ initFiles();
+
+ bots.main.switchToListMode();
+
+ // Set up the sort in descending direction to allow deterministic behaviour of the sort
+ // icon.
+ bots.sort.sortBy(
+ SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_DESCENDING);
+ bots.directory.assertOrder(DIRS_IN_NAME_DESC, FILES_IN_NAME_DESC);
+
+ // Tab in reverse order until the sort icon is the focus (this avoids tabbing through the
+ // roots list which is quite long in tests).
+ while (!bots.sort.isSortIconFocused()) {
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_TAB, KeyEvent.META_SHIFT_LEFT_ON);
+ }
+
+ // Press enter on the sort icon and ensure the sort direction is changed.
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_ENTER);
+ bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_NAME_ASC);
+
+ // Space should also work in the same way as the ENTER key.
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_SPACE);
+ bots.directory.assertOrder(DIRS_IN_NAME_DESC, FILES_IN_NAME_DESC);
+ }
}