Transition animations between activities elevate the user experience, especially in image galleries where thumbnails expand smoothly into detail views. In Android, shared element transitions make it possible to animate views seamlessly from one activity to another, turning a grid thumbnail tap into an engaging transition animation.
This guide explains how to apply custom activity transitions in a GridView image gallery with practical code, including setup, shared element configuration, and compatibility considerations.
What Are Activity Transitions in Android?
Activity transitions define how views animate when an activity starts or finishes. Material Design supports:
- Enter and exit transitions – animations for activity views
- Shared element transitions – animations for views shared between activities (e.g., image thumbnail to full-screen image)
Android’s transition framework supports built-in animations like fade, slide, and shared element transforms such as changeBounds and changeImageTransform.
Shared element transitions are most commonly used for gallery effects where a thumbnail appears to scale and move to its full-screen counterpart.
Prerequisites
Before implementing transitions:
✔ Your app should target API 21 (Lollipop) or higher for shared element transitions.
✔ Use AndroidX libraries and AppCompatActivity.
Step 1: GridView with Image Thumbnails
Start with a GridView that displays images. Define the layout:
res/layout/activity_main.xml
<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="auto_fit"
android:horizontalSpacing="8dp"
android:verticalSpacing="8dp"
android:columnWidth="100dp"
android:stretchMode="columnWidth"/>
Each grid item should contain an ImageView that displays the thumbnail.
Step 2: Adapter and Image Loading
Implement a custom adapter to populate the GridView:
public class ImageAdapter extends BaseAdapter {
private Context context;
private List<Integer> images;
public ImageAdapter(Context context, List<Integer> images) {
this.context = context;
this.images = images;
}
@Override
public int getCount() {
return images.size();
}
@Override
public Object getItem(int position) {
return images.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(300, 300));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(images.get(position));
return imageView;
}
}
Load images (using Glide, Picasso etc.) depending on your project needs.
Step 3: Enable Shared Element Transition
Define a transition name in your grid item XML:
<ImageView
android:id="@+id/imgThumb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:transitionName="photoTransition"/>
Use identical android:transitionName in both activities.
Step 4: Start the Target Activity with Transition
In your MainActivity.java, handle GridView clicks:
gridView.setOnItemClickListener((parent, view, position, id) -> {
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putExtra("imageRes", images.get(position));
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
MainActivity.this,
view.findViewById(R.id.imgThumb),
ViewCompat.getTransitionName(view.findViewById(R.id.imgThumb))
);
startActivity(intent, options.toBundle());
});
This triggers a shared element transition where the clicked image scales and moves into the detail screen.
Step 5: Configure the Detail Activity
In your DetailActivity.java, receive the image and set it:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
ImageView imgDetail = findViewById(R.id.imgDetail);
int imageRes = getIntent().getIntExtra("imageRes", 0);
imgDetail.setImageResource(imageRes);
}
Ensure activity_detail.xml uses the same transition name:
<ImageView
android:id="@+id/imgDetail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionName="photoTransition"/>
This consistency lets Android link the shared element across activities.
Optional: Custom Enter/Exit Animations
For non-shared transitions, you can define custom animations in XML (res/anim/) and apply them via:
overridePendingTransition(R.anim.slide_in, R.anim.fade_out);
This helps add polish beyond shared element motion.
Compatibility with Older Devices
Activity transitions require API 21+. For backward compatibility, wrap transition logic in a version check:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Shared element transition
} else {
startActivity(intent);
}
Apps can still launch the detail screen normally when transitions aren’t supported.
Best Practices
From commercial Android experience:
- Use shared element transitions to create intuitive context continuity between lists and detail views.
- Load images asynchronously (Glide/Picasso) to prevent frame drops.
- Ensure transition names are unique per element to avoid conflict.
- Test transitions on multiple screen sizes/performance tiers — animation can vary.
- For complex scenes, consider MotionLayout (Jetpack) for more control.
Shared transitions are visually engaging and reflect modern Android material design patterns.
Common Challenges and Fixes
Transition looks abrupt
✔ Make sure both source and target views have identical transitionName.
Image flickers or resizes incorrectly
✔ Use the same aspect ratio and scaleType in both layouts.
No animation on older devices
✔ Always include API level checks and fallback behavior.
Summary
Implementing a custom activity transition from a GridView image gallery enhances your app’s UX by smoothly animating images into detail views. This is achieved mainly through shared element activity transitions, which leverage Android’s built-in transitions and Material Design standards. With proper setup and compatibility checks, this pattern delivers a polished, professional gallery experience.


