Răsfoiți Sursa

Merge pull request #6262 from nextcloud/hideOnScrolling

Hide on scrolling
Tobias Kaminsky 4 ani în urmă
părinte
comite
d70502f747

+ 1 - 1
scripts/analysis/findbugs-results.txt

@@ -1 +1 @@
-356
+355

+ 1 - 1
src/main/java/com/owncloud/android/ui/activity/FileActivity.java

@@ -175,7 +175,7 @@ public abstract class FileActivity extends DrawerActivity
         if (onDeviceOnly) {
             setupToolbar();
         } else {
-            setupHomeSearchToolbar();
+            setupHomeSearchToolbarWithSortAndListButtons();
         }
     }
 

+ 50 - 32
src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -245,7 +245,7 @@ public class FileDisplayActivity extends FileActivity
         setContentView(binding.getRoot());
 
         // setup toolbar
-        setupHomeSearchToolbar();
+        setupHomeSearchToolbarWithSortAndListButtons();
 
         mMenuButton.setOnClickListener(v -> openDrawer());
 
@@ -280,10 +280,10 @@ public class FileDisplayActivity extends FileActivity
             if (PermissionUtil.shouldShowRequestPermissionRationale(this,
                     Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                 // Show explanation to the user and then request permission
-                Snackbar snackbar = Snackbar.make(binding.ListLayout,
+                Snackbar snackbar = Snackbar.make(binding.rootLayout,
                                                   R.string.permission_storage_access,
-                        Snackbar.LENGTH_INDEFINITE)
-                        .setAction(R.string.common_ok, v -> PermissionUtil.requestWriteExternalStoreagePermission(this));
+                                                  Snackbar.LENGTH_INDEFINITE)
+                    .setAction(R.string.common_ok, v -> PermissionUtil.requestWriteExternalStoreagePermission(this));
                 ThemeUtils.colorSnackbar(this, snackbar);
                 snackbar.show();
             } else {
@@ -598,7 +598,8 @@ public class FileDisplayActivity extends FileActivity
     }
 
 
-    public OCFileListFragment getListOfFilesFragment() {
+    public @androidx.annotation.Nullable
+    OCFileListFragment getListOfFilesFragment() {
         Fragment listOfFiles = getSupportFragmentManager().findFragmentByTag(
                 FileDisplayActivity.TAG_LIST_OF_FILES);
         if (listOfFiles != null) {
@@ -743,9 +744,10 @@ public class FileDisplayActivity extends FileActivity
                 getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                 mDrawerToggle.syncState();
 
-                if (getListOfFilesFragment() != null) {
-                    getListOfFilesFragment().setSearchFragment(false);
-                    getListOfFilesFragment().refreshDirectory();
+                OCFileListFragment ocFileListFragment = getListOfFilesFragment();
+                if (ocFileListFragment != null) {
+                    ocFileListFragment.setSearchFragment(false);
+                    ocFileListFragment.refreshDirectory();
                 }
             } else {
                 searchView.post(() -> searchView.setQuery("", true));
@@ -796,7 +798,11 @@ public class FileDisplayActivity extends FileActivity
                 break;
             }
             case R.id.action_select_all: {
-                getListOfFilesFragment().selectAllFiles(true);
+                OCFileListFragment fragment = getListOfFilesFragment();
+
+                if (fragment != null) {
+                    fragment.selectAllFiles(true);
+                }
                 break;
             }
             default:
@@ -1027,7 +1033,9 @@ public class FileDisplayActivity extends FileActivity
             searchView.clearFocus();
 
             // Remove the list to the original state
-            listOfFiles.performSearch("", true);
+            if (listOfFiles != null) {
+                listOfFiles.performSearch("", true);
+            }
 
             hideSearchView(getCurrentDir());
 
@@ -1080,7 +1088,10 @@ public class FileDisplayActivity extends FileActivity
         Log_OC.v(TAG, "onResume() start");
         super.onResume();
         // Instead of onPostCreate, starting the loading in onResume for children fragments
-        getListOfFilesFragment().setLoading(mSyncInProgress);
+        OCFileListFragment ocFileListFragment = getListOfFilesFragment();
+        if (ocFileListFragment != null) {
+            ocFileListFragment.setLoading(mSyncInProgress);
+        }
         syncAndUpdateFolder(false);
 
         OCFile startFile = null;
@@ -1092,16 +1103,17 @@ public class FileDisplayActivity extends FileActivity
         // refresh list of files
         if (searchView != null && !TextUtils.isEmpty(searchQuery)) {
             searchView.setQuery(searchQuery, false);
-        } else if (getListOfFilesFragment() != null && !getListOfFilesFragment().isSearchFragment()
-                && startFile == null) {
+        } else if (ocFileListFragment != null && !ocFileListFragment.isSearchFragment() && startFile == null) {
             updateListOfFilesFragment(false);
         } else {
-            getListOfFilesFragment().listDirectory(startFile, false, false);
+            if (ocFileListFragment != null) {
+                ocFileListFragment.listDirectory(startFile, false, false);
+            }
             updateActionBarTitleAndHomeButton(startFile);
         }
 
         // Listen for sync messages
-        if (getListOfFilesFragment() != null && !getListOfFilesFragment().isSearchFragment()) {
+        if (ocFileListFragment != null && !ocFileListFragment.isSearchFragment()) {
             IntentFilter syncIntentFilter = new IntentFilter(FileSyncAdapter.EVENT_FULL_SYNC_START);
             syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_END);
             syncIntentFilter.addAction(FileSyncAdapter.EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED);
@@ -1109,8 +1121,6 @@ public class FileDisplayActivity extends FileActivity
             syncIntentFilter.addAction(RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED);
             mSyncBroadcastReceiver = new SyncBroadcastReceiver();
             registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
-            //LocalBroadcastManager.getInstance(this).registerReceiver(mSyncBroadcastReceiver,
-            // syncIntentFilter);
         }
 
         // Listen for upload messages
@@ -1119,8 +1129,7 @@ public class FileDisplayActivity extends FileActivity
         registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
 
         // Listen for download messages
-        IntentFilter downloadIntentFilter = new IntentFilter(
-                FileDownloader.getDownloadAddedMessage());
+        IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.getDownloadAddedMessage());
         downloadIntentFilter.addAction(FileDownloader.getDownloadFinishMessage());
         mDownloadFinishReceiver = new DownloadFinishReceiver();
         registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
@@ -1134,18 +1143,18 @@ public class FileDisplayActivity extends FileActivity
                 setupToolbar();
             } else {
                 setDrawerMenuItemChecked(R.id.nav_all_files);
-                setupHomeSearchToolbar();
+                setupHomeSearchToolbarWithSortAndListButtons();
             }
         } else {
             if (menuItemId == R.id.nav_all_files) {
-                setupHomeSearchToolbar();
+                setupHomeSearchToolbarWithSortAndListButtons();
             } else {
                 setupToolbar();
             }
             setDrawerMenuItemChecked(menuItemId);
         }
 
-        if (getListOfFilesFragment() instanceof PhotoFragment) {
+        if (ocFileListFragment instanceof PhotoFragment) {
             updateActionBarTitleAndHomeButtonByString(getString(R.string.drawer_item_photos));
         }
 
@@ -1176,7 +1185,10 @@ public class FileDisplayActivity extends FileActivity
 
     @Override
     public void onSortingOrderChosen(FileSortOrder selection) {
-        getListOfFilesFragment().sortFiles(selection);
+        OCFileListFragment ocFileListFragment = getListOfFilesFragment();
+        if (ocFileListFragment != null) {
+            ocFileListFragment.sortFiles(selection);
+        }
     }
 
     @Override
@@ -1282,7 +1294,10 @@ public class FileDisplayActivity extends FileActivity
                         DataHolderUtil.getInstance().delete(intent.getStringExtra(FileSyncAdapter.EXTRA_RESULT));
 
                         Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
-                        getListOfFilesFragment().setLoading(mSyncInProgress);
+                        OCFileListFragment ocFileListFragment = getListOfFilesFragment();
+                        if (ocFileListFragment != null) {
+                            ocFileListFragment.setLoading(mSyncInProgress);
+                        }
                         setBackgroundText();
                     }
                 }
@@ -1406,7 +1421,10 @@ public class FileDisplayActivity extends FileActivity
                         // TODO what about other kind of previews?
                     }
                 }
-                getListOfFilesFragment().setLoading(false);
+                OCFileListFragment ocFileListFragment = getListOfFilesFragment();
+                if (ocFileListFragment != null) {
+                    ocFileListFragment.setLoading(false);
+                }
             } finally {
                 if (intent != null) {
                     removeStickyBroadcast(intent);
@@ -1837,7 +1855,7 @@ public class FileDisplayActivity extends FileActivity
                         getFileOperationsHelper().openFile(renamedFile);
                     }
                 } else if (details instanceof PreviewTextFragment &&
-                        renamedFile.equals(details.getFile())) {
+                    renamedFile.equals(details.getFile())) {
                     ((PreviewTextFileFragment) details).updateFile(renamedFile);
                     if (PreviewTextFileFragment.canBePreviewed(renamedFile)) {
                         startTextPreview(renamedFile, true);
@@ -1847,7 +1865,8 @@ public class FileDisplayActivity extends FileActivity
                 }
             }
 
-            if (getStorageManager().getFileById(renamedFile.getParentId()).equals(getCurrentDir())) {
+            OCFile file = getStorageManager().getFileById(renamedFile.getParentId());
+            if (file != null && file.equals(getCurrentDir())) {
                 updateListOfFilesFragment(false);
             }
 
@@ -2256,17 +2275,16 @@ public class FileDisplayActivity extends FileActivity
         }
     }
 
