Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Created November 4, 2025 10:31
Show Gist options
  • Save sunmeat/c66d5224ea05f57528d630c013d0b918 to your computer and use it in GitHub Desktop.
Save sunmeat/c66d5224ea05f57528d630c013d0b918 to your computer and use it in GitHub Desktop.
fluid motion design android example
MainActivity.java:
package site.sunmeat.animation;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityOptionsCompat;
public class MainActivity extends AppCompatActivity {
private Button btnTransition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnTransition = findViewById(R.id.btn_transition);
// анімація на клік: scale + зміна кольору з overshoot (fluid motion)
btnTransition.setOnClickListener(v -> {
// плавне розширення на 10% з overshoot
////////////////////////////////////////////////////////////////// !!!
v.animate()
.scaleX(1.1f)
.scaleY(1.1f)
.setDuration(200)
.setInterpolator(new OvershootInterpolator(1.0f)) // overshoot для природності
.withEndAction(() -> {
// transition до DetailActivity (shared element)
View sharedElement = btnTransition;
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
MainActivity.this, sharedElement, "transition_button");
var intent = new Intent(MainActivity.this, DetailActivity.class);
startActivity(intent, options.toBundle());
Toast.makeText(this, "Перехід завершено плавно!", Toast.LENGTH_SHORT).show();
})
.start();
btnTransition.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.green_positive)));
});
}
}
=================================================================================================================
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FAFAFA"
android:gravity="center"
android:orientation="vertical"
android:padding="32dp">
<Button
android:id="@+id/btn_transition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#2196F3"
android:padding="16dp"
android:text="Дізнатися більше"
android:textSize="18sp" />
</LinearLayout>
=================================================================================================================
DetailActivity.java:
package site.sunmeat.animation;
import android.os.Bundle;
import android.view.animation.LinearInterpolator;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class DetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
// fade-in для всього екрану (fluid entrance)
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
// додаткова анімація: легке пульсування тексту
TextView textView = findViewById(R.id.detail_text);
textView.animate()
.alpha(0f)
.setDuration(0)
.alpha(1f)
.setDuration(800)
.setInterpolator(new LinearInterpolator()) // лінійне для плавності
.start();
}
}
=================================================================================================================
activity_detail.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FAFAFA"
android:gravity="center"
android:orientation="vertical"
android:padding="32dp">
<Button
android:id="@+id/btn_transition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#4CAF50"
android:padding="16dp"
android:text="Деталі"
android:textSize="18sp"
android:transitionName="transition_button" />
<TextView
android:id="@+id/detail_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Мінімалістичний дизайн з fluid motion"
android:textColor="#2196F3"
android:textSize="16sp" />
</LinearLayout>
=================================================================================================================
res / values / colors.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="pink">#E91E63</color>
<color name="blue_trust">#2196F3</color>
<color name="green_positive">#4CAF50</color>
</resources>
=================================================================================================================
build.gradle.kts:
...
implementation("androidx.transition:transition:1.6.0")
=================================================================================================================
AndroidManifest.xml:
...
<application
tools:replace="android:label"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/cat"
android:label="TEST"
android:roundIcon="@mipmap/cat"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DetailActivity"
android:exported="true">
</activity>
</application>
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment