В чём ошибка возникает, когда раскоментирую строчку             // toolbarBlurView = viewBinding.toolbarBlurView,
? 2024-11-06 13:27:36.426 14248-14248 AndroidRuntime today.maxi.mobile.dev E FATAL EXCEPTION: main
Process: today.maxi.mobile.dev, PID: 14248
java.lang.IllegalArgumentException: width and height must be > 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:1257)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1224)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1174)
at android.graphics.Bitmap.createBitmap(Bitmap.java:1135)
at androidx.core.graphics.drawable.DrawableKt.toBitmap(Drawable.kt:68)
at androidx.core.graphics.drawable.DrawableKt.toBitmap$default(Drawable.kt:46)
at ru.maxi.mobile.base.ui.MvvmBaseFragment$BackgroundObserver.setupToolbarBlur(MvvmBaseFragment.kt:197)
at ru.maxi.mobile.base.ui.MvvmBaseFragment$BackgroundObserver.onBackgroundReady(MvvmBaseFragment.kt:184)
at ru.maxi.mobile.base.ui.MvvmBaseFragment$BackgroundObserver.access$onBackgroundReady(MvvmBaseFragment.kt:128)
at ru.maxi.mobile.base.ui.MvvmBaseFragment$BackgroundObserver$setBackground$1$invokeSuspend$lambda$2$lambda$1
$$inlined$doOnNextLayout$1.onLayoutChange(View.kt:415)
at android.view.View.layout(View.java:22149)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:334)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:334)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:334)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at com.google.android.material.appbar.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:149)
at com.google.android.material.appbar.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:43)
at com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:2365)
at androidx.coordinatorlayout.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:953)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1857)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1701)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1610)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:334)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1857)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1701)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1610)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:334)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1857)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1701)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1610)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:334)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:978)
at android.view.View.layout(View.java:22131)
at android.view.ViewGroup.layout(ViewGroup.java:6438)package ru.maxi.mobile.feature.achievements.container

import android.os.Bundle
import android.view.View
import by.kirich1409.viewbindingdelegate.viewBinding
import dagger.hilt.android.AndroidEntryPoint
import ru.maxi.mobile.R
import ru.maxi.mobile.base.ui.MvvmBaseFragment
import ru.maxi.mobile.common.utils.android.screenArgs
import ru.maxi.mobile.databinding.FragmentAchievementsContainerBinding
import ru.maxi.mobile.feature.achievements.AchievementsScreens
import ru.maxi.mobile.uikit.utils.lifecycleAwareLazy

/**
 * [Fragment] контейнера экранов достижений
 */
@AndroidEntryPoint
class AchievementsContainerFragment : MvvmBaseFragment(R.layout.fragment_achievements_container) {

    private val screenArgs by screenArgs(AchievementsContainerArgs)

    private val viewBinding by viewBinding(FragmentAchievementsContainerBinding::bind)

    override val analyticsName: String? = null