-    private boolean isGridView() {
-        return getListOfFilesFragment().isGridEnabled();
-    }
-
     @Override
     public void showFiles(boolean onDeviceOnly) {
         super.showFiles(onDeviceOnly);
         if (onDeviceOnly) {
             updateActionBarTitleAndHomeButtonByString(getString(R.string.drawer_item_on_device));
         }
-        getListOfFilesFragment().refreshDirectory();
+        OCFileListFragment ocFileListFragment = getListOfFilesFragment();
+        if (ocFileListFragment != null) {
+            ocFileListFragment.refreshDirectory();
+        }
     }
 
     @Subscribe(threadMode = ThreadMode.BACKGROUND)

+ 3 - 0
src/main/java/com/owncloud/android/ui/activity/ReceiveExternalFilesActivity.java

@@ -715,6 +715,9 @@ public class ReceiveExternalFilesActivity extends FileActivity
 
         ListView mListView = findViewById(android.R.id.list);
 
+        findViewById(R.id.sort_list_button_group).setVisibility(View.VISIBLE);
+        findViewById(R.id.switch_grid_view_button).setVisibility(View.GONE);
+
         String current_dir = mParents.peek();
         boolean notRoot = mParents.size() > 1;
 

+ 8 - 4
src/main/java/com/owncloud/android/ui/activity/ToolbarActivity.java

