From b4e34acf3181de2cb56568137805624ef0e4e23b Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Mon, 11 Sep 2023 23:10:54 +0530 Subject: [PATCH] [LeakCanary]: OnboardingFragment: Use viewbinding as official way Signed-off-by: Aayush Gupta --- .../view/ui/onboarding/AccentFragment.kt | 73 ++++++------------ .../view/ui/onboarding/AppLinksFragment.kt | 3 +- .../view/ui/onboarding/InstallerFragment.kt | 75 +++++++------------ .../view/ui/onboarding/OnboardingFragment.kt | 3 +- .../view/ui/onboarding/PermissionsFragment.kt | 49 +++++------- .../store/view/ui/onboarding/ThemeFragment.kt | 72 +++++++----------- .../view/ui/onboarding/WelcomeFragment.kt | 45 +++-------- 7 files changed, 105 insertions(+), 215 deletions(-) diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/AccentFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/AccentFragment.kt index 6e7b8e922..150a768f0 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/AccentFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/AccentFragment.kt @@ -24,10 +24,8 @@ import android.animation.AnimatorListenerAdapter import android.graphics.Bitmap import android.graphics.Canvas import android.os.Bundle -import android.view.LayoutInflater import android.view.View import android.view.ViewAnimationUtils -import android.view.ViewGroup import androidx.recyclerview.widget.StaggeredGridLayoutManager import com.aurora.extensions.hide import com.aurora.extensions.isSAndAbove @@ -48,60 +46,31 @@ import java.nio.charset.StandardCharsets import kotlin.math.sqrt -class AccentFragment : BaseFragment() { +class AccentFragment : BaseFragment(R.layout.fragment_onboarding_accent) { - private lateinit var B: FragmentOnboardingAccentBinding + private var _binding: FragmentOnboardingAccentBinding? = null + private val binding get() = _binding!! private var themeId: Int = 0 private var accentId: Int = if (isSAndAbove()) 0 else 1 - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - B = FragmentOnboardingAccentBinding.bind( - inflater.inflate( - R.layout.fragment_onboarding_accent, - container, - false - ) - ) - - return B.root - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + _binding = FragmentOnboardingAccentBinding.bind(view) - themeId = Preferences.getInteger( - requireContext(), - PREFERENCE_THEME_TYPE - ) + themeId = Preferences.getInteger(requireContext(), PREFERENCE_THEME_TYPE) + accentId = Preferences.getInteger(requireContext(), PREFERENCE_THEME_ACCENT) - accentId = Preferences.getInteger( - requireContext(), - PREFERENCE_THEME_ACCENT - ) - - attachRecycler() - - val accentList = loadAccentsFromAssets() - updateController(accentList) - } - - private fun attachRecycler() { - with(B.epoxyRecycler) { + // RecyclerView + with(binding.epoxyRecycler) { setHasFixedSize(true) layoutManager = StaggeredGridLayoutManager(5, StaggeredGridLayoutManager.VERTICAL) } - } - private fun updateController(accentList: List) { - B.epoxyRecycler.withModels { + binding.epoxyRecycler.withModels { setFilterDuplicates(true) - accentList.forEach { + loadAccentsFromAssets().forEach { if (it.id == 0) { if (!isSAndAbove()) return@forEach } @@ -128,25 +97,25 @@ class AccentFragment : BaseFragment() { } private fun animate(view: View) { - if (B.themeSwitchImage.isVisible()) { + if (binding.themeSwitchImage.isVisible()) { return; } try { val pos = IntArray(2) view.getLocationInWindow(pos) - val w: Int = B.root.measuredWidth - val h: Int = B.root.measuredHeight + val w: Int = binding.root.measuredWidth + val h: Int = binding.root.measuredHeight val bitmap = Bitmap.createBitmap( - B.root.measuredWidth, - B.root.measuredHeight, + binding.root.measuredWidth, + binding.root.measuredHeight, Bitmap.Config.ARGB_8888 ) val canvas = Canvas(bitmap) - B.root.draw(canvas) - B.themeSwitchImage.setImageBitmap(bitmap) - B.themeSwitchImage.show() + binding.root.draw(canvas) + binding.themeSwitchImage.setImageBitmap(bitmap) + binding.themeSwitchImage.show() val finalRadius = sqrt( ((w - pos[0]) * (w - pos[0]) + (h - pos[1]) * (h - pos[1])).toDouble() @@ -155,7 +124,7 @@ class AccentFragment : BaseFragment() { ).toFloat() val anim: Animator = ViewAnimationUtils.createCircularReveal( - B.root, + binding.root, pos[0], pos[1], 0f, @@ -166,8 +135,8 @@ class AccentFragment : BaseFragment() { anim.interpolator = CubicBezierInterpolator.EASE_IN_OUT_QUAD anim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { - B.themeSwitchImage.setImageDrawable(null) - B.themeSwitchImage.hide() + binding.themeSwitchImage.setImageDrawable(null) + binding.themeSwitchImage.hide() } }) anim.start() diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/AppLinksFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/AppLinksFragment.kt index 402b334ab..cacab1379 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/AppLinksFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/AppLinksFragment.kt @@ -17,8 +17,7 @@ import com.aurora.store.databinding.FragmentAppLinksBinding class AppLinksFragment : Fragment(R.layout.fragment_app_links) { private var _binding: FragmentAppLinksBinding? = null - private val binding: FragmentAppLinksBinding - get() = _binding!! + private val binding get() = _binding!! private val playStoreDomain = "play.google.com" diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/InstallerFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/InstallerFragment.kt index be7cb0aa2..bb64d1661 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/InstallerFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/InstallerFragment.kt @@ -21,9 +21,7 @@ package com.aurora.store.view.ui.onboarding import android.content.pm.PackageManager import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import androidx.navigation.fragment.findNavController import com.aurora.extensions.isMIUI import com.aurora.extensions.isMiuiOptimizationDisabled @@ -44,15 +42,16 @@ import com.aurora.store.util.save import com.aurora.store.view.epoxy.views.preference.InstallerViewModel_ import com.aurora.store.view.ui.commons.BaseFragment import com.google.gson.reflect.TypeToken -import java.nio.charset.StandardCharsets import rikka.shizuku.Shizuku +import java.nio.charset.StandardCharsets -class InstallerFragment : BaseFragment() { +class InstallerFragment : BaseFragment(R.layout.fragment_onboarding_installer) { - private lateinit var B: FragmentOnboardingInstallerBinding + private var _binding: FragmentOnboardingInstallerBinding? = null + private val binding get() = _binding!! - var installerId: Int = 0 + private var installerId: Int = 0 private var shizukuAlive = false private val shizukuAliveListener = Shizuku.OnBinderReceivedListener { @@ -69,7 +68,7 @@ class InstallerFragment : BaseFragment() { if (result == PackageManager.PERMISSION_GRANTED) { this.installerId = 5 save(PREFERENCE_INSTALLER_ID, 5) - B.epoxyRecycler.requestModelBuild() + binding.epoxyRecycler.requestModelBuild() } else { showDialog( R.string.action_installations, @@ -78,54 +77,16 @@ class InstallerFragment : BaseFragment() { } } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - - if (hasShizuku(requireContext()) && isOAndAbove()) { - Shizuku.addBinderReceivedListenerSticky(shizukuAliveListener) - Shizuku.addBinderDeadListener(shizukuDeadListener) - Shizuku.addRequestPermissionResultListener(shizukuResultListener) - } - - B = FragmentOnboardingInstallerBinding.bind( - inflater.inflate( - R.layout.fragment_onboarding_installer, - container, - false - ) - ) - - return B.root - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + _binding = FragmentOnboardingInstallerBinding.bind(view) - installerId = Preferences.getInteger( - requireContext(), - PREFERENCE_INSTALLER_ID - ) + installerId = Preferences.getInteger(requireContext(), PREFERENCE_INSTALLER_ID) - val installerList = loadInstallersFromAssets() - updateController(installerList) - } - - override fun onDestroy() { - if (hasShizuku(requireContext()) && isOAndAbove()) { - Shizuku.removeBinderReceivedListener(shizukuAliveListener) - Shizuku.removeBinderDeadListener(shizukuDeadListener) - Shizuku.removeRequestPermissionResultListener(shizukuResultListener) - } - super.onDestroy() - } - - private fun updateController(installerList: List) { - B.epoxyRecycler.withModels { + // RecyclerView + binding.epoxyRecycler.withModels { setFilterDuplicates(true) - installerList.forEach { + loadInstallersFromAssets().forEach { add( InstallerViewModel_() .id(it.id) @@ -146,6 +107,20 @@ class InstallerFragment : BaseFragment() { } } + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun onDestroy() { + if (hasShizuku(requireContext()) && isOAndAbove()) { + Shizuku.removeBinderReceivedListener(shizukuAliveListener) + Shizuku.removeBinderDeadListener(shizukuDeadListener) + Shizuku.removeRequestPermissionResultListener(shizukuResultListener) + } + super.onDestroy() + } + private fun save(installerId: Int) { when (installerId) { 0 -> { diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt index e092012c6..ae9408016 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt @@ -54,8 +54,7 @@ import com.google.android.material.tabs.TabLayoutMediator class OnboardingFragment : Fragment(R.layout.fragment_onboarding) { private var _binding: FragmentOnboardingBinding? = null - private val binding: FragmentOnboardingBinding - get() = _binding!! + private val binding get() = _binding!! override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/PermissionsFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/PermissionsFragment.kt index 6951361e2..649bc1d26 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/PermissionsFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/PermissionsFragment.kt @@ -27,9 +27,7 @@ import android.net.Uri import android.os.Bundle import android.os.Environment import android.provider.Settings -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import androidx.activity.result.contract.ActivityResultContracts import androidx.core.app.ActivityCompat import com.aurora.extensions.isOAndAbove @@ -44,57 +42,40 @@ import com.aurora.store.view.epoxy.views.preference.PermissionViewModel_ import com.aurora.store.view.ui.commons.BaseFragment -class PermissionsFragment : BaseFragment() { +class PermissionsFragment : BaseFragment(R.layout.fragment_onboarding_permissions) { - private lateinit var B: FragmentOnboardingPermissionsBinding + private var _binding: FragmentOnboardingPermissionsBinding? = null + private val binding get() = _binding!! private val startForPackageManagerResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (isOAndAbove() && requireContext().packageManager.canRequestPackageInstalls()) { toast(R.string.toast_permission_granted) - B.epoxyRecycler.requestModelBuild() + binding.epoxyRecycler.requestModelBuild() } } private val startForStorageManagerResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (isRAndAbove() && Environment.isExternalStorageManager()) { toast(R.string.toast_permission_granted) - B.epoxyRecycler.requestModelBuild() + binding.epoxyRecycler.requestModelBuild() } } private val startForPermissions = registerForActivityResult(ActivityResultContracts.RequestPermission()) { if (it) { toast(R.string.toast_permission_granted) - B.epoxyRecycler.requestModelBuild() + binding.epoxyRecycler.requestModelBuild() } else { toast(R.string.permissions_denied) } } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - B = FragmentOnboardingPermissionsBinding.bind( - inflater.inflate( - R.layout.fragment_onboarding_permissions, - container, - false - ) - ) - - return B.root - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - updateController() - } - - private fun updateController() { + _binding = FragmentOnboardingPermissionsBinding.bind(view) + // RecyclerView val installerList = mutableListOf( Permission( 2, @@ -131,7 +112,7 @@ class PermissionsFragment : BaseFragment() { ) } - B.epoxyRecycler.withModels { + binding.epoxyRecycler.withModels { val writeExternalStorage = if (!isRAndAbove()) ActivityCompat.checkSelfPermission( requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE @@ -141,7 +122,12 @@ class PermissionsFragment : BaseFragment() { Manifest.permission.POST_NOTIFICATIONS ) == PackageManager.PERMISSION_GRANTED else true val storageManager = if (isRAndAbove()) Environment.isExternalStorageManager() else true - val canInstallPackages = if (isOAndAbove()) requireContext().packageManager.canRequestPackageInstalls() else true + val canInstallPackages = if (isOAndAbove()) { + requireContext().packageManager.canRequestPackageInstalls() + } else { + true + } + setFilterDuplicates(true) installerList.forEach { add( @@ -170,6 +156,11 @@ class PermissionsFragment : BaseFragment() { } } + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + private fun checkStorageAccessPermission() { startForPermissions.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) } diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/ThemeFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/ThemeFragment.kt index 1257e5f1c..09f78f865 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/ThemeFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/ThemeFragment.kt @@ -24,10 +24,8 @@ import android.animation.AnimatorListenerAdapter import android.graphics.Bitmap import android.graphics.Canvas import android.os.Bundle -import android.view.LayoutInflater import android.view.View import android.view.ViewAnimationUtils -import android.view.ViewGroup import com.aurora.extensions.hide import com.aurora.extensions.isVisible import com.aurora.extensions.show @@ -46,50 +44,25 @@ import java.nio.charset.StandardCharsets import kotlin.math.sqrt -class ThemeFragment : BaseFragment() { +class ThemeFragment : BaseFragment(R.layout.fragment_onboarding_theme) { - private lateinit var B: FragmentOnboardingThemeBinding + private var _binding: FragmentOnboardingThemeBinding? = null + private val binding get() = _binding!! private var themeId: Int = 0 private var accentId: Int = 0 - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - B = FragmentOnboardingThemeBinding.bind( - inflater.inflate( - R.layout.fragment_onboarding_theme, - container, - false - ) - ) - - return B.root - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + _binding = FragmentOnboardingThemeBinding.bind(view) - themeId = Preferences.getInteger( - requireContext(), - PREFERENCE_THEME_TYPE - ) + themeId = Preferences.getInteger(requireContext(), PREFERENCE_THEME_TYPE) + accentId = Preferences.getInteger(requireContext(), PREFERENCE_THEME_ACCENT) - accentId = Preferences.getInteger( - requireContext(), - PREFERENCE_THEME_ACCENT - ) - - val themeList = loadThemesFromAssets() - updateController(themeList) - } - - private fun updateController(themeList: List) { - B.epoxyRecycler.withModels { + // RecyclerView + binding.epoxyRecycler.withModels { setFilterDuplicates(true) - themeList.forEach { + loadThemesFromAssets().forEach { add( ThemeViewModel_() .id(it.id) @@ -108,31 +81,36 @@ class ThemeFragment : BaseFragment() { } } + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + private fun update(themeId: Int) { requireActivity().recreate() save(PREFERENCE_THEME_TYPE, themeId) } private fun animate(view: View) { - if (B.themeSwitchImage.isVisible()) { + if (binding.themeSwitchImage.isVisible()) { return; } try { val pos = IntArray(2) view.getLocationInWindow(pos) - val w: Int = B.root.measuredWidth - val h: Int = B.root.measuredHeight + val w: Int = binding.root.measuredWidth + val h: Int = binding.root.measuredHeight val bitmap = Bitmap.createBitmap( - B.root.measuredWidth, - B.root.measuredHeight, + binding.root.measuredWidth, + binding.root.measuredHeight, Bitmap.Config.ARGB_8888 ) val canvas = Canvas(bitmap) - B.root.draw(canvas) - B.themeSwitchImage.setImageBitmap(bitmap) - B.themeSwitchImage.show() + binding.root.draw(canvas) + binding.themeSwitchImage.setImageBitmap(bitmap) + binding.themeSwitchImage.show() val finalRadius = sqrt( ((w - pos[0]) * (w - pos[0]) + (h - pos[1]) * (h - pos[1])).toDouble() @@ -141,7 +119,7 @@ class ThemeFragment : BaseFragment() { ).toFloat() val anim: Animator = ViewAnimationUtils.createCircularReveal( - B.root, + binding.root, pos[0], pos[1], 0f, @@ -152,8 +130,8 @@ class ThemeFragment : BaseFragment() { anim.interpolator = CubicBezierInterpolator.EASE_IN_OUT_QUAD anim.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { - B.themeSwitchImage.setImageDrawable(null) - B.themeSwitchImage.hide() + binding.themeSwitchImage.setImageDrawable(null) + binding.themeSwitchImage.hide() } }) anim.start() diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/WelcomeFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/WelcomeFragment.kt index 7d8a076ab..fcec89cae 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/WelcomeFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/WelcomeFragment.kt @@ -20,9 +20,7 @@ package com.aurora.store.view.ui.onboarding import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import com.aurora.extensions.browse import com.aurora.store.R import com.aurora.store.data.model.Dash @@ -32,18 +30,12 @@ import com.aurora.store.view.ui.commons.BaseFragment import com.google.gson.reflect.TypeToken import java.nio.charset.StandardCharsets -class WelcomeFragment : BaseFragment() { +class WelcomeFragment : BaseFragment(R.layout.fragment_onboarding_welcome) { - private lateinit var B: FragmentOnboardingWelcomeBinding + private var _binding: FragmentOnboardingWelcomeBinding? = null + private val binding get() = _binding!! companion object { - @JvmStatic - fun newInstance(): WelcomeFragment { - return WelcomeFragment().apply { - - } - } - val icMap: MutableMap = mutableMapOf( "ic_faq" to R.drawable.ic_faq, "ic_code" to R.drawable.ic_code, @@ -53,32 +45,14 @@ class WelcomeFragment : BaseFragment() { ) } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - B = FragmentOnboardingWelcomeBinding.bind( - inflater.inflate( - R.layout.fragment_onboarding_welcome, - container, - false - ) - ) - - return B.root - } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val dashList = loadDashFromAssets() - updateController(dashList) - } + _binding = FragmentOnboardingWelcomeBinding.bind(view) - private fun updateController(dashList: List) { - B.epoxyRecycler.withModels { + // RecyclerView + binding.epoxyRecycler.withModels { setFilterDuplicates(true) - dashList.forEach { + loadDashFromAssets().forEach { add( DashViewModel_() .id(it.id) @@ -101,4 +75,9 @@ class WelcomeFragment : BaseFragment() { object : TypeToken?>() {}.type ) } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } } \ No newline at end of file