Skip to content
This repository has been archived by the owner on Dec 9, 2024. It is now read-only.

Motion: Support predictive back in Container transform #102

Merged
merged 3 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions Motion/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ apply plugin: 'kotlin-android'
apply plugin: "androidx.navigation.safeargs.kotlin"

android {
compileSdk 31
compileSdk 34

defaultConfig {
applicationId 'com.example.android.motion'
minSdk 14
targetSdk 31
namespace 'com.example.android.motion'
minSdk 19
targetSdk 34
versionCode 1
versionName '1.0'
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
Expand All @@ -51,33 +51,33 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.fragment:fragment-ktx:1.4.1'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.fragment:fragment-ktx:1.6.2'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.transition:transition:1.4.1'
implementation 'androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.recyclerview:recyclerview:1.3.2'

implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

def lifecycle_version = '2.4.1'
def lifecycle_version = '2.7.0'
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"

implementation 'androidx.paging:paging-runtime-ktx:3.1.1'
implementation 'androidx.paging:paging-runtime-ktx:3.2.1'

implementation 'com.google.android.material:material:1.6.0'
implementation 'com.google.android.material:material:1.11.0'

implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"

implementation 'com.github.bumptech.glide:glide:4.10.0'
implementation 'com.github.bumptech.glide:glide:4.15.1'

testImplementation 'junit:junit:4.13.2'
testImplementation 'com.google.truth:truth:1.1.3'

testImplementation 'androidx.test:core:1.4.0'
androidTestImplementation 'androidx.test.ext:truth:1.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
testImplementation 'androidx.test:core:1.5.0'
androidTestImplementation 'androidx.test.ext:truth:1.5.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
4 changes: 3 additions & 1 deletion Motion/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@

<application
android:allowBackup="false"
android:enableOnBackInvokedCallback="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Motion"
tools:ignore="GoogleAppIndexingWarning">
tools:ignore="GoogleAppIndexingWarning"
tools:targetApi="34">

<activity
android:name=".MainActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,21 @@ import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.BackEventCompat
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import androidx.core.view.ViewGroupCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.animation.PathInterpolatorCompat
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.example.android.motion.R
import com.google.android.material.appbar.CollapsingToolbarLayout
Expand All @@ -44,6 +48,8 @@ class CheeseArticleFragment : Fragment() {

companion object {
const val TRANSITION_NAME_BACKGROUND = "background"

private val GestureInterpolator = PathInterpolatorCompat.create(0f, 0f, 0f, 1f)
}

private val args: CheeseArticleFragmentArgs by navArgs()
Expand Down Expand Up @@ -111,5 +117,55 @@ class CheeseArticleFragment : Fragment() {
toolbar.setNavigationOnClickListener { v ->
v.findNavController().popBackStack()
}

val predictiveBackMargin = resources.getDimensionPixelSize(R.dimen.predictive_back_margin)
var initialTouchY = -1f
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// This invokes the sharedElementReturnTransition, which is
// MaterialContainerTransform.
findNavController().popBackStack()
}

override fun handleOnBackProgressed(backEvent: BackEventCompat) {
val progress = GestureInterpolator.getInterpolation(backEvent.progress)
if (initialTouchY < 0f) {
initialTouchY = backEvent.touchY
}
val progressY = GestureInterpolator.getInterpolation(
(backEvent.touchY - initialTouchY) / background.height
)

// See the motion spec about the calculations below.
// https://developer.android.com/design/ui/mobile/guides/patterns/predictive-back#motion-specs

// Shift horizontally.
val maxTranslationX = (background.width / 20) - predictiveBackMargin
background.translationX = progress * maxTranslationX *
(if (backEvent.swipeEdge == BackEventCompat.EDGE_LEFT) 1 else -1)

// Shift vertically.
val maxTranslationY = (background.height / 20) - predictiveBackMargin
background.translationY = progressY * maxTranslationY

// Scale down from 100% to 90%.
val scale = 1f - (0.1f * progress)
background.scaleX = scale
background.scaleY = scale
}

override fun handleOnBackCancelled() {
initialTouchY = -1f
background.run {
translationX = 0f
translationY = 0f
scaleX = 1f
scaleY = 1f
}
}
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class MirrorView @JvmOverloads constructor(
setWillNotDraw(value == null)
}

override fun onDraw(canvas: Canvas?) {
override fun onDraw(canvas: Canvas) {
_substance?.draw(canvas)
}
}
1 change: 1 addition & 0 deletions Motion/app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@
<dimen name="pick_up_elevation">8dp</dimen>
<dimen name="fab_elevation">6dp</dimen>
<dimen name="icon_size">24dp</dimen>
<dimen name="predictive_back_margin">8dp</dimen>
</resources>
6 changes: 3 additions & 3 deletions Motion/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
*/

buildscript {
ext.kotlin_version = '1.6.21'
ext.navigation_version = '2.4.2'
ext.kotlin_version = '1.9.22'
ext.navigation_version = '2.7.7'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath 'com.android.tools.build:gradle:8.2.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigation_version"
}
Expand Down
4 changes: 2 additions & 2 deletions Motion/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Wed Oct 28 16:25:10 JST 2020
#Fri Feb 16 14:02:28 JST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
Loading