@@ -80,7 +80,7 @@ public abstract class ToolbarActivity extends BaseActivity {
      * Toolbar setup that must be called in implementer's {@link #onCreate} after {@link #setContentView} if they want
      * to use the toolbar.
      */
-    private void setupToolbar(boolean isHomeSearchToolbarShow) {
+    private void setupToolbar(boolean isHomeSearchToolbarShow, boolean showSortListButtonGroup) {
         int fontColor = ThemeUtils.appBarPrimaryFontColor(this);
 
         mToolbar = findViewById(R.id.toolbar);
@@ -94,6 +94,10 @@ public abstract class ToolbarActivity extends BaseActivity {
         mSearchText = findViewById(R.id.search_text);
         mSwitchAccountButton = findViewById(R.id.switch_account_button);
 
+        if (showSortListButtonGroup) {
+            findViewById(R.id.sort_list_button_group).setVisibility(View.VISIBLE);
+        }
+
         this.isHomeSearchToolbarShow = isHomeSearchToolbarShow;
         updateActionBarTitleAndHomeButton(null);
 
@@ -115,11 +119,11 @@ public abstract class ToolbarActivity extends BaseActivity {
     }
 
     public void setupToolbar() {
-        setupToolbar(false);
+        setupToolbar(false, false);
     }
 
-    public void setupHomeSearchToolbar() {
-        setupToolbar(true);
+    public void setupHomeSearchToolbarWithSortAndListButtons() {
+        setupToolbar(true, true);
     }
 
     /**

+ 10 - 85
src/main/java/com/owncloud/android/ui/fragment/ExtendedListFragment.java

@@ -27,9 +27,7 @@ package com.owncloud.android.ui.fragment;
 import android.animation.LayoutTransition;
 import android.app.Activity;
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.content.res.Configuration;
-import android.graphics.Color;
 import android.graphics.PorterDuff;
 import android.os.Bundle;
 import android.os.Handler;
@@ -54,9 +52,7 @@ import android.widget.LinearLayout;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
-import com.google.android.material.behavior.HideBottomViewOnScrollBehavior;
 import com.google.android.material.button.MaterialButton;
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
 import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
@@ -86,7 +82,6 @@ import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.StringRes;
 import androidx.appcompat.widget.SearchView;
-import androidx.coordinatorlayout.widget.CoordinatorLayout;
 import androidx.core.view.MenuItemCompat;
 import androidx.fragment.app.Fragment;
 import androidx.recyclerview.widget.GridLayoutManager;
@@ -129,8 +124,6 @@ public class ExtendedListFragment extends Fragment implements
     protected ImageView mEmptyListIcon;
     protected ProgressBar mEmptyListProgress;
 
-    private FloatingActionButton mFabMain;
-
     // Save the state of the scroll in browsing
     private ArrayList<Integer> mIndexes;
     private ArrayList<Integer> mFirstPositions;
@@ -174,10 +167,6 @@ public class ExtendedListFragment extends Fragment implements
         return mRecyclerView;
     }
 
-    public FloatingActionButton getFabMain() {
-        return mFabMain;
-    }
-
     public void setLoading(boolean enabled) {
         mRefreshListLayout.setRefreshing(enabled);
     }
@@ -231,7 +220,12 @@ public class ExtendedListFragment extends Fragment implements
         searchView.setOnQueryTextFocusChangeListener((v, hasFocus) -> handler.post(() -> {
             if (getActivity() != null && !(getActivity() instanceof FolderPickerActivity)
                 && !(getActivity() instanceof UploadFilesActivity)) {
-                setFabVisible(!hasFocus);
+                if (getActivity() instanceof FileDisplayActivity) {
+                    OCFileListFragment fileFragment = ((FileDisplayActivity) getActivity()).getListOfFilesFragment();
+                    if (fileFragment != null) {
+                        fileFragment.setFabVisible(!hasFocus);
+                    }
+                }
                 if (TextUtils.isEmpty(searchView.getQuery())) {
                     closeButton.setVisibility(View.INVISIBLE);
                 }
@@ -354,7 +348,7 @@ public class ExtendedListFragment extends Fragment implements
     }
 
     @Override
-    public void onAttach(Context context) {
+    public void onAttach(@NonNull Context context) {
         super.onAttach(context);
     }
 
@@ -391,12 +385,8 @@ public class ExtendedListFragment extends Fragment implements
         ThemeUtils.colorSwipeRefreshLayout(getContext(), mRefreshListLayout);
         mRefreshListLayout.setOnRefreshListener(this);
 
-        mSortButton = v.findViewById(R.id.sort_button);
-        mSwitchGridViewButton = v.findViewById(R.id.switch_grid_view_button);
-
-        mFabMain = v.findViewById(R.id.fab_main);
-        ThemeUtils.tintFloatingActionButton(mFabMain, requireContext());
-        ThemeUtils.drawableFloatingActionButton(mFabMain, R.drawable.ic_plus, requireContext());
+        mSortButton = getActivity().findViewById(R.id.sort_button);
+        mSwitchGridViewButton = getActivity().findViewById(R.id.switch_grid_view_button);
 
         return v;
     }
@@ -585,72 +575,7 @@ public class ExtendedListFragment extends Fragment implements
         mRefreshListLayout.setEnabled(enabled);
     }
 
-    /**
-     * Sets the 'visibility' state of the FAB contained in the fragment.
-     * <p>
-     * When 'false' is set, FAB visibility is set to View.GONE programmatically.
-     *
-     * @param visible Desired visibility for the FAB.
-     */
-    public void setFabVisible(final boolean visible) {
-        if (getActivity() != null) {
-            getActivity().runOnUiThread(() -> {
-                if (visible) {
-                    mFabMain.show();
-                    ThemeUtils.tintFloatingActionButton(mFabMain, requireContext());
-                } else {
-                    mFabMain.hide();
-                }
-
-                showFabWithBehavior(visible);
-            });
-        }
-    }
-
-    /**
-     * Remove this, if HideBottomViewOnScrollBehavior is fix by Google
-     *
-     * @param visible
-     */
-    private void showFabWithBehavior(boolean visible) {
-        ViewGroup.LayoutParams layoutParams = mFabMain.getLayoutParams();
-        if (layoutParams instanceof CoordinatorLayout.LayoutParams) {
-            CoordinatorLayout.Behavior coordinatorLayoutBehavior =
-                ((CoordinatorLayout.LayoutParams) layoutParams).getBehavior();
-            if (coordinatorLayoutBehavior instanceof HideBottomViewOnScrollBehavior) {
-                @SuppressWarnings("unchecked")
-                HideBottomViewOnScrollBehavior<FloatingActionButton> behavior =
-                    (HideBottomViewOnScrollBehavior<FloatingActionButton>) coordinatorLayoutBehavior;
-                if (visible) {
-                    behavior.slideUp(mFabMain);
-                } else {
-                    behavior.slideDown(mFabMain);
-                }
-            }
-        }
-    }
 
-    /**
-     * Sets the 'visibility' state of the FAB contained in the fragment.
-     * <p>
-     * When 'false' is set, FAB is greyed out
-     *
-     * @param enabled Desired visibility for the FAB.
-     */
-    public void setFabEnabled(final boolean enabled) {
-        if (getActivity() != null) {
-            getActivity().runOnUiThread(() -> {
-                if (enabled) {
-                    mFabMain.setEnabled(true);
-                    ThemeUtils.tintFloatingActionButton(mFabMain, requireContext());
-                } else {
-                    mFabMain.setEnabled(false);
-                    mFabMain.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY));
-                    mFabMain.setRippleColor(Color.GRAY);
-                }
-            });
-        }
-    }
 
     /**
      * /** Set message for empty list view.
@@ -810,7 +735,7 @@ public class ExtendedListFragment extends Fragment implements
     }
 
     @Override
-    public void onConfigurationChanged(Configuration newConfig) {
+    public void onConfigurationChanged(@NonNull Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
 
         if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {

+ 1 - 2
src/main/java/com/owncloud/android/ui/fragment/LocalFileListFragment.java

@@ -68,7 +68,7 @@ public class LocalFileListFragment extends ExtendedListFragment implements
     private LocalFileListAdapter mAdapter;
 
     @Override
-    public void onAttach(Context context) {
+    public void onAttach(@NonNull Context context) {
         super.onAttach(context);
     }
 
@@ -109,7 +109,6 @@ public class LocalFileListFragment extends ExtendedListFragment implements
         }
 
         setSwipeEnabled(false); // Disable pull-to-refresh
-        setFabVisible(false); // Disable FAB
 
         Log_OC.i(TAG, "onCreateView() end");
         return v;

+ 96 - 6
src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -28,6 +28,8 @@ import android.accounts.Account;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.Color;
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
@@ -44,6 +46,8 @@ import android.view.ViewGroup;
 import android.widget.AbsListView;
 import android.widget.PopupMenu;
 
+import com.google.android.material.behavior.HideBottomViewOnScrollBehavior;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
 import com.google.android.material.snackbar.Snackbar;
 import com.nextcloud.android.lib.richWorkspace.RichWorkspaceDirectEditingRemoteOperation;
 import com.nextcloud.client.account.User;
@@ -120,6 +124,7 @@ import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 import androidx.appcompat.app.ActionBar;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
 import androidx.core.content.ContextCompat;
 import androidx.drawerlayout.widget.DrawerLayout;
 import androidx.fragment.app.FragmentActivity;
@@ -191,6 +196,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
     protected SearchEvent searchEvent;
     protected AsyncTask<Void, Void, Boolean> remoteOperationAsyncTask;
     protected String mLimitToMimeType;
+    private FloatingActionButton mFabMain;
 
     @Inject DeviceInfo deviceInfo;
 
@@ -241,7 +247,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
      * {@inheritDoc}
      */
     @Override
-    public void onAttach(Context context) {
+    public void onAttach(@NonNull Context context) {
         super.onAttach(context);
         Log_OC.i(TAG, "onAttach");
         try {
@@ -284,6 +290,13 @@ public class OCFileListFragment extends ExtendedListFragment implements
             setChoiceModeAsMultipleModal(savedInstanceState);
         }
 
+        mFabMain = requireActivity().findViewById(R.id.fab_main);
+
+        if (mFabMain != null) { // is not available in FolderPickerActivity
+            ThemeUtils.tintFloatingActionButton(mFabMain, requireContext());
+            ThemeUtils.drawableFloatingActionButton(mFabMain, R.drawable.ic_plus, requireContext());
+        }
+
         Log_OC.i(TAG, "onCreateView() end");
         return v;
     }
@@ -410,11 +423,11 @@ public class OCFileListFragment extends ExtendedListFragment implements
      */
     private void registerFabListener() {
         FileActivity activity = (FileActivity) getActivity();
-        getFabMain().setOnClickListener(v -> new OCFileListBottomSheetDialog(activity,
-                                                                             this,
-                                                                             deviceInfo,
-                                                                             accountManager.getUser(),
-                                                                             getCurrentFile())
+        mFabMain.setOnClickListener(v -> new OCFileListBottomSheetDialog(activity,
+                                                                         this,
+                                                                         deviceInfo,
+                                                                         accountManager.getUser(),
+                                                                         getCurrentFile())
             .show());
     }
 
@@ -1739,4 +1752,81 @@ public class OCFileListFragment extends ExtendedListFragment implements
     public boolean isLoading() {
         return false;
     }
+
+    /**
+     * Sets the 'visibility' state of the FAB contained in the fragment.
+     * <p>
+     * When 'false' is set, FAB visibility is set to View.GONE programmatically.
+     *
+     * @param visible Desired visibility for the FAB.
+     */
+    void setFabVisible(final boolean visible) {
+        if (mFabMain == null) {
+            // is not available in FolderPickerActivity
+            return;
+        }
+
+        if (getActivity() != null) {
+            getActivity().runOnUiThread(() -> {
+                if (visible) {
+                    mFabMain.show();
+                    ThemeUtils.tintFloatingActionButton(mFabMain, requireContext());
+                } else {
+                    mFabMain.hide();
+                }
+
+                showFabWithBehavior(visible);
+            });
+        }
+    }
+
+    /**
+     * Remove this, if HideBottomViewOnScrollBehavior is fix by Google
+     *
+     * @param visible
+     */
+    private void showFabWithBehavior(boolean visible) {
+        ViewGroup.LayoutParams layoutParams = mFabMain.getLayoutParams();
+        if (layoutParams instanceof CoordinatorLayout.LayoutParams) {
+            CoordinatorLayout.Behavior coordinatorLayoutBehavior =
+                ((CoordinatorLayout.LayoutParams) layoutParams).getBehavior();
+            if (coordinatorLayoutBehavior instanceof HideBottomViewOnScrollBehavior) {
+                @SuppressWarnings("unchecked")
+                HideBottomViewOnScrollBehavior<FloatingActionButton> behavior =
+                    (HideBottomViewOnScrollBehavior<FloatingActionButton>) coordinatorLayoutBehavior;
+                if (visible) {
+                    behavior.slideUp(mFabMain);
+                } else {
+                    behavior.slideDown(mFabMain);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the 'visibility' state of the FAB contained in the fragment.
+     * <p>
+     * When 'false' is set, FAB is greyed out
+     *
+     * @param enabled Desired visibility for the FAB.
+     */
+    public void setFabEnabled(final boolean enabled) {
+        if (mFabMain == null) {
+            // is not available in FolderPickerActivity
+            return;
+        }
+
+        if (getActivity() != null) {
+            getActivity().runOnUiThread(() -> {
+                if (enabled) {
+                    mFabMain.setEnabled(true);
+                    ThemeUtils.tintFloatingActionButton(mFabMain, requireContext());
+                } else {
+                    mFabMain.setEnabled(false);
+                    mFabMain.setBackgroundTintList(ColorStateList.valueOf(Color.GRAY));
+                    mFabMain.setRippleColor(Color.GRAY);
+                }
+            });
+        }
+    }
 }

+ 2 - 0
src/main/java/com/owncloud/android/ui/trashbin/TrashbinActivity.java

@@ -116,6 +116,8 @@ public class TrashbinActivity extends FileActivity implements
         setContentView(R.layout.trashbin_activity);
         unbinder = ButterKnife.bind(this);
         setupToolbar();
+        findViewById(R.id.sort_list_button_group).setVisibility(View.VISIBLE);
+        findViewById(R.id.switch_grid_view_button).setVisibility(View.GONE);
         updateActionBarTitleAndHomeButtonByString(getString(R.string.trashbin_activity_title));
         setupDrawer(R.id.nav_trashbin);
     }

+ 39 - 25
src/main/res/layout/files.xml

@@ -17,44 +17,58 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
   -->
 <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:clickable="true"
     android:fitsSystemWindows="true">
 
-    <!-- The main content view -->
-    <LinearLayout
+    <androidx.coordinatorlayout.widget.CoordinatorLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:id="@+id/root_layout"
-        android:orientation="vertical">
+        android:layout_height="match_parent">
+
+        <include layout="@layout/toolbar_standard" />
 
-            <include layout="@layout/toolbar_standard" />
+        <!-- The main content view -->
+        <LinearLayout
+            android:id="@+id/root_layout"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="@color/bg_default"
+            android:baselineAligned="false"
+            android:contentDescription="@string/list_layout"
+            android:orientation="horizontal"
+            app:layout_behavior="@string/appbar_scrolling_view_behavior">
 
-            <LinearLayout
-                android:id="@+id/ListLayout"
-                android:layout_width="match_parent"
+            <FrameLayout
+                android:id="@+id/left_fragment_container"
+                android:layout_width="@dimen/zero"
                 android:layout_height="match_parent"
-                android:background="@color/bg_default"
-                android:baselineAligned="false"
-                android:contentDescription="@string/list_layout"
-                android:orientation="horizontal">
+                android:layout_weight="1"
+                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
 
-                <FrameLayout
-                    android:id="@+id/left_fragment_container"
-                    android:layout_width="@dimen/zero"
-                    android:layout_height="match_parent"
-                    android:layout_weight="1" />
+            <FrameLayout
+                android:id="@+id/right_fragment_container"
+                android:layout_width="@dimen/zero"
+                android:layout_height="match_parent"
+                android:layout_weight="2"
+                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+        </LinearLayout>
 
-                <FrameLayout
-                    android:id="@+id/right_fragment_container"
-                    android:layout_width="@dimen/zero"
-                    android:layout_height="match_parent"
-                    android:layout_weight="2" />
-            </LinearLayout>
+        <com.google.android.material.floatingactionbutton.FloatingActionButton
+            android:id="@+id/fab_main"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentEnd="true"
+            android:layout_gravity="end|bottom"
+            android:layout_marginEnd="@dimen/standard_margin"
+            android:layout_marginBottom="@dimen/standard_margin"
+            android:contentDescription="@string/fab_label"
+            android:visibility="gone"
+            app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" />
 
-    </LinearLayout>
+    </androidx.coordinatorlayout.widget.CoordinatorLayout>
 
     <include
         layout="@layout/drawer"

+ 12 - 77
src/main/res/layout/list_fragment.xml

@@ -18,89 +18,24 @@
 -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/list_fragment_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <androidx.coordinatorlayout.widget.CoordinatorLayout
-        android:id="@+id/list_fragment_layout"
+    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
+        android:id="@+id/swipe_containing_list"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="match_parent"
+        android:footerDividersEnabled="false"
+        android:visibility="visible"
+        app:layout_behavior="@string/appbar_scrolling_view_behavior">
 
-        <com.google.android.material.appbar.AppBarLayout
+        <com.owncloud.android.ui.EmptyRecyclerView
+            android:id="@+id/list_root"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:background="@color/bg_default"
-            app:elevation="0dp">
+            android:layout_height="match_parent" />
+    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
 
-            <androidx.constraintlayout.widget.ConstraintLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                app:layout_scrollFlags="scroll|enterAlways|snap">
+    <include layout="@layout/empty_list" />
 
-                <com.google.android.material.button.MaterialButton
-                    android:id="@+id/sort_button"
-                    style="@style/Widget.MaterialComponents.Button.TextButton"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="8dp"
-                    android:contentDescription="@string/actionbar_sort"
-                    android:minWidth="0dp"
-                    android:text="@string/menu_item_sort_by_date_newest_first"
-                    android:textAlignment="textStart"
-                    android:textAllCaps="false"
-                    android:textColor="@color/fontAppbar"
-                    android:textSize="14sp"
-                    app:icon="@drawable/ic_keyboard_arrow_down"
-                    app:iconGravity="textEnd"
-                    app:iconSize="16dp"
-                    app:iconTint="@color/fontAppbar"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
-
-                <com.google.android.material.button.MaterialButton
-                    android:id="@+id/switch_grid_view_button"
-                    style="@style/Widget.AppTheme.Button.IconButton"
-                    android:layout_width="38dp"
-                    android:layout_height="38dp"
-                    android:layout_marginEnd="4dp"
-                    android:contentDescription="@string/action_switch_grid_view"
-                    app:cornerRadius="24dp"
-                    app:icon="@drawable/ic_view_module"
-                    app:iconTint="@color/fontAppbar"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintEnd_toEndOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
-            </androidx.constraintlayout.widget.ConstraintLayout>
-        </com.google.android.material.appbar.AppBarLayout>
-
-        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-            android:id="@+id/swipe_containing_list"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:footerDividersEnabled="false"
-            android:visibility="visible"
-            app:layout_behavior="@string/appbar_scrolling_view_behavior">
-
-            <com.owncloud.android.ui.EmptyRecyclerView
-                android:id="@+id/list_root"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent" />
-        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
-
-        <include layout="@layout/empty_list" />
-
-        <com.google.android.material.floatingactionbutton.FloatingActionButton
-            android:id="@+id/fab_main"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_alignParentEnd="true"
-            android:layout_gravity="end|bottom"
-            android:layout_marginEnd="@dimen/standard_margin"
-            android:layout_marginBottom="@dimen/standard_margin"
-            android:contentDescription="@string/fab_label"
-            android:visibility="gone"
-            app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" />
-
-    </androidx.coordinatorlayout.widget.CoordinatorLayout>
 </RelativeLayout>

+ 0 - 35
src/main/res/layout/receive_external_files.xml

@@ -32,41 +32,6 @@
         android:layout_height="0dp"
         android:layout_weight="1">
 
-        <com.google.android.material.appbar.AppBarLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:background="@color/bg_default"
-            app:elevation="0dp">
-
-            <androidx.constraintlayout.widget.ConstraintLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                app:layout_scrollFlags="scroll|enterAlways|snap">
-
-                <com.google.android.material.button.MaterialButton
-                    android:id="@+id/sort_button"
-                    style="@style/Widget.MaterialComponents.Button.TextButton"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginStart="8dp"
-                    android:contentDescription="@string/actionbar_sort"
-                    android:minWidth="0dp"
-                    android:text="@string/menu_item_sort_by_date_newest_first"
-                    android:textAlignment="textStart"
-                    android:textAllCaps="false"
-                    android:textColor="@color/fontAppbar"
-                    android:textSize="14sp"
-                    app:icon="@drawable/ic_keyboard_arrow_down"
-                    app:iconGravity="textEnd"
-                    app:iconSize="16dp"
-                    app:iconTint="@color/fontAppbar"
-                    app:layout_constraintBottom_toBottomOf="parent"
-                    app:layout_constraintStart_toStartOf="parent"
-                    app:layout_constraintTop_toTopOf="parent" />
-            </androidx.constraintlayout.widget.ConstraintLayout>
-
-        </com.google.android.material.appbar.AppBarLayout>
-
         <ListView
             android:id="@android:id/list"
             android:layout_width="match_parent"

+ 1 - 1
src/main/res/layout/synced_folders_layout.xml

@@ -52,7 +52,7 @@
                 android:clipToPadding="false"
                 android:scrollbarStyle="outsideOverlay"
                 android:scrollbars="vertical"
-                android:visibility="visible"/>
+                android:visibility="visible" />
         </FrameLayout>
 
     </androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 47 - 2
src/main/res/layout/toolbar_standard.xml

@@ -30,7 +30,8 @@
     <RelativeLayout
         android:id="@+id/default_toolbar"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="wrap_content"
+        app:layout_scrollFlags="scroll|enterAlways">
 
         <FrameLayout
             android:id="@+id/preview_image_frame"
@@ -84,7 +85,8 @@
         app:cardCornerRadius="8dp"
         app:cardElevation="2dp"
         app:strokeWidth="0dp"
-        tools:visibility="visible">
+        tools:visibility="visible"
+        app:layout_scrollFlags="scroll|enterAlways">
 
         <androidx.constraintlayout.widget.ConstraintLayout
             android:layout_width="match_parent"
@@ -137,6 +139,49 @@
 
     </com.google.android.material.card.MaterialCardView>
 
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/sort_list_button_group"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        app:layout_scrollFlags="scroll|enterAlways">
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/sort_button"
+            style="@style/Widget.MaterialComponents.Button.TextButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:contentDescription="@string/actionbar_sort"
+            android:minWidth="0dp"
+            android:text="@string/menu_item_sort_by_date_newest_first"
+            android:textAlignment="textStart"
+            android:textAllCaps="false"
+            android:textColor="@color/fontAppbar"
+            android:textSize="14sp"
+            app:icon="@drawable/ic_keyboard_arrow_down"
+            app:iconGravity="textEnd"
+            app:iconSize="16dp"
+            app:iconTint="@color/fontAppbar"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/switch_grid_view_button"
+            style="@style/Widget.AppTheme.Button.IconButton"
+            android:layout_width="38dp"
+            android:layout_height="38dp"
+            android:layout_marginEnd="4dp"
+            android:contentDescription="@string/action_switch_grid_view"
+            app:cornerRadius="24dp"
+            app:icon="@drawable/ic_view_module"
+            app:iconTint="@color/fontAppbar"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
     <include layout="@layout/info_box" />
 
 </com.google.android.material.appbar.AppBarLayout>

+ 0 - 35
src/main/res/layout/trashbin_activity.xml

@@ -21,7 +21,6 @@
 -->
 <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/drawer_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -42,40 +41,6 @@
             android:layout_height="match_parent"
             android:layout_below="@id/appbar">
 
-            <com.google.android.material.appbar.AppBarLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:background="@color/bg_default"
-                app:elevation="0dp">
-
-                <androidx.constraintlayout.widget.ConstraintLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    app:layout_scrollFlags="scroll|enterAlways|snap">
-
-                    <com.google.android.material.button.MaterialButton
-                        android:id="@+id/sort_button"
-                        style="@style/Widget.MaterialComponents.Button.TextButton"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginStart="8dp"
-                        android:contentDescription="@string/actionbar_sort"
-                        android:minWidth="0dp"
-                        android:text="@string/menu_item_sort_by_date_newest_first"
-                        android:textAlignment="textStart"
-                        android:textAllCaps="false"
-                        android:textColor="@color/fontAppbar"
-                        android:textSize="14sp"
-                        app:icon="@drawable/ic_keyboard_arrow_down"
-                        app:iconGravity="textEnd"
-                        app:iconSize="16dp"
-                        app:iconTint="@color/fontAppbar"
-                        app:layout_constraintBottom_toBottomOf="parent"
-                        app:layout_constraintStart_toStartOf="parent"
-                        app:layout_constraintTop_toTopOf="parent" />
-                </androidx.constraintlayout.widget.ConstraintLayout>
-            </com.google.android.material.appbar.AppBarLayout>
-
             <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
                 android:id="@+id/swipe_containing_list"
                 android:layout_width="match_parent"