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

Commit f14d3751 authored by Kelvin Kwan's avatar Kelvin Kwan Committed by Android (Google) Code Review
Browse files

Merge "Add TabLayout UI to on BaseActivity and show it conditionally"

parents 33a186c1 1b9f85bf
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -28,6 +28,12 @@
    <!-- used for search chip. -->
    <include layout="@layout/search_chip_row"/>

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"/>

    <!-- used for apps row. -->
    <include layout="@layout/apps_row"/>

+6 −0
Original line number Diff line number Diff line
@@ -483,4 +483,10 @@

    <!-- Content description for deleting search history. [CHAR_LIMIT=60] -->
    <string name="delete_search_history">Delete search history <xliff:g id="text" example="image">%1$s</xliff:g></string>

    <!-- Label of tab to indicate personal directory [CHAR LIMIT=40] -->
    <string name="personal_tab">Personal</string>

    <!-- Label of tab to indicate work directory [CHAR LIMIT=40] -->
    <string name="work_tab">Work</string>
</resources>
+10 −3
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ import com.android.documentsui.sorting.SortController;
import com.android.documentsui.sorting.SortModel;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.tabs.TabLayout;

import java.util.ArrayList;
import java.util.Date;
@@ -95,7 +96,6 @@ public abstract class BaseActivity
    protected Injector<?> mInjector;

    protected ProvidersCache mProviders;
    protected UserIdManager mUserIdManager;
    protected DocumentsAccess mDocs;
    protected DrawerController mDrawer;

@@ -153,7 +153,6 @@ public abstract class BaseActivity
        mDrawer = DrawerController.create(this, mInjector.config);
        Metrics.logActivityLaunch(mState, intent);

        mUserIdManager = DocumentsApplication.getUserIdManager(this);
        mProviders = DocumentsApplication.getProvidersCache(this);
        mDocs = DocumentsAccess.create(this);

