Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 386b938e authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[DocsUI M3] Add bottom Select and Cancel buttons to file pickers" into main

parents 3521d86b 8ce189c5
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2025 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingStart="@dimen/picker_saver_padding_start"
    android:paddingEnd="@dimen/picker_saver_padding_end"
    android:paddingBottom="@dimen/picker_saver_padding_bottom"
    android:paddingTop="@dimen/picker_saver_padding_top"
    android:background="?attr/colorSurfaceContainer"
    android:baselineAligned="false"
    android:gravity="center_vertical|end"
    android:orientation="horizontal">

        <com.google.android.material.button.MaterialButton
            android:id="@+id/button_cancel"
            style="@style/MaterialTonalButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="@dimen/picker_saver_button_gap"
            android:layout_marginTop="@dimen/picker_saver_button_gap"
            android:layout_marginBottom="@dimen/picker_saver_button_gap"
            android:text="@android:string/cancel"
            app:cornerRadius="@dimen/button_corner_radius_m3" />

        <com.google.android.material.button.MaterialButton
            android:id="@+id/button_pick"
            style="@style/MaterialButtonM3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/picker_saver_button_gap"
            android:layout_marginTop="@dimen/picker_saver_button_gap"
            android:layout_marginBottom="@dimen/picker_saver_button_gap"
            android:text="@string/menu_select"
            app:cornerRadius="@dimen/button_corner_radius_m3" />
</LinearLayout>
+37 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import androidx.recyclerview.selection.Selection;
import androidx.recyclerview.selection.SelectionTracker;
import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;

import java.util.HashSet;
import java.util.Set;

/**
@@ -42,6 +43,8 @@ public final class DocsSelectionHelper extends SelectionTracker<String> {
    // See: b/69306667.
    private SelectionTracker<String> mDelegate = new StubSelectionTracker<>();

    private Set<ResetObserver> mResetObservers = new HashSet<>();

    @VisibleForTesting
    DocsSelectionHelper(DelegateFactory factory) {
        mFactory = factory;
@@ -52,6 +55,40 @@ public final class DocsSelectionHelper extends SelectionTracker<String> {
            mDelegate.clearSelection();
        }
        mDelegate = mFactory.create(selectionTracker);
        for (ResetObserver observer : mResetObservers) {
            observer.onReset();
        }
    }

    /**
     * Observes when the DocsSelectionHelper gets reset (this happens on every initialization and
     * re-initialization).
     */
    public abstract static class ResetObserver {
        /**
         * Called when the DocsSelectionHelper resets.
         */
        public void onReset() {
        }
    }

    /**
     * Adds a ResetObserver.
     * @param observer
     */
    public void addResetObserver(ResetObserver observer) {
        if (mResetObservers.contains(observer)) {
            return;
        }
        mResetObservers.add(observer);
    }

    /**
     * Removes a ResetObserver.
     * @param observer
     */
    public void removeResetObserver(ResetObserver observer) {
        mResetObservers.remove(observer);
    }

    @Override
+27 −0
Original line number Diff line number Diff line
@@ -24,6 +24,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.util.FlagUtils.isUseMaterial3FlagEnabled;

import static java.util.regex.Pattern.CASE_INSENSITIVE;

@@ -71,6 +72,7 @@ import com.android.documentsui.util.FileUtils;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.regex.Pattern;

@@ -427,6 +429,9 @@ class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionH
        return !doc.isContainer();
    }

    /**
     * Picks a folder for the ACTION_OPEN_TREE or ACTION_PICK_COPY_DESTINATION picker.
     */
    void pickDocument(FragmentManager fm, DocumentInfo pickTarget) {
        assert (pickTarget != null);
        mInjector.pickResult.increaseActionCount();
@@ -445,6 +450,28 @@ class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionH
        }
    }

    /**
     * Picks selected documents for the ACTION_OPEN or ACTION_GET_CONTENT picker.
     */
    void pickSelected() {
        if (!isUseMaterial3FlagEnabled()) {
            return;
        }
        assert (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT);
        List<DocumentInfo> selection = mInjector.getModel().getDocuments(
                mInjector.selectionMgr.getSelection());
        if (selection.isEmpty()) {
            Log.w(TAG, "There are no selected files");
            return;
        }

        if (selection.size() > 1) {
            mActivity.onDocumentsPicked(selection);
        } else {
            mActivity.onDocumentPicked(selection.getFirst());
        }
    }

    void saveDocument(
            String mimeType, String displayName, BooleanConsumer inProgressStateListener) {
        assert (mState.action == ACTION_CREATE);
+3 −1
Original line number Diff line number Diff line
@@ -22,6 +22,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.util.FlagUtils.isUseMaterial3FlagEnabled;
import static com.android.documentsui.util.Material3Config.getRes;

import android.database.Cursor;
@@ -137,7 +138,8 @@ public final class MenuManager extends com.android.documentsui.MenuManager {

    @Override
    protected void updateSelect(MenuItem select, SelectionDetails selectionDetails) {
        Menus.setEnabledAndVisible(select, (mState.action == ACTION_GET_CONTENT
        Menus.setEnabledAndVisible(select,
                !isUseMaterial3FlagEnabled() && (mState.action == ACTION_GET_CONTENT
                || mState.action == ACTION_OPEN)
                && selectionDetails.size() > 0);
        select.setTitle(getRes(R.string.menu_select));
+4 −1
Original line number Diff line number Diff line
@@ -245,8 +245,11 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons {
        } else if (mState.action == ACTION_OPEN_TREE ||
                mState.action == ACTION_PICK_COPY_DESTINATION) {
            PickDirectoryFragment.show(getSupportFragmentManager());
        } else if (isUseMaterial3FlagEnabled() && (mState.action == ACTION_OPEN
                || mState.action == ACTION_GET_CONTENT)) {
            PickFilesFragment.show(getSupportFragmentManager(), mState.action);
        } else if (!isUseMaterial3FlagEnabled()) {
            // If PickFragment or SaveFragment does not show,
            // If PickDirectoryFragment, PickFilesFragment or SaveFragment does not show,
            // Set save container background to transparent for edge to edge nav bar.
            // However when the use_material3 flag is on, the file path bar is at the bottom of the
            // layout and hence the edge to edge nav bar is no longer required.
Loading