diff --git a/app/src/main/java/com/tunjid/androidx/MainActivity.kt b/app/src/main/java/com/tunjid/androidx/MainActivity.kt index 982a06aa..aa336bf6 100644 --- a/app/src/main/java/com/tunjid/androidx/MainActivity.kt +++ b/app/src/main/java/com/tunjid/androidx/MainActivity.kt @@ -1,11 +1,15 @@ package com.tunjid.androidx +import android.app.NotificationChannel +import android.app.NotificationManager import android.content.Intent +import android.os.Build import android.os.Bundle import android.view.View import android.view.WindowInsets import androidx.activity.addCallback import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope import com.tunjid.androidx.core.delegates.activityIntent import com.tunjid.androidx.databinding.ActivityMainBinding import com.tunjid.androidx.navigation.MultiStackNavigator @@ -31,7 +35,7 @@ class MainActivity : AppCompatActivity(), GlobalUiHost, Navigator.Controller { stackCount = tabs.size, containerId = R.id.content_container, backStackType = MultiStackNavigator.BackStackType.Unlimited, - rootFunction = RouteFragment.Companion::newInstance + rootFunction = RouteFragment.Companion::newInstance, ) public override fun onCreate(savedInstanceState: Bundle?) { @@ -54,6 +58,7 @@ class MainActivity : AppCompatActivity(), GlobalUiHost, Navigator.Controller { setOnNavigationItemSelectedListener { navigator.show(tabs.indexOf(it.itemId)).let { true } } setOnNavigationItemReselectedListener { navigator.activeNavigator.clear() } } + createNotificationChannel() } override fun onNewIntent(intent: Intent?) { @@ -63,4 +68,26 @@ class MainActivity : AppCompatActivity(), GlobalUiHost, Navigator.Controller { ?.takeIf { it >= 0 } ?.let(navigator::show) } + + override fun onResume() { + super.onResume() + if (intent?.getBooleanExtra("stress_test", false) == true) { + navigator.performConsecutively(lifecycleScope) { + clearAll() + push(RouteFragment.newInstance(tabIndex = 0, launchStressTest = true)) + } + } + } + + private fun createNotificationChannel() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel( + getString(R.string.notification_channel_id), + getString(R.string.notification_channel_name), + NotificationManager.IMPORTANCE_LOW + ).apply { + getSystemService(NotificationManager::class.java).createNotificationChannel(this) + } + } + } } diff --git a/app/src/main/java/com/tunjid/androidx/tabnav/navigator/IndependentStacksFragment.kt b/app/src/main/java/com/tunjid/androidx/tabnav/navigator/IndependentStacksFragment.kt index edcc68e7..65e41d41 100644 --- a/app/src/main/java/com/tunjid/androidx/tabnav/navigator/IndependentStacksFragment.kt +++ b/app/src/main/java/com/tunjid/androidx/tabnav/navigator/IndependentStacksFragment.kt @@ -35,7 +35,7 @@ import com.tunjid.androidx.uidrivers.InsetFlags import com.tunjid.androidx.uidrivers.crossFade import com.tunjid.androidx.uidrivers.uiState import com.tunjid.androidx.uidrivers.updatePartial -import java.util.* +import java.util.ArrayDeque class IndependentStacksFragment : Fragment(R.layout.fragment_independent_stack) { @@ -100,7 +100,9 @@ class IndependentStacksFragment : Fragment(R.layout.fragment_independent_stack) } private fun navigatorFor(id: Int) = navigators.getOrPut(id) { - val stackNavigator by childStackNavigationController(id) + val stackNavigator by childStackNavigationController( + containerId = id, + ) stackNavigator.apply { transactionModifier = { crossFade() } } } diff --git a/app/src/main/java/com/tunjid/androidx/tabnav/navigator/MultipleStacksFragment.kt b/app/src/main/java/com/tunjid/androidx/tabnav/navigator/MultipleStacksFragment.kt index b8ea1df1..e5f74c8a 100644 --- a/app/src/main/java/com/tunjid/androidx/tabnav/navigator/MultipleStacksFragment.kt +++ b/app/src/main/java/com/tunjid/androidx/tabnav/navigator/MultipleStacksFragment.kt @@ -54,11 +54,12 @@ class MultipleStacksFragment : Fragment(R.layout.fragment_multiple_stack) { private val navigator by activityNavigatorController() internal val innerNavigator: MultiStackNavigator by childMultiStackNavigationController( - DESTINATIONS.size, - R.id.inner_container - ) { index -> - MultipleStackChildFragment.newInstance(getChildName(index), 1) - } + stackCount = DESTINATIONS.size, + containerId = R.id.inner_container, + rootFunction = { index -> + MultipleStackChildFragment.newInstance(getChildName(index), 1) + } + ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/tunjid/androidx/tabnav/routing/RouteFragment.kt b/app/src/main/java/com/tunjid/androidx/tabnav/routing/RouteFragment.kt index 4b57cd9a..a008ec3d 100644 --- a/app/src/main/java/com/tunjid/androidx/tabnav/routing/RouteFragment.kt +++ b/app/src/main/java/com/tunjid/androidx/tabnav/routing/RouteFragment.kt @@ -1,6 +1,10 @@ package com.tunjid.androidx.tabnav.routing import android.annotation.SuppressLint +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Intent import android.graphics.Color import android.graphics.PorterDuff import android.os.Bundle @@ -10,6 +14,8 @@ import android.view.ViewGroup import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES +import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels @@ -18,6 +24,7 @@ import androidx.transition.AutoTransition import androidx.transition.TransitionManager import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.tunjid.androidx.MainActivity import com.tunjid.androidx.R import com.tunjid.androidx.core.content.colorAt import com.tunjid.androidx.core.content.themeColorAt @@ -46,6 +53,7 @@ class RouteFragment : Fragment(R.layout.fragment_route) { private val navigator by activityNavigatorController() private var tabIndex: Int by fragmentArgs() + private var launchStressTest: Boolean by fragmentArgs() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -83,6 +91,10 @@ class RouteFragment : Fragment(R.layout.fragment_route) { ) OverScrollDecoratorHelper.setUpOverScroll(this, OverScrollDecoratorHelper.ORIENTATION_VERTICAL) } + + if (launchStressTest) { + stressTest() + } } private fun onMenuItemSelected(item: MenuItem) = when (item.itemId) { @@ -97,6 +109,7 @@ class RouteFragment : Fragment(R.layout.fragment_route) { .show() .let { } R.id.menu_reset -> navigator.clearAll() + R.id.menu_stress_test_intent -> createStressTestIntent() else -> requireActivity().onOptionsItemSelected(item).let { } } @@ -111,6 +124,31 @@ class RouteFragment : Fragment(R.layout.fragment_route) { push(route.fragment(isTopLevel = true)) } + private fun createStressTestIntent() { + val context = requireContext() + val intent = Intent(context, MainActivity::class.java).apply { + putExtra("stress_test", true) + } + + val pendingIntent = PendingIntent.getActivity( + context, + 0, + intent, + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + ) + + val notification = NotificationCompat.Builder(context, getString(R.string.notification_channel_id)) + .setSmallIcon(R.drawable.ic_android_24dp) + .setCategory(Notification.CATEGORY_MESSAGE) + .setContentTitle(getString(R.string.stress_test_intent_title)) + .setContentText(getString(R.string.stress_test_intent_message)) + .setContentIntent(pendingIntent) + .setAutoCancel(true) + .build() + + ContextCompat.getSystemService(context, NotificationManager::class.java)?.notify(0, notification) + } + private fun stressTest() = navigator.performConsecutively(requireActivity().lifecycleScope) { val nav = navigator @@ -138,7 +176,13 @@ class RouteFragment : Fragment(R.layout.fragment_route) { } companion object { - fun newInstance(tabIndex: Int): RouteFragment = RouteFragment().apply { this.tabIndex = tabIndex } + fun newInstance( + tabIndex: Int, + launchStressTest: Boolean = false, + ): RouteFragment = RouteFragment().apply { + this.tabIndex = tabIndex + this.launchStressTest = launchStressTest + } } } diff --git a/app/src/main/res/menu/menu_route.xml b/app/src/main/res/menu/menu_route.xml index 21895673..b88c1ab0 100644 --- a/app/src/main/res/menu/menu_route.xml +++ b/app/src/main/res/menu/menu_route.xml @@ -10,6 +10,10 @@ android:icon="@drawable/ic_baseline_fire_24" android:title="@string/menu_stress_test" app:showAsAction="ifRoom" /> + Reset Navigation Toggle theme Stress Test + Stress Test Intent Scan Stop Refresh @@ -148,4 +149,9 @@ I am inevitable I a survivor + + android_extensions + Android Extensions + Navigation Stress Test Intent + Enable Don\'t Keep Activities in Developer Options and open this