@@ -162,8 +161,11 @@ public abstract class BaseActivity

        Breadcrumb breadcrumb = findViewById(R.id.horizontal_breadcrumb);
        assert(breadcrumb != null);
        TabLayout profileTabs = findViewById(R.id.tabs);
        assert (profileTabs != null);

        mNavigator = new NavigationViewManager(this, mDrawer, mState, this, breadcrumb);
        mNavigator = new NavigationViewManager(this, mDrawer, mState, this, breadcrumb,
                profileTabs, DocumentsApplication.getUserIdManager(this));
        SearchManagerListener searchListener = new SearchManagerListener() {
            /**
             * Called when search results changed. Refreshes the content of the directory. It
@@ -738,6 +740,11 @@ public abstract class BaseActivity
        return mSearchManager.isExpanded();
    }

    @Override
    public boolean isSearching() {
        return mSearchManager.isSearching();
    }

    @Override
    public RootInfo getCurrentRoot() {
        RootInfo root = mState.stack.getRoot();
+8 −2
Original line number Diff line number Diff line
@@ -29,13 +29,13 @@ import android.view.ViewOutlineProvider;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;

import com.android.documentsui.R;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.AnimationView;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.tabs.TabLayout;

import java.util.function.IntConsumer;

@@ -51,6 +51,7 @@ public class NavigationViewManager {
    private final State mState;
    private final NavigationViewManager.Environment mEnv;
    private final Breadcrumb mBreadcrumb;
    private final ProfileTabs mProfileTabs;
    private final View mSearchBarView;
    private final CollapsingToolbarLayout mCollapsingBarLayout;
    private final Drawable mDefaultActionBarBackground;
@@ -62,7 +63,9 @@ public class NavigationViewManager {
            DrawerController drawer,
            State state,
            NavigationViewManager.Environment env,
            Breadcrumb breadcrumb) {
            Breadcrumb breadcrumb,
            TabLayout tabLayout,
            UserIdManager userIdManager) {

        mToolbar = activity.findViewById(R.id.toolbar);
        mDrawer = drawer;
@@ -70,6 +73,7 @@ public class NavigationViewManager {
        mEnv = env;
        mBreadcrumb = breadcrumb;
        mBreadcrumb.setup(env, state, this::onNavigationItemSelected);
        mProfileTabs = new ProfileTabs(tabLayout, mState, userIdManager, mEnv);

        mToolbar.setNavigationOnClickListener(
                new View.OnClickListener() {
@@ -122,6 +126,7 @@ public class NavigationViewManager {
    public void update() {
        updateScrollFlag();
        updateToolbar();
        mProfileTabs.updateView();

        // TODO: Looks to me like this block is never getting hit.
        if (mEnv.isSearchExpanded()) {
@@ -214,5 +219,6 @@ public class NavigationViewManager {
        @Deprecated  // Use CommonAddones#refreshCurrentRootAndDirectory
        void refreshCurrentRootAndDirectory(int animation);
        boolean isSearchExpanded();
        boolean isSearching();
    }
}
+106 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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;

import static androidx.core.util.Preconditions.checkNotNull;

import android.view.View;

import androidx.annotation.VisibleForTesting;

import com.android.documentsui.base.State;
import com.android.documentsui.base.UserId;

import com.google.android.material.tabs.TabLayout;

import java.util.Collections;
import java.util.List;

/**
 * A manager class to control UI on a {@link TabLayout} for cross-profile purpose.
 */
public class ProfileTabs {

    private final TabLayout mTabs;
    private final State mState;
    private final NavigationViewManager.Environment mEnv;
    private final UserIdManager mUserIdManager;
    private List<UserId> mUserIds;

    public ProfileTabs(TabLayout tabLayout, State state, UserIdManager userIdManager,
            NavigationViewManager.Environment env) {
        mTabs = checkNotNull(tabLayout);
        mState = checkNotNull(state);
        mEnv = checkNotNull(env);
        mUserIdManager = checkNotNull(userIdManager);
        mTabs.removeAllTabs();
        mUserIds = Collections.singletonList(UserId.CURRENT_USER);
    }

    /**
     * Update the tab layout based on conditions.
     */
    public void updateView() {
        updateTabsIfNeeded();
        mTabs.setVisibility(shouldShow() ? View.VISIBLE : View.GONE);
    }

    private void updateTabsIfNeeded() {
        List<UserId> userIds = mUserIdManager.getUserIds();
        // Add tabs if the userIds is not equals to cached mUserIds.
        // Given that mUserIds was initialized with only the current user, if getUserIds()
        // returns just the current user, we don't need to do anything on the tab layout.
        if (!userIds.equals(mUserIds)) {
            mUserIds = userIds;
            mTabs.removeAllTabs();
            if (mUserIds.size() > 1) {
                mTabs.addTab(createTab(R.string.personal_tab, mUserIdManager.getSystemUser()));
                mTabs.addTab(createTab(R.string.work_tab, mUserIdManager.getManagedUser()));
            }
        }
    }

    /**
     * Returns the user represented by the selected tab. If there is no tab, return the
     * current user.
     */
    @VisibleForTesting
    public UserId getSelectedUser() {
        if (mTabs.getTabCount() > 1 && mTabs.getSelectedTabPosition() >= 0) {
            return (UserId) mTabs.getTabAt(mTabs.getSelectedTabPosition()).getTag();
        }
        return UserId.CURRENT_USER;
    }

    private boolean shouldShow() {
        // Only show tabs when:
        // 1. state supports cross profile, and
        // 2. more than one tab, and
        // 3. not in search mode, and
        // 4. not in sub-folder, and
        // 5. the root supports cross profile.
        return mState.supportsCrossProfile()
                && mTabs.getTabCount() > 1
                && !mEnv.isSearching()
                && mState.stack.size() <= 1
                && mState.stack.getRoot() != null && mState.stack.getRoot().supportsCrossProfile();
    }

    private TabLayout.Tab createTab(int resId, UserId userId) {
        return mTabs.newTab().setText(resId).setTag(userId);
    }
}
Loading