diff options
author | 2025-02-03 21:53:49 -0800 | |
---|---|---|
committer | 2025-02-04 16:54:54 +1100 | |
commit | 616e5b91d2e7a10714b22cff37150e8c25a096b3 (patch) | |
tree | 6da602e641a173af7d6bf390fc26ad8ac46b29af | |
parent | b4a53462e1feb20a73319c1f9b14e4ae02778000 (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
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); + } } |