Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.nextcloud.client.systembars

import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import android.widget.FrameLayout
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import com.nextcloud.client.onboarding.FirstRunActivity
import com.nmc.android.ui.LauncherActivity
import com.owncloud.android.R
import com.owncloud.android.authentication.AuthenticatorActivity
import com.owncloud.android.ui.activity.DrawerActivity
import com.owncloud.android.utils.theme.ViewThemeUtils
import dynamiccolor.MaterialDynamicColors
import javax.inject.Provider

class SystemBarBackgroundCallbacks(private val viewThemeUtilsProvider: Provider<ViewThemeUtils>) :
ActivityLifecycleCallbacks {

companion object {
private val dynamicColor = MaterialDynamicColors()
private val excludedActivities = listOf(
LauncherActivity::class,
AuthenticatorActivity::class,
FirstRunActivity::class
)

private fun isExcluded(activity: Activity): Boolean =
excludedActivities.any { it.isInstance(activity) }

@JvmStatic
@Suppress("ReturnCount")
fun apply(activity: Activity, viewThemeUtils: ViewThemeUtils) {
if (isExcluded(activity)) return

val decorView = activity.window?.decorView as? FrameLayout ?: return
val actionBarColor = dynamicColor.surface().getArgb(viewThemeUtils.getScheme(activity))
val statusBarColor = statusBarColor(activity, actionBarColor)

val existing = decorView.foreground as? SystemBarsBackgroundDrawable
if (existing != null) {
existing.setColors(statusBarColor, actionBarColor)
return
}

decorView.foreground = SystemBarsBackgroundDrawable(decorView, statusBarColor, actionBarColor)
}

@ColorInt
private fun statusBarColor(activity: Activity, @ColorInt actionBarColor: Int): Int {
if (activity is DrawerActivity && activity.isToolbarStyleSearch) {
return ContextCompat.getColor(activity, R.color.bg_default)
}

return actionBarColor
}
}

override fun onActivityStarted(activity: Activity) {
apply(activity, viewThemeUtilsProvider.get())
}

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) = Unit

override fun onActivityResumed(activity: Activity) = Unit

override fun onActivityPaused(activity: Activity) = Unit

override fun onActivityStopped(activity: Activity) = Unit

override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit

override fun onActivityDestroyed(activity: Activity) = Unit
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.nextcloud.client.systembars

import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.PixelFormat
import android.graphics.drawable.Drawable
import android.view.View
import androidx.annotation.ColorInt
import androidx.core.graphics.Insets
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat

class SystemBarsBackgroundDrawable(
private val decorView: View,
@ColorInt statusBarColor: Int,
@ColorInt navigationBarColor: Int
) : Drawable() {

private val statusBarPaint = Paint().apply { color = statusBarColor }
private val navigationBarPaint = Paint().apply { color = navigationBarColor }

fun setColors(@ColorInt statusBarColor: Int, @ColorInt navigationBarColor: Int) {
if (statusBarPaint.color == statusBarColor && navigationBarPaint.color == navigationBarColor) {
return
}
statusBarPaint.color = statusBarColor
navigationBarPaint.color = navigationBarColor
invalidateSelf()
}

override fun draw(canvas: Canvas) {
val insets = ViewCompat.getRootWindowInsets(decorView) ?: return
drawStatusBar(canvas, insets.getInsets(WindowInsetsCompat.Type.statusBars()))
drawNavigationBar(canvas, insets.getInsets(WindowInsetsCompat.Type.navigationBars()))
}

private fun drawStatusBar(canvas: Canvas, insets: Insets) {
if (insets.top == 0) {
return
}
canvas.drawRect(left, top, right, top + insets.top, statusBarPaint)
}

private fun drawNavigationBar(canvas: Canvas, insets: Insets) {
if (insets.bottom > 0) {
canvas.drawRect(left, bottom - insets.bottom, right, bottom, navigationBarPaint)
}
if (insets.left > 0) {
canvas.drawRect(left, top, left + insets.left, bottom, navigationBarPaint)
}
if (insets.right > 0) {
canvas.drawRect(right - insets.right, top, right, bottom, navigationBarPaint)
}
}

private val left: Float get() = bounds.left.toFloat()
private val top: Float get() = bounds.top.toFloat()
private val right: Float get() = bounds.right.toFloat()
private val bottom: Float get() = bounds.bottom.toFloat()

override fun setAlpha(alpha: Int) {
statusBarPaint.alpha = alpha
navigationBarPaint.alpha = alpha
}

override fun setColorFilter(colorFilter: ColorFilter?) {
statusBarPaint.colorFilter = colorFilter
navigationBarPaint.colorFilter = colorFilter
}

@Deprecated("Deprecated in Java")
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
}
2 changes: 2 additions & 0 deletions app/src/main/java/com/owncloud/android/MainApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import com.nextcloud.client.preferences.AppPreferences;
import com.nextcloud.client.preferences.AppPreferencesImpl;
import com.nextcloud.client.preferences.DarkMode;
import com.nextcloud.client.systembars.SystemBarBackgroundCallbacks;
import com.nextcloud.ui.composeActivity.ComposeProcessTextAlias;
import com.nextcloud.utils.extensions.ContextExtensionsKt;
import com.nextcloud.utils.mdm.MDMConfig;
Expand Down Expand Up @@ -292,6 +293,7 @@ public void onCreate() {
insertConscrypt();

registerActivityLifecycleCallbacks(new ActivityInjector());
registerActivityLifecycleCallbacks(new SystemBarBackgroundCallbacks(viewThemeUtilsProvider));

//update the app restart count when app is launched by the user
inAppReviewHelper.resetAndIncrementAppRestartCounter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import com.nextcloud.client.onboarding.FirstRunActivity;
import com.nextcloud.client.player.media3.PlaybackModel;
import com.nextcloud.client.preferences.AppPreferences;
import com.nextcloud.client.systembars.SystemBarBackgroundCallbacks;
import com.nextcloud.client.utils.IntentUtil;
import com.nextcloud.common.NextcloudClient;
import com.nextcloud.ui.ChooseAccountDialogFragment;
Expand Down Expand Up @@ -316,6 +317,7 @@ public void highlightNavigationViewItem(int menuItemId) {
NavigationViewExtensionsKt.highlightNavigationView(drawerNavigationView,
bottomNavigationView,
menuItemId);
SystemBarBackgroundCallbacks.apply(this, viewThemeUtils);
Log_OC.d(TAG, "New menu item is: " + menuItemId);
}

Expand Down
Loading