mirror of
https://github.com/nextcloud/android.git
synced 2024-12-18 23:11:58 +03:00
Merge pull request #14146 from nextcloud/feature-bottom-navigation
Feature - Bottom Navigation View
This commit is contained in:
commit
586a9b8010
11 changed files with 149 additions and 43 deletions
|
@ -163,6 +163,7 @@ class FileUploadWorker(
|
|||
return Result.success()
|
||||
}
|
||||
|
||||
@Suppress("NestedBlockDepth")
|
||||
private fun uploadFiles(totalUploadSize: Int, uploadsPerPage: List<OCUpload>, accountName: String) {
|
||||
val user = userAccountManager.getUser(accountName)
|
||||
setWorkerState(user.get(), uploadsPerPage)
|
||||
|
|
|
@ -46,6 +46,7 @@ import com.bumptech.glide.load.model.StreamEncoder;
|
|||
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
|
||||
import com.bumptech.glide.request.animation.GlideAnimation;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
import com.google.android.material.progressindicator.LinearProgressIndicator;
|
||||
|
@ -123,6 +124,7 @@ import androidx.core.content.res.ResourcesCompat;
|
|||
import androidx.core.view.GravityCompat;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hct.Hct;
|
||||
|
||||
import static com.nextcloud.utils.extensions.DrawerActivityExtensionsKt.getMenuItemIdFromTitle;
|
||||
|
@ -155,7 +157,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
/**
|
||||
* Reference to the navigation view.
|
||||
*/
|
||||
private NavigationView mNavigationView;
|
||||
private NavigationView drawerNavigationView;
|
||||
|
||||
/**
|
||||
* Reference to the navigation view header.
|
||||
|
@ -196,6 +198,8 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
private ExternalLinksProvider externalLinksProvider;
|
||||
private ArbitraryDataProvider arbitraryDataProvider;
|
||||
|
||||
private BottomNavigationView bottomNavigationView;
|
||||
|
||||
@Inject
|
||||
AppPreferences preferences;
|
||||
|
||||
|
@ -208,14 +212,14 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
protected void setupDrawer() {
|
||||
mDrawerLayout = findViewById(R.id.drawer_layout);
|
||||
|
||||
mNavigationView = findViewById(R.id.nav_view);
|
||||
if (mNavigationView != null) {
|
||||
drawerNavigationView = findViewById(R.id.nav_view);
|
||||
if (drawerNavigationView != null) {
|
||||
|
||||
// Setting up drawer header
|
||||
mNavigationViewHeader = mNavigationView.getHeaderView(0);
|
||||
mNavigationViewHeader = drawerNavigationView.getHeaderView(0);
|
||||
updateHeader();
|
||||
|
||||
setupDrawerMenu(mNavigationView);
|
||||
setupDrawerMenu(drawerNavigationView);
|
||||
getAndDisplayUserQuota();
|
||||
setupQuotaElement();
|
||||
}
|
||||
|
@ -225,6 +229,56 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
bottomNavigationView = findViewById(R.id.bottom_navigation);
|
||||
if (bottomNavigationView != null) {
|
||||
themeBottomNavigationMenu();
|
||||
checkAssistantBottomNavigationMenu();
|
||||
handleBottomNavigationViewClicks();
|
||||
}
|
||||
}
|
||||
|
||||
private void themeBottomNavigationMenu() {
|
||||
viewThemeUtils.platform.colorBottomNavigationView(bottomNavigationView);
|
||||
}
|
||||
|
||||
@SuppressFBWarnings("RV")
|
||||
private void checkAssistantBottomNavigationMenu() {
|
||||
boolean isAssistantAvailable = getCapabilities().getAssistant().isTrue();
|
||||
|
||||
bottomNavigationView
|
||||
.getMenu()
|
||||
.findItem(R.id.nav_assistant)
|
||||
.setVisible(isAssistantAvailable);
|
||||
}
|
||||
|
||||
@SuppressFBWarnings("RV")
|
||||
private void handleBottomNavigationViewClicks() {
|
||||
bottomNavigationView.setOnItemSelectedListener(menuItem -> {
|
||||
menuItemId = menuItem.getItemId();
|
||||
|
||||
if (menuItemId == R.id.nav_all_files) {
|
||||
showFiles(false,false);
|
||||
if (this instanceof FileDisplayActivity fda) {
|
||||
fda.browseToRoot();
|
||||
}
|
||||
} else if (menuItemId == R.id.nav_favorites) {
|
||||
handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH), menuItemId);
|
||||
} else if (menuItemId == R.id.nav_assistant) {
|
||||
startComposeActivity(ComposeDestination.AssistantScreen, R.string.assistant_screen_top_bar_title);
|
||||
} else if (menuItemId == R.id.nav_gallery) {
|
||||
startPhotoSearch(menuItem.getItemId());
|
||||
}
|
||||
|
||||
// Remove extra icon from the action bar
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setIcon(null);
|
||||
}
|
||||
|
||||
setNavigationViewItemChecked();
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,7 +296,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
if (menuItemIdFromTitle != null && menuItemIdFromTitle != menuItemId) {
|
||||
menuItemId = menuItemIdFromTitle;
|
||||
}
|
||||
setDrawerMenuItemChecked();
|
||||
setNavigationViewItemChecked();
|
||||
isMenuItemChecked = true;
|
||||
}
|
||||
}
|
||||
|
@ -500,7 +554,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
private void onNavigationItemClicked(final MenuItem menuItem) {
|
||||
int itemId = menuItem.getItemId();
|
||||
menuItemId = itemId;
|
||||
setDrawerMenuItemChecked();
|
||||
setNavigationViewItemChecked();
|
||||
|
||||
if (itemId == R.id.nav_all_files || itemId == R.id.nav_personal_files) {
|
||||
if (this instanceof FileDisplayActivity &&
|
||||
|
@ -809,9 +863,9 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
}
|
||||
|
||||
private void unsetAllDrawerMenuItems() {
|
||||
if (mNavigationView != null) {
|
||||
mNavigationView.getMenu();
|
||||
Menu menu = mNavigationView.getMenu();
|
||||
if (drawerNavigationView != null) {
|
||||
drawerNavigationView.getMenu();
|
||||
Menu menu = drawerNavigationView.getMenu();
|
||||
for (int i = 0; i < menu.size(); i++) {
|
||||
menu.getItem(i).setChecked(false);
|
||||
}
|
||||
|
@ -879,29 +933,29 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
}
|
||||
|
||||
/**
|
||||
* checks/highlights the provided menu item if the drawer has been initialized and the menu item exists.
|
||||
*
|
||||
* Sets the menu item as checked in both the drawer and bottom navigation views, if applicable.
|
||||
*/
|
||||
public void setDrawerMenuItemChecked() {
|
||||
if (mNavigationView == null) {
|
||||
return;
|
||||
@SuppressFBWarnings("RV")
|
||||
public void setNavigationViewItemChecked() {
|
||||
if (drawerNavigationView != null) {
|
||||
MenuItem menuItem = drawerNavigationView.getMenu().findItem(menuItemId);
|
||||
|
||||
if (menuItem != null && !menuItem.isChecked()) {
|
||||
viewThemeUtils.platform.colorNavigationView(drawerNavigationView);
|
||||
menuItem.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem menuItem = mNavigationView.getMenu().findItem(menuItemId);
|
||||
if (bottomNavigationView != null) {
|
||||
MenuItem menuItem = bottomNavigationView.getMenu().findItem(menuItemId);
|
||||
|
||||
if (menuItem == null) {
|
||||
Log_OC.w(TAG, "setDrawerMenuItemChecked has been called with invalid menu-item-ID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (menuItem.isChecked()) {
|
||||
return;
|
||||
// Don't highlight assistant bottom navigation item because Assistant screen doesn't have bottom navigation bar
|
||||
if (menuItem != null && !menuItem.isChecked() && menuItem.getItemId() != R.id.nav_assistant) {
|
||||
menuItem.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
Log_OC.d(TAG, "New menu item is: " + menuItemId);
|
||||
|
||||
viewThemeUtils.platform.colorNavigationView(mNavigationView);
|
||||
menuItem.setChecked(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -971,14 +1025,14 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
}
|
||||
|
||||
private void updateExternalLinksInDrawer() {
|
||||
if (mNavigationView != null && MDMConfig.INSTANCE.externalSiteSupport(this)) {
|
||||
mNavigationView.getMenu().removeGroup(R.id.drawer_menu_external_links);
|
||||
if (drawerNavigationView != null && MDMConfig.INSTANCE.externalSiteSupport(this)) {
|
||||
drawerNavigationView.getMenu().removeGroup(R.id.drawer_menu_external_links);
|
||||
|
||||
int greyColor = ContextCompat.getColor(this, R.color.drawer_menu_icon);
|
||||
|
||||
for (final ExternalLink link : externalLinksProvider.getExternalLink(ExternalLinkType.LINK)) {
|
||||
int id = mNavigationView.getMenu().add(R.id.drawer_menu_external_links,
|
||||
MENU_ITEM_EXTERNAL_LINK + link.getId(), MENU_ORDER_EXTERNAL_LINKS, link.getName())
|
||||
int id = drawerNavigationView.getMenu().add(R.id.drawer_menu_external_links,
|
||||
MENU_ITEM_EXTERNAL_LINK + link.getId(), MENU_ORDER_EXTERNAL_LINKS, link.getName())
|
||||
.setCheckable(true).getItemId();
|
||||
|
||||
MenuSimpleTarget target = new MenuSimpleTarget<Drawable>(id) {
|
||||
|
@ -1005,7 +1059,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
}
|
||||
|
||||
private void setExternalLinkIcon(int id, Drawable drawable, int greyColor) {
|
||||
MenuItem menuItem = mNavigationView.getMenu().findItem(id);
|
||||
MenuItem menuItem = drawerNavigationView.getMenu().findItem(id);
|
||||
|
||||
if (menuItem != null) {
|
||||
if (drawable != null) {
|
||||
|
@ -1037,7 +1091,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
mIsAccountChooserActive = savedInstanceState.getBoolean(KEY_IS_ACCOUNT_CHOOSER_ACTIVE, false);
|
||||
setDrawerMenuItemChecked();
|
||||
setNavigationViewItemChecked();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1312,10 +1366,10 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
}
|
||||
|
||||
private void handleNavItemClickEvent(@IdRes int menuItemId) {
|
||||
if (mNavigationView == null) {
|
||||
mNavigationView = findViewById(R.id.nav_view);
|
||||
if (drawerNavigationView == null) {
|
||||
drawerNavigationView = findViewById(R.id.nav_view);
|
||||
}
|
||||
Menu navMenu = mNavigationView.getMenu();
|
||||
Menu navMenu = drawerNavigationView.getMenu();
|
||||
onNavigationItemClicked(navMenu.findItem(menuItemId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1249,7 +1249,7 @@ public class FileDisplayActivity extends FileActivity
|
|||
menuItemId = R.id.nav_all_files;
|
||||
}
|
||||
|
||||
setDrawerMenuItemChecked();
|
||||
setNavigationViewItemChecked();
|
||||
|
||||
if (MainApp.isOnlyOnDevice()) {
|
||||
setupToolbar();
|
||||
|
|
|
@ -1839,7 +1839,10 @@ public class OCFileListFragment extends ExtendedListFragment implements
|
|||
|
||||
// avoid calling api multiple times if async task is already executing
|
||||
if (remoteOperationAsyncTask != null && remoteOperationAsyncTask.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
Log_OC.d(TAG, "OCFileListSearchAsyncTask already running skipping new api call for search event: " + searchEvent.getSearchType());
|
||||
if (searchEvent != null) {
|
||||
Log_OC.d(TAG, "OCFileListSearchAsyncTask already running skipping new api call for search event: " + searchEvent.getSearchType());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -387,6 +387,7 @@ class TrashbinActivity :
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("ReturnCount")
|
||||
private fun onFileActionChosen(@IdRes itemId: Int, checkedFiles: Set<TrashbinFile>): Boolean {
|
||||
if (checkedFiles.isEmpty()) {
|
||||
return false
|
||||
|
|
|
@ -11,7 +11,6 @@ import android.content.res.Resources;
|
|||
import android.view.Menu;
|
||||
|
||||
import com.nextcloud.client.account.User;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.lib.resources.status.OCCapability;
|
||||
|
||||
|
|
|
@ -596,7 +596,7 @@ class EncryptionUtilsV2 {
|
|||
}
|
||||
|
||||
@Throws(IllegalStateException::class)
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
@Suppress("TooGenericExceptionCaught", "LongMethod")
|
||||
fun parseAnyMetadata(
|
||||
metadataResponse: MetadataResponse,
|
||||
user: User,
|
||||
|
|
|
@ -45,18 +45,26 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
android:id="@+id/bottom_navigation"
|
||||
app:labelVisibilityMode="labeled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:menu="@menu/bottom_navigation_menu"
|
||||
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" />
|
||||
|
||||
<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:layout_marginBottom="@dimen/floating_action_button_bottom_margin"
|
||||
android:contentDescription="@string/fab_label"
|
||||
android:visibility="gone"
|
||||
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
|
||||
app:srcCompat="@drawable/ic_plus"
|
||||
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
33
app/src/main/res/menu/bottom_navigation_menu.xml
Normal file
33
app/src/main/res/menu/bottom_navigation_menu.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Nextcloud - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
~ SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/nav_all_files"
|
||||
android:enabled="true"
|
||||
android:icon="@drawable/folder"
|
||||
android:title="@string/bottom_navigation_menu_files_label"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_favorites"
|
||||
android:enabled="true"
|
||||
android:icon="@drawable/nav_favorites"
|
||||
android:title="@string/bottom_navigation_menu_favorites_label"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_assistant"
|
||||
android:enabled="true"
|
||||
android:icon="@drawable/ic_assistant"
|
||||
android:title="@string/bottom_navigation_menu_assistant_label"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_gallery"
|
||||
android:enabled="true"
|
||||
android:icon="@drawable/nav_photos"
|
||||
android:title="@string/bottom_navigation_menu_media_label"/>
|
||||
|
||||
</menu>
|
|
@ -34,6 +34,7 @@
|
|||
<dimen name="standard_margin">16dp</dimen>
|
||||
<dimen name="standard_double_margin">32dp</dimen>
|
||||
<dimen name="standard_half_margin">8dp</dimen>
|
||||
<dimen name="floating_action_button_bottom_margin">100dp</dimen>
|
||||
<dimen name="standard_quarter_margin">4dp</dimen>
|
||||
<dimen name="grid_layout_item_size">10dp</dimen>
|
||||
<dimen name="grid_layout_file_features_margin_end">24dp</dimen>
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
~ SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
|
||||
-->
|
||||
<resources>
|
||||
<string name="bottom_navigation_menu_files_label">All files</string>
|
||||
<string name="bottom_navigation_menu_favorites_label">Favorites</string>
|
||||
<string name="bottom_navigation_menu_assistant_label">Assistant</string>
|
||||
<string name="bottom_navigation_menu_media_label">Media</string>
|
||||
|
||||
|
||||
<string name="about_android">%1$s Android app</string>
|
||||
<string name="about_version">version %1$s</string>
|
||||
<string name="about_version_with_build">version %1$s, build #%2$s</string>
|
||||
|
|
Loading…
Reference in a new issue