    private val backgroundObserver by lifecycleAwareLazy {
        BackgroundObserver(
            bgSource = BackgroundSource.FromDrawable(R.drawable.bg_achievements),
            hideToolbar = false,
            // toolbarBlurView = viewBinding.toolbarBlurView,
        )
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        actionBarManager.setTitle(R.string.achievements_screen_title)
        actionBarManager.showBackButton()

        if (screenArgs.achievementId != null) {
            val initialTabScreen = when (screenArgs.initialTab) {
                AchievementsScreens.ContainerTab.IN_PROGRESS_TAB -> "IN_PROGRESS_TAB"
                AchievementsScreens.ContainerTab.RECEIVED_TAB -> "RECEIVED_TAB"
            }
            // viewBinding.text.text = "$initialTabScreen with id = ${screenArgs.achievementId}"
        } else {
            val screen = when (screenArgs.initialTab) {
                AchievementsScreens.ContainerTab.IN_PROGRESS_TAB -> "IN_PROGRESS_TAB"
                AchievementsScreens.ContainerTab.RECEIVED_TAB -> "RECEIVED_TAB"
            }
            // viewBinding.text.text = "$screen"
        }
        backgroundObserver.attachTo(viewLifecycleOwner)


    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:background="@drawable/bg_achievements"
    android:orientation="vertical"
    android:theme="@style/ThemeOverlay.Achievements">

    <FrameLayout
        android:id="@+id/toolbar_blur_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:foreground="@color/advent_calendar_toolbar_tint"
        tools:layout_height="?attr/actionBarSize" />

    <ru.maxi.mobile.uikit.components.toggleGroup.ButtonToggleGroup
        android:id="@+id/tabs_button_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="@dimen/std_margin"
        android:layout_marginTop="@dimen/std_margin"
        android:layout_marginBottom="@dimen/std_half_margin">

        <Button
            android:id="@+id/balance_tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/chips_balance_tab_title" />

        <Button
            android:id="@+id/info_tab"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/chips_info_tab_title" />

    </ru.maxi.mobile.uikit.components.toggleGroup.ButtonToggleGroup>

    <Button
        android:id="@+id/info_dsasa"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="16dp"
        android:text="Активировать промокод" />

    <Button
        android:id="@+id/info_dsa"
        style="?attr/materialButtonOutlinedStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="Закрыть" />


    <!--<androidx.viewpager2.widget.ViewPager2-->
    <!--    android:id="@+id/tabs_container"-->
    <!--    android:layout_width="match_parent"-->
    <!--    android:layout_height="0dp"-->
    <!--    android:layout_weight="1" />-->

    <ru.maxi.mobile.uikit.components.noDataView.NoDataView
        android:id="@+id/no_data_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:theme="@style/ThemeOverlay.Achievements.NoDataView"
        android:visibility="gone"
        app:description="Не удалось получить данные. Попробуйте позже"
        app:image="@drawable/ic_empty_cart"
        app:title="Что-то пошло не так" />


    <ru.maxi.mobile.uikit.components.noConnectionView.NoConnectionView
        android:id="@+id/no_connection_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:theme="@style/ThemeOverlay.Achievements.NoConnectionView"
        android:visibility="gone" />

    <ru.maxi.mobile.uikit.components.loaderWithBackground.LoaderWithBackground
        android:id="@+id/loader_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="140dp"
        android:theme="@style/ThemeOverlay.Achievements.LoaderWithBackground"
        android:visibility="visible" />


</LinearLayout>package ru.maxi.mobile.base.ui

import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.view.View
import android.view.ViewGroup
import androidx.annotation.ContentView
import androidx.annotation.DrawableRes
import androidx.annotation.LayoutRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.doOnLayout
import androidx.core.view.doOnNextLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.withResumed
import com.axmor.maxi.view.main.MainNavigationView
import com.google.android.renderscript.Toolkit
import com.google.firebase.Firebase
import com.google.firebase.crashlytics.crashlytics
import kotlinx.coroutines.launch
import ru.maxi.mobile.app
import ru.maxi.mobile.base.ui.manager.ActionBarManager
import ru.maxi.mobile.base.ui.manager.BlockingLoaderManager
import ru.maxi.mobile.base.ui.manager.BottomBarManager
import ru.maxi.mobile.base.ui.manager.DialogManager
import ru.maxi.mobile.base.ui.manager.KeyboardManager
import ru.maxi.mobile.base.ui.manager.NoOpActionBarManager
import ru.maxi.mobile.base.ui.manager.NoOpDialogManager
import ru.maxi.mobile.base.ui.manager.NoOpKeyboardManager
import ru.maxi.mobile.base.ui.manager.NotificationManager
import ru.maxi.mobile.feature.analytics.model.events.AnalyticsGeneralEvent
import ru.maxi.mobile.uikit.utils.lifecycleAwareLazy

/**
 * Базовый класс для MVVM фрагментов
 */
abstract class MvvmBaseFragment @ContentView constructor(
    @LayoutRes contentLayoutId: Int,
) : Fragment(contentLayoutId) {

    private val baseActivity: BaseActivity?
        get() = (activity as? BaseActivity)

    protected val actionBarManager: ActionBarManager
        get() = baseActivity?.actionBarManager ?: NoOpActionBarManager

    protected val blockingLoaderManager: BlockingLoaderManager by lifecycleAwareLazy {
        baseActivity?.blockingLoaderManager ?: BlockingLoaderManager(view as ViewGroup)
    }

    /** TODO: сделать protected после удаления [MvpBaseFragment] */
    open val bottomBarManager: BottomBarManager?
        get() = (parentFragment as? MvvmBaseFragment)?.bottomBarManager
            ?: (activity as? MainNavigationView)?.bottomBarManager

    protected val dialogManager: DialogManager
        get() = baseActivity?.dialogManager ?: NoOpDialogManager

    /** TODO: сделать protected после удаления [MvpBaseFragment] */
    open val keyboardManager: KeyboardManager
        get() = (parentFragment as? MvvmBaseFragment)?.keyboardManager
            ?: baseActivity?.keyboardManager
            ?: NoOpKeyboardManager

    /** TODO: сделать protected после удаления [MvpBaseFragment] */
    open val notificationManager: NotificationManager by lifecycleAwareLazy {
        object : NotificationManager {
            override val snackbarParentView: View = this@MvvmBaseFragment.requireView()

            override val snackbarAnchorViewId: Int? =
                (parentFragment as? MvvmBaseFragment)?.notificationManager?.snackbarAnchorViewId
        }
    }

    /** Название экрана для отправки в аналитику */
    protected abstract val analyticsName: String?

    override fun onResume() {
        super.onResume()
        sendScreenViewAnalyticsEvent()
    }

    override fun onDestroyView() {
        blockingLoaderManager.isShowing = false
        super.onDestroyView()
    }

    private fun sendScreenViewAnalyticsEvent() {
        val analyticsName = analyticsName ?: return

        try {
            app.appComponent.analyticsUseCase() log AnalyticsGeneralEvent.ScreenView(
                analyticsName,
                this.javaClass.simpleName,
            )
        } catch (exception: Exception) {
            Firebase.crashlytics.recordException(exception)
        }
    }

    /**
     * Источник фонового изображения экрана
     */
    protected sealed class BackgroundSource {

        /**
         * Изображение по ссылке [url]
         */
        data class FromUrl(val url: String) : BackgroundSource()

        /**
         * Изображение из [Drawable] с идентификатором [drawableResId]
         */
        data class FromDrawable(@DrawableRes val drawableResId: Int) : BackgroundSource()
    }

    /**
     * [LifecycleEventObserver] для установки фона экрана и блюра тулбара
     *
     * @param bgSource источник изображения для использования в качестве фона экрана
     * @param hideToolbar флаг скрытия тулбара на время отображения фона
     * @param toolbarBlurView [View] для установки блюра под тулбаром
     */
    protected inner class BackgroundObserver(
        private val bgSource: BackgroundSource,
        private val hideToolbar: Boolean = false,
        private val toolbarBlurView: View? = null,
    ) : DefaultLifecycleObserver {

        /**
         * Запустить отслеживание lifecycle [owner]'а текущим [BackgroundObserver]
         */
        fun attachTo(owner: LifecycleOwner) {
            owner.lifecycle.addObserver(this)
        }

        override fun onStart(owner: LifecycleOwner) {
            when (bgSource) {
                is BackgroundSource.FromDrawable ->
                    AppCompatResources.getDrawable(requireContext(), bgSource.drawableResId)
                        ?.let { setBackground(owner, it) }

                is BackgroundSource.FromUrl -> baseActivity?.loadBackground(bgSource.url) { drawable ->
                    setBackground(owner, drawable)
                }
            }
        }

        override fun onStop(owner: LifecycleOwner) {
            actionBarManager.setLightTheme(true)
            actionBarManager.setTransparency(false)
            actionBarManager.isShowing = true
            baseActivity?.resetBackground()
        }

        override fun onDestroy(owner: LifecycleOwner) {
            owner.lifecycle.removeObserver(this)
        }

        private fun setBackground(owner: LifecycleOwner, drawable: Drawable) {
            owner.lifecycleScope.launch {
                withResumed {
                    baseActivity?.setBackground(drawable)
                    view?.apply {
                        doOnNextLayout { onBackgroundReady() }
                        if (!isInLayout) {
                            requestLayout()
                        }
                    }
                }
            }
        }

        private fun onBackgroundReady() {
            actionBarManager.setLightTheme(false)
            actionBarManager.setTransparency(true)
            if (hideToolbar) {
                actionBarManager.isShowing = false
            } else {
                setupToolbarBlur()
            }
        }

        private fun setupToolbarBlur() {
            val toolbarBlurView = this.toolbarBlurView ?: return
            val background = baseActivity?.getBackground() ?: return

            toolbarBlurView.doOnLayout {
                val blurViewWindowLocation = IntArray(2)
                toolbarBlurView.getLocationInWindow(blurViewWindowLocation)

                var viewBitmap = Bitmap.createBitmap(
                    background.toBitmap(),
                    blurViewWindowLocation[0],
                    blurViewWindowLocation[1],
                    toolbarBlurView.measuredWidth,
                    toolbarBlurView.measuredHeight,
                )

                repeat(5) {
                    viewBitmap = Toolkit.blur(viewBitmap, 25)
                }

                toolbarBlurView.background = BitmapDrawable(resources, viewBitmap)
            }
        }
    }
}