### Activity Setup for Predictive Back Custom Animations
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
This code initializes the activity and replaces the initial fragment. Use setEnterTransition, setExitTransition, etc., where possible.
```kotlin
// PBSetCustomAnimationsActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
"..."
supportFragmentManager.commit {
replace(R.id.fragment_container, PBSetCustomAnimationsFirstFragment())
}
}
```
--------------------------------
### Clone Connectivity Samples Repository
Source: https://github.com/android/platform-samples/blob/main/samples/connectivity/UwbRanging/README.md
Use this Git command to clone the repository containing the Android UWB sample project. Ensure you have Git installed.
```bash
git clone git@github.com:android/connectivity-samples.git
```
--------------------------------
### MotionLayout with CoordinatorLayout Integration (1)
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Shows how MotionLayout can be integrated with CoordinatorLayout for complex scrolling and animation effects. This example focuses on a specific interaction pattern.
```xml
```
```xml
```
--------------------------------
### Shared Element Fragment Transition Setup
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
Initiates a shared element transition between fragments. Ensure fragment and transition dependencies are updated for predictive back gesture compatibility.
```kotlin
binding.sharedElementCrossFragment.setOnClickListener {
findNavController().navigate(
R.id.show_PBSharedElementTransitionFragment,
null,
null,
FragmentNavigatorExtras(it to "second_card")
)
}
```
--------------------------------
### MotionLayout with ImageFilterView Animation (Variant)
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Another example of animating an ImageFilterView with MotionLayout, showcasing different filter properties or keyframe configurations.
```xml
```
```xml
```
--------------------------------
### Audio Loop Source Utility
Source: https://github.com/android/platform-samples/blob/main/samples/connectivity/audio/README.md
A simple utility class demonstrating how to loop audio from an input source to an output source using AudioTrack and AudioRecord. Ensure proper audio buffer handling and thread management for real-time performance.
```kotlin
package com.example.platform.connectivity.audio
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.AudioTrack
import android.media.MediaRecorder
import java.util.concurrent.atomic.AtomicBoolean
class AudioLoopSource {
private var audioRecord: AudioRecord? = null
private var audioTrack: AudioTrack? = null
private val isLooping = AtomicBoolean(false)
fun startLooping(bufferSize: Int) {
if (isLooping.compareAndSet(false, true)) {
try {
// Initialize AudioRecord
audioRecord = AudioRecord(
MediaRecorder.AudioSource.MIC,
SAMPLE_RATE,
CHANNEL_CONFIG,
AUDIO_FORMAT,
bufferSize
)
// Initialize AudioTrack
audioTrack = AudioTrack(
AudioManager.STREAM_MUSIC,
SAMPLE_RATE,
CHANNEL_CONFIG,
AUDIO_FORMAT,
bufferSize,
AudioTrack.MODE_STREAM
)
audioRecord?.startRecording()
audioTrack?.play()
// Start the loop thread
Thread(audioLoopRunnable).start()
} catch (e: Exception) {
stopLooping()
e.printStackTrace()
}
}
}
fun stopLooping() {
if (isLooping.compareAndSet(true, false)) {
audioRecord?.stop()
audioTrack?.stop()
audioRecord?.release()
audioTrack?.release()
audioRecord = null
audioTrack = null
}
}
private val audioLoopRunnable = Runnable {
val buffer = ShortArray(BUFFER_SIZE)
while (isLooping.get()) {
val readResult = audioRecord?.read(buffer, 0, BUFFER_SIZE) ?: 0
if (readResult > 0) {
audioTrack?.write(buffer, 0, readResult) ?: 0
}
}
}
companion object {
private const val SAMPLE_RATE = 44100
private const val CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO or AudioFormat.CHANNEL_OUT_MONO
private const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT
private const val BUFFER_SIZE = 1024 // Example buffer size
}
}
```
--------------------------------
### Basic Drag and Drop with Views
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/draganddrop/README.md
Demonstrates basic drag-and-drop implementation using `onLongClickListener` and implementing the `DragListener` callback in Android Views.
```kotlin
package com.example.platform.ui.draganddrop
import android.content.ClipData
import android.content.ClipDescription.MIMETYPE_TEXT_PLAIN
import android.os.Build
import android.os.Bundle
import android.view.DragAndDropPermissions
import android.view.DragEvent
import android.view.View
import android.view.View.DragShadowBuilder
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.draganddrop.DragAndDropManagerCompat
import androidx.core.view.draganddrop.DropHelper
class DragAndDropWithViews : AppCompatActivity() {
private lateinit var textView1: TextView
private lateinit var textView2: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_drag_and_drop_with_views)
textView1 = findViewById(R.id.text_view_1)
textView2 = findViewById(R.id.text_view_2)
// Set touch listener for drag
textView1.setOnLongClickListener {
// Create ClipData for the drag item
val clipData = ClipData("text", arrayOf(MIMETYPE_TEXT_PLAIN), ClipData.Item(it.tag as CharSequence))
// Start the drag and drop operation
it.startDragAndDrop(
clipData,
DragShadowBuilder(it),
it,
0
)
true
}
// Set drag listener for drop target
textView2.setOnDragListener { view, dragEvent ->
when (dragEvent.action) {
DragAndDropManagerCompat.ACTION_DRAG_STARTED -> {
// Indicates that a drag operation has started.
true
}
DragAndDropManagerCompat.ACTION_DRAG_ENTERED -> {
// Indicates that a drag shadow has entered the bounds of a view.
view.alpha = 0.5f
true
}
DragAndDropManagerCompat.ACTION_DRAG_LOCATION -> {
// Indicates that a drag shadow is moving within the bounds of a view.
true
}
DragAndDropManagerCompat.ACTION_DRAG_EXITED -> {
// Indicates that a drag shadow has exited the bounds of a view.
view.alpha = 1.0f
true
}
DragAndDropManagerCompat.ACTION_DROP -> {
// Indicates that a drag shadow has been dropped within the bounds of a view.
val item = dragEvent.clipData.getItemAt(0)
val draggedData = item.text.toString()
(view as TextView).text = draggedData
view.alpha = 1.0f
true
}
DragAndDropManagerCompat.ACTION_DRAG_ENDED -> {
// Indicates that a drag operation has ended.
view.alpha = 1.0f
true
}
else -> {
false
}
}
}
}
}
```
--------------------------------
### Audio Manager Communication Sample
Source: https://github.com/android/platform-samples/blob/main/samples/connectivity/audio/README.md
Shows how to use the audio manager to manage the communication device, particularly useful during VoIP calls. Requires appropriate Android permissions.
```kotlin
package com.example.platform.connectivity.audio
import android.content.Context
import android.media.AudioManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class AudioCommsSample : AppCompatActivity() {
private lateinit var audioManager: AudioManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
}
override fun onResume() {
super.onResume()
// Example: Set to speakerphone mode
audioManager.isSpeakerphoneOn = true
}
override fun onPause() {
super.onPause()
// Example: Restore default behavior (e.g., turn off speakerphone)
audioManager.isSpeakerphoneOn = false
}
}
```
--------------------------------
### Basic MotionLayout Animation
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Demonstrates a basic animation using MotionLayout. This snippet is suitable for simple transitions between two states.
```xml
```
```xml
```
--------------------------------
### Accepting Rich Media Content
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/draganddrop/README.md
Showcases handling rich media content using the `RichContentReceiver` API, which supports drag-and-drop, keyboard, and clipboard operations.
```kotlin
package com.example.platform.ui.draganddrop
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ContentInfoCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.draganddrop.DropHelper
class DragAndDropRichContentReceiverFragment : AppCompatActivity() {
private lateinit var richContentReceiverView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_drag_and_drop_rich_content_receiver)
richContentReceiverView = findViewById(R.id.rich_content_receiver_view)
// Set up the RichContentReceiver
ViewCompat.setOnReceiveContentListener(richContentReceiverView) { view, payload ->
Log.d("RichContentReceiver", "Received content")
// Check if the payload contains text
val text = payload.getText(view.context)
if (text != null) {
(view as TextView).text = text
// Return the payload to indicate it was handled
return@setOnReceiveContentListener payload
}
// Handle other types of content if necessary (images, etc.)
// For this example, we only handle text.
null // Return null if the content is not handled
}
}
}
```
--------------------------------
### Basic MotionLayout Animation (No Auto Complete)
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Illustrates a basic MotionLayout animation where the animation does not automatically complete on swipe. Use this when manual control over animation completion is desired.
```xml
```
```xml
```
--------------------------------
### Reacting to IME Visibility Changes with WindowInsetsAnimationCompat
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/window-insets/README.md
Implement a WindowInsetsAnimationCompat.Callback to automatically adjust UI elements when the IME appears or disappears. This provides a smooth user experience by making views move in unison with the IME. Graceful degradation is handled for API levels below 30.
```java
public class TranslateDeferringInsetsAnimationCallback
: WindowInsetsAnimationCompat.Callback {
private val view: View
private var startTop: Int = 0
private var endTop: Int = 0
constructor(view: View) : super(DISPATCH_MODE_CONTINUE_ON_SUBపంచ)
{
this.view = view
}
override fun onPrepare(controller: WindowInsetsAnimationControllerCompat?) {
super.onPrepare(controller)
val insets = view.rootWindowInsets
startTop = insets.getInsets(WindowInsetsCompat.Type.ime()).top
}
override fun onProgress(
insets: WindowInsetsCompat,
runner: WindowInsetsAnimationCompat.InterpolatorRunner
): WindowInsetsCompat {
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
val fraction = runner.fraction
val currentTop = startTop + ((imeInsets.top - startTop) * fraction).roundToInt()
view.updateLayoutParams {
topMargin = currentTop
}
return insets
}
override fun onEnd(controller: WindowInsetsAnimationControllerCompat?) {
super.onEnd(controller)
}
override fun onCancel(controller: WindowInsetsAnimationControllerCompat?) {
super.onCancel(controller)
}
}
```
--------------------------------
### MotionLayout with CoordinatorLayout Integration (2)
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Presents another scenario of integrating MotionLayout with CoordinatorLayout, likely demonstrating different header behaviors or scroll effects.
```xml
```
```xml
```
--------------------------------
### License Information
Source: https://github.com/android/platform-samples/blob/main/samples/connectivity/bluetooth/ble/README.md
This is the Apache 2.0 license text.
```text
Copyright 2022 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.
```
--------------------------------
### App Widgets License
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/appwidgets/README.md
Contains the Apache License, Version 2.0, governing the use of the App Widgets sample code.
```text
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.
```
--------------------------------
### MotionLayout Keyframe Cycle Animation
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Demonstrates creating a cyclical animation using keyframes in MotionLayout. This is useful for animations that repeat or loop.
```xml
```
```xml
```
--------------------------------
### Linkify Text with LinkifyCompat
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/text/README.md
Utilize `LinkifyCompat` to automatically create clickable links for email addresses, phone numbers, and URLs within TextViews. Custom patterns can also be defined using regular expressions.
```java
LinkifyCompat.addLinks(textView, LinkifyCompat.ALL);
```
--------------------------------
### MotionLayout Keyframe Position Animation
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Demonstrates animating an object's position along a path using keyframes in MotionLayout. This allows for precise control over the animation's trajectory.
```xml
```
```xml
```
--------------------------------
### Custom Progress API Animation Handling
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
Implements custom back progress animations using the Progress API. Handles swipe edge, progress, and scaling for visual feedback during predictive back gestures.
```kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
"..."
val windowWidth = requireActivity().windowManager.currentWindowMetrics.bounds.width()
val maxXShift = windowWidth / 20
val predictiveBackCallback = object: OnBackPressedCallback(enabled=false) {
override fun handleOnBackProgressed(backEvent: BackEventCompat) {
when (backEvent.swipeEdge) {
BackEventCompat.EDGE_LEFT ->
binding.box.translationX = backEvent.progress * maxXShift
BackEventCompat.EDGE_RIGHT ->
binding.box.translationX = -(backEvent.progress * maxXShift)
}
binding.box.scaleX = 1F - (0.1F * backEvent.progress)
binding.box.scaleY = 1F - (0.1F * backEvent.progress)
}
override fun handleOnBackPressed() {
// your back handling logic
}
override fun handleOnBackCancelled() {
binding.box.scaleX = 1F
binding.box.scaleY = 1F
binding.box.translationX = 0F
}
}
requireActivity().onBackPressedDispatcher.addCallback(
this.viewLifecycleOwner,
predictiveBackCallback
)
}
```
--------------------------------
### Cross-fragment Animation with MaterialSharedAxis
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
Implement cross-fragment animations using MaterialSharedAxis. Configure exit/reenter transitions for the exiting fragment and enter/return transitions for the entering fragment. This transition requires a change in fragment visibility or addition/removal to trigger.
```kotlin
// FragmentA.kt
override fun onCreateView(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, /* forward= */ true)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, /* forward= */ false)
}
```
```kotlin
// FragmentB.kt
override fun onCreateView(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, /* forward= */ true)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, /* forward= */ false)
}
```
--------------------------------
### Navigation Component Fragment Transitions
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
Defines default enter, exit, pop enter, and pop exit animations for fragment transitions using the navigation component.
```xml
```
--------------------------------
### MotionLayout Keyframe Interpolation Animation
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Illustrates animating an object's properties with different interpolation curves using keyframes in MotionLayout. This allows for varied animation pacing.
```xml
```
```xml
```
--------------------------------
### License Information
Source: https://github.com/android/platform-samples/blob/main/samples/privacy/permissions/README.md
This section provides the Apache License 2.0 details for the code.
```plaintext
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.
```
--------------------------------
### MotionLayout with ImageFilterView Animation
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Demonstrates animating an ImageFilterView using MotionLayout. This allows for applying various image filters and animating their properties.
```xml
```
```xml
```
--------------------------------
### Drag and Drop Across Apps
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/draganddrop/README.md
Demonstrates drag-and-drop functionality across different applications in multi-window mode on Android.
```kotlin
package com.example.platform.ui.draganddrop
import android.content.ClipData
import android.content.ClipDescription.MIMETYPE_TEXT_PLAIN
import android.os.Build
import android.os.Bundle
import android.view.DragEvent
import android.view.View
import android.view.View.DragShadowBuilder
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.draganddrop.DragAndDropManagerCompat
class DragAndDropMultiWindow : AppCompatActivity() {
private lateinit var textView1: TextView
private lateinit var textView2: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_drag_and_drop_multi_window)
textView1 = findViewById(R.id.text_view_1)
textView2 = findViewById(R.id.text_view_2)
// Set touch listener for drag
textView1.setOnLongClickListener {
val clipData = ClipData("text", arrayOf(MIMETYPE_TEXT_PLAIN), ClipData.Item(it.tag as CharSequence))
it.startDragAndDrop(
clipData,
DragShadowBuilder(it),
it,
0
)
true
}
// Set drag listener for drop target
textView2.setOnDragListener { view, dragEvent ->
when (dragEvent.action) {
DragAndDropManagerCompat.ACTION_DRAG_STARTED -> {
true
}
DragAndDropManagerCompat.ACTION_DRAG_ENTERED -> {
view.alpha = 0.5f
true
}
DragAndDropManagerCompat.ACTION_DRAG_LOCATION -> {
true
}
DragAndDropManagerCompat.ACTION_DRAG_EXITED -> {
view.alpha = 1.0f
true
}
DragAndDropManagerCompat.ACTION_DROP -> {
val item = dragEvent.clipData.getItemAt(0)
val draggedData = item.text.toString()
(view as TextView).text = draggedData
view.alpha = 1.0f
true
}
DragAndDropManagerCompat.ACTION_DRAG_ENDED -> {
view.alpha = 1.0f
true
}
else -> {
false
}
}
}
}
}
```
--------------------------------
### Fragment Transaction with Custom Animations
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
This fragment handles the click event to trigger a fragment transaction with custom enter, exit, popEnter, and popExit animations using setCustomAnimations. Ensure reordering is allowed and add to the back stack.
```kotlin
// PBSetCustomAnimationsFirstFragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
):
View {
_binding = FragmentSetCustomAnimationsBinding
.inflate(inflater, container, false)
binding.box.setOnClickListener {
parentFragmentManager.commit {
setCustomAnimations(
android.R.animator.fade_in, // enter
android.R.animator.fade_out, // exit
android.R.animator.fade_in, // popEnter
android.R.animator.fade_out) // popExit
replace(R.id.fragment_container,PBSetCustomAnimationsSecondFragment())
setReorderingAllowed(true)
addToBackStack(null)
}
}
return binding.root
}
```
--------------------------------
### Custom AndroidX Transition for Predictive Back
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
Define a custom transition set for predictive back gestures. This involves creating an OnBackPressedCallback to control the transition based on back event progress and completion. Ensure the transition is applied to a container view.
```kotlin
class MyFragment : Fragment() {
val transitionSet = TransitionSet().apply {
addTransition(Fade(Fade.MODE_OUT))
addTransition(ChangeBounds())
addTransition(Fade(Fade.MODE_IN))
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val callback = object : OnBackPressedCallback(enabled = false) {
var controller: TransitionSeekController? = null
override fun handleOnBackStarted(backEvent: BackEvent) {
// Create the transition
controller = TransitionManager.controlDelayedTransition(
// textContainer is a FrameLayout containing the shortText and longText TextViews
binding.textContainer,
transitionSet
)
changeTextVisibility(ShowText.SHORT)
}
override fun handleOnBackProgressed(backEvent: BackEvent) {
// Play the transition as the user swipes back
if (controller?.isReady == true) {
controller?.currentFraction = backEvent.progress
}
}
override fun handleOnBackPressed() {
// Finish playing the transition when the user commits back
controller?.animateToEnd()
this.isEnabled = false
}
override fun handleOnBackCancelled() {
// If the user cancels the back gesture, reset the state
transition(ShowText.LONG)
}
}
binding.shortText.setOnClickListener {
transition(ShowText.LONG)
callback.isEnabled = true
}
this.requireActivity().onBackPressedDispatcher.addCallback(callback)
}
private fun transition(showText: ShowText) {
TransitionManager.beginDelayedTransition(
binding.textContainer,
transitionSet
)
changeTextVisibility(showText)
}
enum class ShowText { SHORT, LONG }
private fun changeTextVisibility(showText: ShowText) {
when (showText) {
ShowText.SHORT -> {
binding.shortText.isVisible = true
binding.longText.isVisible = false
}
ShowText.LONG -> {
binding.shortText.isVisible = false
binding.longText.isVisible = true
}
}
}
}
```
--------------------------------
### Shared Element Fragment Transition Configuration
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
Configures enter and shared element enter transitions for a fragment. Specifying `enterTransition` is necessary alongside `sharedElementEnterTransition` to enable predictive back gesture.
```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = AutoTransition()
sharedElementEnterTransition = AutoTransition()
}
```
--------------------------------
### License Information
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/draganddrop/README.md
Contains the Apache License, Version 2.0, governing the use of the software.
```plaintext
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.
```
--------------------------------
### Drag and Drop in Jetpack Compose
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/draganddrop/README.md
Showcases drag-and-drop implementation within a Jetpack Compose UI.
```kotlin
package com.example.platform.ui.draganddrop
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.core.view.draganddrop.DragAndDropManagerCompat
import androidx.core.view.draganddrop.DropHelper
class DragAndDropUsingCompose : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DragAndDropScreen()
}
}
}
@Composable
fun DragAndDropScreen() {
var droppedText by remember { mutableStateOf("Drop here") }
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Box(
modifier = Modifier
.size(100.dp)
.background(Color.Blue)
.dragSource( // Make this Box a drag source
clipData = {
androidx.core.view.draganddrop.ClipData(
"text",
arrayOf(androidx.core.view.draganddrop.ClipDescription.MIMETYPE_TEXT_PLAIN),
androidx.core.view.draganddrop.ClipData.Item("Dragged Item")
)
},
shadowBuilder = { androidx.core.view.draganddrop.DragShadowBuilder(this@Box) },
flags = 0
)
)
Spacer(modifier = Modifier.height(32.dp))
Box(
modifier = Modifier
.size(150.dp)
.background(Color.Gray)
.dropTarget { event -> // Make this Box a drop target
if (event.action == DragAndDropManagerCompat.ACTION_DROP) {
val item = event.clipData.getItemAt(0)
droppedText = item.text.toString()
Log.d("DragDropCompose", "Dropped: ${droppedText}")
true
} else {
false
}
},
contentAlignment = Alignment.Center
) {
Text(text = droppedText)
}
}
}
```
--------------------------------
### Controlling IME Visibility with WindowInsetsAnimationControllerCompat
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/window-insets/README.md
Utilize WindowInsetsAnimationControllerCompat to animate the IME on and off screen as part of a scroll gesture. This is particularly useful for custom scrolling views that over-scroll, allowing the IME to be controlled directly by the user's interaction. Requires AndroidX Core 1.5.0+ and functions on devices with Android 11 or newer.
```java
class InsetsAnimationLinearLayout : LinearLayout {
private var controller: WindowInsetsAnimationControllerCompat? = null
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
init {
setOnApplyWindowInsetsListener { v, insets ->
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
val insetTop = imeInsets.top
val fraction = if (insetTop == 0) 0f else 1f
if (controller == null) {
controller = WindowInsetsControllerCompat(v.rootWindowInsets, v)
}
controller?.control(WindowInsetsCompat.Type.ime(), fraction)
// Consume the IME insets to prevent them from being passed further down the view hierarchy
v.rootWindowInsets = insets.consume(WindowInsetsCompat.Type.ime())
insets.consumeDisplayCutout() // Consume other insets if necessary
}
}
}
```
```java
class InsetsAnimationTouchListener(private val controller: WindowInsetsAnimationControllerCompat) : View.OnTouchListener {
private var initialY: Float = 0f
private var initialBottom: Int = 0
override fun onTouch(v: View, event: MotionEvent): Boolean {
val imeInsets = v.rootWindowInsets.getInsets(WindowInsetsCompat.Type.ime())
val currentBottom = imeInsets.bottom
when (event.action) {
MotionEvent.ACTION_DOWN -> {
initialY = event.y
initialBottom = currentBottom
return true
}
MotionEvent.ACTION_MOVE -> {
val deltaY = event.y - initialY
val newBottom = (initialBottom - deltaY).toInt()
val fraction = newBottom.toFloat() / v.height // Assuming view height represents max IME height
controller.control(WindowInsetsCompat.Type.ime(), fraction.coerceIn(0f, 1f))
return true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
// Optionally, animate to a final state or reset
return true
}
}
return false
}
}
```
--------------------------------
### Drag and Drop with Jetpack Library
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/draganddrop/README.md
Utilizes the Jetpack Drag and Drop Library for implementing drag-and-drop functionality in Android applications.
```kotlin
package com.example.platform.ui.draganddrop
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.draganddrop.DropHelper
import androidx.fragment.app.commit
class DragAndDropWithHelper : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_drag_and_drop_with_helper)
if (savedInstanceState == null) {
supportFragmentManager.commit {
setReorderingAllowed(true)
add(R.id.fragment_container_view, DragDropHelperFragment())
}
}
}
}
```
--------------------------------
### MotionLayout with Custom Attribute Animation
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/constraintlayout/README.md
Shows how to animate custom attributes within a MotionLayout transition. This is useful for animating properties not directly supported by standard view attributes.
```xml
```
```xml
```
--------------------------------
### Build Spanned String with core-ktx
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/text/README.md
Use `buildSpannedString` from the core-ktx library for efficient creation of rich text with spans. Ensure the core-ktx library is included in your project dependencies.
```kotlin
val spannedString = buildSpannedString {
append("This is normal text.")
append(" This is bold.", SpanStyle(fontWeight = FontWeight.Bold))
append(" This is italic.", SpanStyle(fontStyle = FontStyle.Italic))
}
```
--------------------------------
### Override Activity Transitions
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/predictiveback/README.md
Use `overrideActivityTransition` for custom cross-activity animations. It expects animation resources but recommends using animators and AndroidX transitions.
```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
"..."
overrideActivityTransition(
OVERRIDE_TRANSITION_OPEN,
android.R.anim.fade_in,
0
)
overrideActivityTransition(
OVERRIDE_TRANSITION_CLOSE,
0,
android.R.anim.fade_out
)
}
```
--------------------------------
### Configure Line Break Word Style
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/text/README.md
Control line breaking behavior for languages like Japanese and Chinese using `android:lineBreakWordStyle`. Set to `"phrase"` to prevent line breaks within phrases (bunsetsu). This feature requires the device locale to be set appropriately.
```xml
```
--------------------------------
### Enable Hyphenation in TextView
Source: https://github.com/android/platform-samples/blob/main/samples/user-interface/text/README.md
Apply automatic hyphenation to TextViews using the `android:hyphenationFrequency` attribute. For Android 13 (API 33) and higher, `fullFast` and `normalFast` offer improved performance.
```xml
```