@@ -13,7 +13,6 @@ import android.content.Intent
1313import android.content.res.Configuration
1414import android.graphics.Color
1515import android.graphics.Rect
16- import android.os.Build
1716import android.os.Bundle
1817import android.os.Handler
1918import android.os.Looper
@@ -22,13 +21,15 @@ import android.text.TextWatcher
2221import android.view.MenuItem
2322import android.view.MotionEvent
2423import android.view.View
25- import android.view.ViewGroup.MarginLayoutParams
2624import android.view.WindowManager
2725import android.view.animation.DecelerateInterpolator
2826import android.view.inputmethod.EditorInfo
2927import android.view.inputmethod.InputMethodManager
3028import android.widget.EditText
3129import android.widget.Toast
30+ import androidx.core.view.ViewCompat
31+ import androidx.core.view.WindowInsetsAnimationCompat
32+ import androidx.core.view.WindowInsetsCompat
3233import androidx.recyclerview.widget.LinearLayoutManager
3334import androidx.recyclerview.widget.RecyclerView
3435import androidx.room.Room
@@ -61,6 +62,7 @@ import com.fox2code.mmm.utils.io.net.Http.Companion.hasWebView
6162import com.fox2code.mmm.utils.room.ReposListDatabase
6263import com.google.android.material.bottomnavigation.BottomNavigationView
6364import com.google.android.material.dialog.MaterialAlertDialogBuilder
65+ import com.google.android.material.elevation.SurfaceColors
6466import com.google.android.material.floatingactionbutton.FloatingActionButton
6567import com.google.android.material.progressindicator.LinearProgressIndicator
6668import com.google.android.material.textfield.TextInputEditText
@@ -70,6 +72,7 @@ import java.sql.Timestamp
7072
7173
7274class MainActivity : FoxActivity (), OnRefreshListener, OverScrollHelper {
75+ private lateinit var bottomNavigationView: BottomNavigationView
7376 val moduleViewListBuilder: ModuleViewListBuilder = ModuleViewListBuilder (this )
7477 val moduleViewListBuilderOnline: ModuleViewListBuilder = ModuleViewListBuilder (this )
7578 var progressIndicator: LinearProgressIndicator ? = null
@@ -96,6 +99,12 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
9699
97100 override fun onResume () {
98101 onMainActivityResume(this )
102+ // check that installed or online is selected depending on which recyclerview is visible
103+ if (moduleList!! .visibility == View .VISIBLE ) {
104+ bottomNavigationView.selectedItemId = R .id.installed_menu_item
105+ } else {
106+ bottomNavigationView.selectedItemId = R .id.online_menu_item
107+ }
99108 super .onResume()
100109 }
101110
@@ -159,22 +168,8 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
159168 }
160169 setContentView(R .layout.activity_main)
161170 this .setTitle(R .string.app_name_v2)
162- // set window flags to ignore status bar
163- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .R ) {
164- // ignore status bar space
165- this .window.setDecorFitsSystemWindows(false )
166- } else {
167- this .window.setFlags(
168- WindowManager .LayoutParams .FLAG_LAYOUT_NO_LIMITS ,
169- WindowManager .LayoutParams .FLAG_LAYOUT_NO_LIMITS
170- )
171- }
172- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .P ) {
173- val layoutParams = this .window.attributes
174- layoutParams.layoutInDisplayCutoutMode = // Support cutout in Android 9
175- WindowManager .LayoutParams .LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
176- this .window.attributes = layoutParams
177- }
171+ // set navigation bar color based on surfacecolors
172+ window.navigationBarColor = SurfaceColors .SURFACE_2 .getColor(this )
178173 progressIndicator = findViewById(R .id.progress_bar)
179174 swipeRefreshLayout = findViewById(R .id.swipe_refresh)
180175 val swipeRefreshLayout = swipeRefreshLayout!!
@@ -185,6 +180,45 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
185180 moduleListOnline = findViewById(R .id.module_list_online)
186181 searchTextInputEditText = findViewById(R .id.search_input)
187182 val textInputEditText = searchTextInputEditText!!
183+ val view = findViewById<View >(R .id.root_container)
184+ var startBottom = 0f
185+ var endBottom = 0f
186+ ViewCompat .setWindowInsetsAnimationCallback(
187+ view,
188+ object : WindowInsetsAnimationCompat .Callback (DISPATCH_MODE_STOP ) {
189+ // Override methods…
190+ override fun onProgress (
191+ insets : WindowInsetsCompat ,
192+ runningAnimations : MutableList <WindowInsetsAnimationCompat >
193+ ): WindowInsetsCompat {
194+ // Find an IME animation.
195+ val imeAnimation = runningAnimations.find {
196+ it.typeMask and WindowInsetsCompat .Type .ime() != 0
197+ } ? : return insets
198+ Timber .d(" IME animation progress: %f" , imeAnimation.interpolatedFraction)
199+ // smoothly offset the view based on the interpolated fraction of the IME animation.
200+ view.translationY =
201+ (startBottom - endBottom) * (1 - imeAnimation.interpolatedFraction)
202+
203+ return insets
204+ }
205+
206+ override fun onStart (
207+ animation : WindowInsetsAnimationCompat ,
208+ bounds : WindowInsetsAnimationCompat .BoundsCompat
209+ ): WindowInsetsAnimationCompat .BoundsCompat {
210+ // Record the position of the view after the IME transition.
211+ endBottom = view.bottom.toFloat()
212+ Timber .d(" IME animation start: %f" , endBottom)
213+ return bounds
214+ }
215+
216+ override fun onPrepare (animation : WindowInsetsAnimationCompat ) {
217+ startBottom = view.bottom.toFloat()
218+ Timber .d(" IME animation prepare: %f" , startBottom)
219+ }
220+ }
221+ )
188222 // set search view listeners for text edit. filter the appropriate list based on visibility. do the filtering as the user types not just on submit as a background task
189223 textInputEditText.addTextChangedListener(object : TextWatcher {
190224 override fun beforeTextChanged (
@@ -314,20 +348,26 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
314348 // get background color and elevation of reboot fab
315349 moduleList.addOnScrollListener(object : RecyclerView .OnScrollListener () {
316350 override fun onScrollStateChanged (recyclerView : RecyclerView , newState : Int ) {
317- if (newState != RecyclerView .SCROLL_STATE_IDLE ) textInputEditText.clearFocus()
318- // hide search view and reboot fab when scrolling - we have to account for padding, corners, and shadows
351+ if (newState != RecyclerView .SCROLL_STATE_IDLE ) {
352+ textInputEditText.clearFocus()
353+ }
354+ // hide reboot fab on scroll by fading it out
319355 if (newState == RecyclerView .SCROLL_STATE_DRAGGING ) {
320- rebootFab.animate().translationY(rebootFab.height.toFloat() + 2 * 8 + 2 * 2 )
321- .setInterpolator(DecelerateInterpolator (2f )).start()
356+ rebootFab.animate().alpha(0f ).setDuration(300 )
357+ .setListener(object : AnimatorListenerAdapter () {
358+ override fun onAnimationEnd (animation : Animator ) {
359+ rebootFab.visibility = View .GONE
360+ }
361+ })
322362 }
323363 }
324364
325365 override fun onScrolled (recyclerView : RecyclerView , dx : Int , dy : Int ) {
326366 super .onScrolled(recyclerView, dx, dy)
327367 // if the user scrolled up, show the search bar
328368 if (dy < 0 ) {
329- rebootFab.animate().translationY( 0f ).setInterpolator( DecelerateInterpolator ( 2f ))
330- .start( )
369+ rebootFab.visibility = View . VISIBLE
370+ rebootFab.animate().alpha( 1f ).setDuration( 300 ).setListener( null )
331371 }
332372 }
333373 })
@@ -337,16 +377,23 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
337377 if (newState != RecyclerView .SCROLL_STATE_IDLE ) textInputEditText.clearFocus()
338378 // hide search view when scrolling
339379 if (newState == RecyclerView .SCROLL_STATE_DRAGGING ) {
340- rebootFab.animate().translationY(rebootFab.height.toFloat() + 2 * 8 + 2 * 2 )
341- .setInterpolator(DecelerateInterpolator (2f )).start()
380+ textInputEditText.clearFocus()
381+ // animate reboot fab out
382+ rebootFab.animate().alpha(0f ).setDuration(300 )
383+ .setListener(object : AnimatorListenerAdapter () {
384+ override fun onAnimationEnd (animation : Animator ) {
385+ rebootFab.visibility = View .GONE
386+ }
387+ })
342388 }
343389 }
344390
345391 override fun onScrolled (recyclerView : RecyclerView , dx : Int , dy : Int ) {
346392 super .onScrolled(recyclerView, dx, dy)
347- // if the user scrolled up, show the search bar
393+ // if the user scrolled up, show the reboot fab
348394 if (dy < 0 ) {
349- rebootFab.animate().translationY(0f )
395+ rebootFab.visibility = View .VISIBLE
396+ rebootFab.animate().alpha(1f ).setDuration(300 ).setListener(null )
350397 }
351398 }
352399 })
@@ -357,13 +404,19 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
357404 this .updateScreenInsets(this .resources.configuration)
358405
359406 // on the bottom nav, there's a settings item. open the settings activity when it's clicked.
360- val bottomNavigationView = findViewById< BottomNavigationView > (R .id.bottom_navigation)
407+ bottomNavigationView = findViewById(R .id.bottom_navigation)
361408 bottomNavigationView.setOnItemSelectedListener { item: MenuItem ->
362409 when (item.itemId) {
363410 R .id.settings_menu_item -> {
364411 TrackHelper .track().event(" view_list" , " settings" )
365412 .with (MainApplication .INSTANCE !! .tracker)
366- startActivity(Intent (this @MainActivity, SettingsActivity ::class .java))
413+ // start settings activity so that when user presses back, they go back to main activity and on api34 they see a preview of the main activity. tell settings activity current active tab so that it can be selected when user goes back to main activity
414+ val intent = Intent (this @MainActivity, SettingsActivity ::class .java)
415+ when (bottomNavigationView.selectedItemId) {
416+ R .id.online_menu_item -> intent.putExtra(" activeTab" , " online" )
417+ R .id.installed_menu_item -> intent.putExtra(" activeTab" , " installed" )
418+ }
419+ startActivity(intent)
367420 }
368421
369422 R .id.online_menu_item -> {
@@ -420,24 +473,6 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
420473 } else {
421474 bottomNavigationView.selectedItemId = R .id.installed_menu_item
422475 }
423- // update the padding of blur_frame to match the new bottom nav height
424- val blurFrame = findViewById<View >(R .id.blur_frame)
425- blurFrame.post {
426- blurFrame.setPadding(
427- blurFrame.paddingLeft,
428- blurFrame.paddingTop,
429- blurFrame.paddingRight,
430- bottomNavigationView.height
431- )
432- }
433- // for some reason, root_container has a margin at the top. remove it.
434- val rootContainer = findViewById<View >(R .id.root_container)
435- rootContainer.post {
436- val params = rootContainer.layoutParams as MarginLayoutParams
437- params.topMargin = 0
438- rootContainer.layoutParams = params
439- rootContainer.y = 0f
440- }
441476 // reset update module and update module count in main application
442477 MainApplication .INSTANCE !! .resetUpdateModule()
443478 tryGetMagiskPathAsync(object : InstallerInitializer .Callback {
@@ -646,8 +681,6 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
646681 // this.actionBarBlur.invalidate();
647682 overScrollInsetTop = statusBarHeight
648683 overScrollInsetBottom = bottomInset
649- // set root_container to have zero padding
650- findViewById<View >(R .id.root_container).setPadding(0 , statusBarHeight, 0 , 0 )
651684 }
652685
653686 private fun updateBlurState () {
@@ -913,6 +946,15 @@ class MainActivity : FoxActivity(), OnRefreshListener, OverScrollHelper {
913946 return super .dispatchTouchEvent(event)
914947 }
915948
949+ override fun setOnBackPressedCallback (onBackPressedCallback : OnBackPressedCallback ? ) {
950+ // if is on online list, go back to installed list
951+ if (moduleListOnline!! .visibility == View .VISIBLE ) {
952+ bottomNavigationView.selectedItemId = R .id.installed_menu_item
953+ } else {
954+ super .setOnBackPressedCallback(onBackPressedCallback)
955+ }
956+ }
957+
916958 companion object {
917959 fun getFoxActivity (activity : FoxActivity ): FoxActivity {
918960 return activity
0 commit comments