Add material fab transition

pull/178/head
Zakhar Timoshenko 4 years ago
parent 86d8ff3c68
commit afd8200540

@ -6,6 +6,7 @@ import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup.MarginLayoutParams import android.view.ViewGroup.MarginLayoutParams
import android.view.Window
import androidx.activity.result.ActivityResultCallback import androidx.activity.result.ActivityResultCallback
import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
@ -24,6 +25,7 @@ import com.google.android.material.appbar.AppBarLayout.LayoutParams.*
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.navigation.NavigationView import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get import org.koin.android.ext.android.get
@ -84,6 +86,11 @@ class MainActivity :
get() = binding.appbar get() = binding.appbar
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
setExitSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementsUseOverlay = false
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(ActivityMainBinding.inflate(layoutInflater)) setContentView(ActivityMainBinding.inflate(layoutInflater))
navHeaderBinding = NavigationHeaderBinding.inflate(layoutInflater) navHeaderBinding = NavigationHeaderBinding.inflate(layoutInflater)
@ -319,8 +326,20 @@ class MainActivity :
} }
private fun onOpenReader(manga: Manga) { private fun onOpenReader(manga: Manga) {
val options = ActivityOptions.makeScaleUpAnimation(binding.fab, 0, 0, binding.fab.width, binding.fab.height) apply {
startActivity(ReaderActivity.newIntent(this, manga), options?.toBundle()) val intent = ReaderActivity.newIntent(this, manga)
val options = ActivityOptions.makeSceneTransitionAnimation(
this,
binding.fab,
ReaderActivity.SHARED_ELEMENT_NAME
)
startActivity(
intent.apply {
putExtra(ReaderActivity.EXTRA_IS_TRANSITION, true)
},
options.toBundle()
)
}
} }
private fun onError(e: Throwable) { private fun onError(e: Throwable) {
@ -388,6 +407,7 @@ class MainActivity :
private fun setPrimaryFragment(fragment: Fragment) { private fun setPrimaryFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.fragment_fade_in, R.anim.fragment_fade_out)
.replace(R.id.container, fragment, TAG_PRIMARY) .replace(R.id.container, fragment, TAG_PRIMARY)
.commit() .commit()
adjustFabVisibility(topFragment = fragment) adjustFabVisibility(topFragment = fragment)

@ -19,6 +19,8 @@ import androidx.transition.TransitionManager
import androidx.transition.TransitionSet import androidx.transition.TransitionSet
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.transition.platform.MaterialContainerTransform
import com.google.android.material.transition.platform.MaterialContainerTransformSharedElementCallback
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@ -79,6 +81,21 @@ class ReaderActivity :
private val hideUiRunnable = Runnable { setUiIsVisible(false) } private val hideUiRunnable = Runnable { setUiIsVisible(false) }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
// Setup shared element transitions
if (intent.extras?.getBoolean(EXTRA_IS_TRANSITION) == true) {
window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
findViewById<View>(android.R.id.content)?.let { contentView ->
contentView.transitionName = SHARED_ELEMENT_NAME
setEnterSharedElementCallback(MaterialContainerTransformSharedElementCallback())
window.sharedElementEnterTransition = buildContainerTransform(true)
window.sharedElementReturnTransition = buildContainerTransform(false)
// Postpone custom transition until manga ready
postponeEnterTransition()
}
}
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(ActivityReaderBinding.inflate(layoutInflater)) setContentView(ActivityReaderBinding.inflate(layoutInflater))
readerManager = ReaderManager(supportFragmentManager, R.id.container) readerManager = ReaderManager(supportFragmentManager, R.id.container)
@ -113,6 +130,12 @@ class ReaderActivity :
} }
} }
private fun buildContainerTransform(entering: Boolean): MaterialContainerTransform {
return MaterialContainerTransform(this, entering).apply {
addTarget(android.R.id.content)
}
}
private fun onInitReader(mode: ReaderMode) { private fun onInitReader(mode: ReaderMode) {
if (readerManager.currentMode != mode) { if (readerManager.currentMode != mode) {
readerManager.replace(mode) readerManager.replace(mode)
@ -129,6 +152,7 @@ class ReaderActivity :
if (binding.appbarTop.isVisible) { if (binding.appbarTop.isVisible) {
lifecycle.postDelayed(hideUiRunnable, TimeUnit.SECONDS.toMillis(1)) lifecycle.postDelayed(hideUiRunnable, TimeUnit.SECONDS.toMillis(1))
} }
startPostponedEnterTransition()
} }
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
@ -393,6 +417,8 @@ class ReaderActivity :
companion object { companion object {
const val SHARED_ELEMENT_NAME = "reader_shared_element_root"
const val EXTRA_IS_TRANSITION = "${BuildConfig.APPLICATION_ID}.READER_IS_TRANSITION"
const val ACTION_MANGA_READ = "${BuildConfig.APPLICATION_ID}.action.READ_MANGA" const val ACTION_MANGA_READ = "${BuildConfig.APPLICATION_ID}.action.READ_MANGA"
private const val EXTRA_STATE = "state" private const val EXTRA_STATE = "state"
private const val EXTRA_BRANCH = "branch" private const val EXTRA_BRANCH = "branch"

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="210"
android:fromAlpha="0.0"
android:toAlpha="1.0" />

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="90"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
Loading…
Cancel
Save