Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Predictive Back] Add a new Predictive Back Samples folder. #94

Merged
merged 2 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ androidx-activity = "androidx.activity:activity:1.7.2"
androidx-core = "androidx.core:core-ktx:1.10.1"
androidx-appcompat = "androidx.appcompat:appcompat:1.6.1"
androidx-exifinterface = "androidx.exifinterface:exifinterface:1.3.6"
androidx-fragment = "androidx.fragment:fragment-ktx:1.6.0"
# Fragment 1.7.0 alpha is for predictive back to work with Fragment transitions
androidx-fragment = "androidx.fragment:fragment-ktx:1.7.0-alpha04"
androidx-activity-compose = "androidx.activity:activity-compose:1.7.2"
androidx-navigation-fragment = { module = "androidx.navigation:navigation-fragment", version.ref = "androidx-navigation" }
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation" }
Expand Down
1 change: 1 addition & 0 deletions samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Select images/videos in a privacy-friendly way using the photo picker
Basic usage of Picture-in-Picture mode showcasing a stopwatch
- [Picture in Picture (PiP) - Video playback](user-interface/picture-in-picture/src/main/java/com/example/android/pip/PiPMovieActivity.kt):
Basic usage of Picture-in-Picture mode showcasing video playback
- [Predictive Back](user-interface/predictiveback/src/main/java/com/example/platform/ui/predictiveback/PBHostingActivity.kt):
- [Quick Settings](user-interface/quicksettings/src/main/java/com/example/platform/ui/quicksettings/QuickSettings.kt):
Add your custom tile to the Quick Settings.
- [Scan with BLE Intent](connectivity/bluetooth/ble/src/main/java/com/example/platform/connectivity/bluetooth/ble/BLEScanIntentSample.kt):
Expand Down
9 changes: 9 additions & 0 deletions samples/user-interface/predictiveback/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# PredictiveBackSample samples

Shows different types of predictive back animations, including:

+ back-to-home
+ cross-activity
+ (coming soon) cross-fragment
+ (coming soon) androidx-transitions
+ (coming soon) custom cross-activity
36 changes: 36 additions & 0 deletions samples/user-interface/predictiveback/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


plugins {
id("com.example.platform.sample")
alias(libs.plugins.kotlin.android)
}

android {
namespace = "com.example.platform.ui.predictiveback"
buildFeatures {
viewBinding = true
}
}

dependencies {
implementation(libs.androidx.appcompat)
implementation(libs.androidx.constraintlayout)
implementation(libs.mdc)
// Add samples specific dependencies
}
12 changes: 12 additions & 0 deletions samples/user-interface/predictiveback/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>
<activity
android:name=".PBHostingActivity"
android:exported="false"
android:label="@string/title_activity_predictive_back_sample"
android:theme="@style/Theme.PlatformSamples" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.platform.ui.predictiveback

class PBAnimation(val title: String, val description: String)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it data class for just class holders

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

acknowledged


val pbAnimations = mutableListOf<PBAnimation>().apply {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's better to use the constructor directly

mutableListOf(PBAnimation(...), PBAnimation(..), ...)

And if this list is not modified then defnie the variable type to be the immutable version List

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

acknowledged

add(
PBAnimation(
"Enable System Animations",
"The system animations are back-to-home and default cross-activity. To see them: (1) Enable gesture navigation. (2) In Android 14, enable the Predictive Back Developer Option."
)
)
add(
PBAnimation(
"Back-to-Home",
"To see the back-to-home animation, go to the root activity and swipe back from either the left or right edge to exit the app."
)
)
add(
PBAnimation(
"Default Cross-Activity",
"To see the default cross-activity animation in this app, on this screen swipe back from either the left or right edge."
)
)
add(
PBAnimation(
"Cross-Fragment",
"Animation example coming soon."
)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.platform.ui.predictiveback

import androidx.recyclerview.widget.RecyclerView
import com.example.platform.ui.predictiveback.databinding.ListItemAnimationBinding

class PBHolder(
private val binding: ListItemAnimationBinding
) : RecyclerView.ViewHolder(binding.root) {
fun bind(animation: PBAnimation) {
binding.animationTitle.text = animation.title
binding.animationDescription.text = animation.description
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.platform.ui.predictiveback

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.platform.ui.predictiveback.databinding.HostingActivityBinding
import com.google.android.catalog.framework.annotations.Sample

@Sample(
name="Predictive Back Sample",
description="Shows Predictive Back animations."
)
class PBHostingActivity : AppCompatActivity() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the activity needed to demostrate the sample? If not maybe you could just use the fragment directly. This way you can skip the theme and all the boilerplate that comes with activity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the activity is needed. From the sample page folks can swipe back to see the cross-activity animation. I'm also hoping to add a custom cross-activity animation.


private lateinit var binding: HostingActivityBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding = HostingActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.platform.ui.predictiveback

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.platform.ui.predictiveback.databinding.ListItemAnimationBinding

class PBListAdapter(private val animations: List<PBAnimation>) : RecyclerView.Adapter<PBHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PBHolder {
val inflater = LayoutInflater.from(parent.context)
val binding = ListItemAnimationBinding.inflate(inflater, parent, false)
return PBHolder(binding)
}

override fun getItemCount() = animations.size

override fun onBindViewHolder(holder: PBHolder, position: Int) {
val animation = animations[position]
holder.bind(animation)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.platform.ui.predictiveback

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.platform.ui.predictiveback.databinding.FragmentAnimationListBinding

class PBListFragment : Fragment() {

private var _binding: FragmentAnimationListBinding? = null
private val binding
get() = checkNotNull(_binding){
"Cannot access binding in PBListFragment because it is null."
}

private val pbViewModel: PBViewModel by viewModels()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentAnimationListBinding.inflate(inflater, container, false)
binding.pbRecyclerView.layoutManager = LinearLayoutManager(context)

val animations = pbViewModel.animations
val adapter = PBListAdapter(animations)
binding.pbRecyclerView.adapter = adapter

return binding.root
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.platform.ui.predictiveback

import androidx.lifecycle.ViewModel

class PBViewModel: ViewModel() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for this I would skip the VM. Just use the variable directly. It's simple and clear

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

acknowledged


val animations = pbAnimations

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_margin="16dp"
android:gravity="center"
android:text="@string/predictive_back_sample_first_activity_header"
android:textSize="24sp"
android:textAppearance="?attr/textAppearanceTitleMedium" />

<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/pb_recycler_view" />

</LinearLayout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_container"
android:name="com.example.platform.ui.predictiveback.PBListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PBHostingActivity" />
Loading