or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

caching-strategies.mderror-handling-debugging.mdindex.mdmodules-configuration.mdrequest-configuration.mdrequest-management.mdtargets-loading.mdtransformations.mdtransitions-animations.md

transitions-animations.mddocs/

0

# Glide Transitions and Animations System

1

2

Glide's transition and animation system provides smooth visual effects during image loading through a flexible architecture built around the `TransitionOptions` base class and specialized implementations like `DrawableTransitionOptions`. The system supports built-in cross-fade effects, custom transitions, and comprehensive animation timing controls for enhanced user experience.

3

4

## TransitionOptions Base Class

5

6

The foundation for all transition configurations in Glide:

7

8

```java { .api }

9

public abstract class TransitionOptions<CHILD extends TransitionOptions<CHILD, TranscodeType>, TranscodeType> {

10

11

/**

12

* Disables all transitions for this request

13

* @return Updated options instance

14

*/

15

public abstract CHILD dontTransition();

16

17

/**

18

* Creates a clone of these options

19

* @return Cloned options instance

20

*/

21

public abstract CHILD clone();

22

23

/**

24

* Creates empty transition options with no effects

25

*/

26

public static <T> TransitionOptions<?, T> of() {

27

// Implementation provided by Glide

28

return null;

29

}

30

}

31

```

32

33

## DrawableTransitionOptions Class

34

35

Specialized transition options for Drawable resources with built-in cross-fade support:

36

37

```java { .api }

38

public class DrawableTransitionOptions extends TransitionOptions<DrawableTransitionOptions, Drawable> {

39

40

/**

41

* Creates cross-fade transition with default duration (300ms)

42

* @return DrawableTransitionOptions with cross-fade

43

*/

44

public static DrawableTransitionOptions withCrossFade() {

45

// Implementation provided by Glide

46

return null;

47

}

48

49

/**

50

* Creates cross-fade transition with custom duration

51

* @param duration Fade duration in milliseconds

52

* @return DrawableTransitionOptions with timed cross-fade

53

*/

54

public static DrawableTransitionOptions withCrossFade(int duration) {

55

// Implementation provided by Glide

56

return null;

57

}

58

59

/**

60

* Creates cross-fade with custom duration and animation builder

61

* @param duration Fade duration in milliseconds

62

* @param animationId Android animation resource ID

63

* @return DrawableTransitionOptions with custom animation

64

*/

65

public static DrawableTransitionOptions withCrossFade(int duration, int animationId) {

66

// Implementation provided by Glide

67

return null;

68

}

69

70

/**

71

* Creates transition with custom transition factory

72

* @param transitionFactory Factory for creating transitions

73

* @return DrawableTransitionOptions with custom factory

74

*/

75

public static DrawableTransitionOptions with(TransitionFactory<? super Drawable> transitionFactory) {

76

// Implementation provided by Glide

77

return null;

78

}

79

80

/**

81

* Creates transition with no animation effects

82

* @return DrawableTransitionOptions with transitions disabled

83

*/

84

public static DrawableTransitionOptions withNoTransition() {

85

// Implementation provided by Glide

86

return null;

87

}

88

89

@Override

90

public DrawableTransitionOptions clone() {

91

// Implementation provided by Glide

92

return null;

93

}

94

}

95

```

96

97

## BitmapTransitionOptions Class

98

99

Transition options specifically for Bitmap resources:

100

101

```java { .api }

102

public class BitmapTransitionOptions extends TransitionOptions<BitmapTransitionOptions, Bitmap> {

103

104

/**

105

* Creates cross-fade transition for bitmaps (default 300ms)

106

* @return BitmapTransitionOptions with cross-fade

107

*/

108

public static BitmapTransitionOptions withCrossFade() {

109

// Implementation provided by Glide

110

return null;

111

}

112

113

/**

114

* Creates cross-fade transition with custom duration

115

* @param duration Fade duration in milliseconds

116

* @return BitmapTransitionOptions with timed cross-fade

117

*/

118

public static BitmapTransitionOptions withCrossFade(int duration) {

119

// Implementation provided by Glide

120

return null;

121

}

122

123

/**

124

* Creates custom bitmap transition

125

* @param transitionFactory Factory for bitmap transitions

126

* @return BitmapTransitionOptions with custom factory

127

*/

128

public static BitmapTransitionOptions with(TransitionFactory<? super Bitmap> transitionFactory) {

129

// Implementation provided by Glide

130

return null;

131

}

132

133

/**

134

* Creates no-transition options for bitmaps

135

* @return BitmapTransitionOptions with no effects

136

*/

137

public static BitmapTransitionOptions withNoTransition() {

138

// Implementation provided by Glide

139

return null;

140

}

141

142

@Override

143

public BitmapTransitionOptions clone() {

144

// Implementation provided by Glide

145

return null;

146

}

147

}

148

```

149

150

## Transition Interface

151

152

Core interface for implementing custom transitions:

153

154

```java { .api }

155

public interface Transition<R> {

156

/**

157

* Executes the transition animation

158

* @param current Current resource (may be placeholder)

159

* @param adapter Adapter for applying the transition

160

* @return True if transition was applied, false otherwise

161

*/

162

boolean transition(R current, ViewAdapter adapter);

163

164

/**

165

* Adapter interface for applying transitions to views

166

*/

167

interface ViewAdapter {

168

/**

169

* Gets the current drawable from the view

170

* @return Current drawable or null

171

*/

172

Drawable getCurrentDrawable();

173

174

/**

175

* Sets the drawable on the view

176

* @param drawable Drawable to set

177

*/

178

void setDrawable(Drawable drawable);

179

180

/**

181

* Gets the underlying view

182

* @return View being transitioned

183

*/

184

View getView();

185

}

186

}

187

```

188

189

## ViewTransition Interface

190

191

Specialized transition interface for view-based animations:

192

193

```java { .api }

194

public interface ViewTransition {

195

/**

196

* Executes transition on a specific view

197

* @param view Target view for the transition

198

* @param adapter Adapter for view operations

199

* @return True if transition was handled

200

*/

201

boolean transition(View view, Transition.ViewAdapter adapter);

202

203

/**

204

* Creates a view transition from an animation resource

205

* @param animationId Android animation resource ID

206

* @return ViewTransition using the animation

207

*/

208

static ViewTransition withAnimation(int animationId) {

209

// Implementation provided by Glide

210

return null;

211

}

212

213

/**

214

* Creates a view transition with no animation

215

* @return ViewTransition that immediately sets the drawable

216

*/

217

static ViewTransition withNoTransition() {

218

// Implementation provided by Glide

219

return null;

220

}

221

}

222

```

223

224

## TransitionFactory Interface

225

226

Factory interface for creating transition instances:

227

228

```java { .api }

229

public interface TransitionFactory<R> {

230

/**

231

* Creates a transition for the given data source

232

* @param dataSource Source of the image data

233

* @param isFirstResource Whether this is the first resource loaded

234

* @return Transition instance or null for no transition

235

*/

236

Transition<R> build(DataSource dataSource, boolean isFirstResource);

237

}

238

```

239

240

## Basic Transition Usage

241

242

### Simple Cross-Fade Transitions

243

244

Apply basic cross-fade effects to image loading:

245

246

```java

247

public class BasicTransitionsActivity extends AppCompatActivity {

248

249

public void basicCrossFade() {

250

// Default cross-fade (300ms)

251

Glide.with(this)

252

.load(imageUrl)

253

.transition(DrawableTransitionOptions.withCrossFade())

254

.into(imageView);

255

256

// Custom duration cross-fade

257

Glide.with(this)

258

.load(imageUrl)

259

.transition(DrawableTransitionOptions.withCrossFade(500))

260

.into(imageView);

261

262

// Bitmap-specific cross-fade

263

Glide.with(this)

264

.asBitmap()

265

.load(imageUrl)

266

.transition(BitmapTransitionOptions.withCrossFade(400))

267

.into(imageView);

268

}

269

270

public void noTransition() {

271

// Disable transitions completely

272

Glide.with(this)

273

.load(imageUrl)

274

.transition(DrawableTransitionOptions.withNoTransition())

275

.into(imageView);

276

277

// Alternative syntax

278

Glide.with(this)

279

.load(imageUrl)

280

.dontAnimate()

281

.into(imageView);

282

}

283

}

284

```

285

286

### Android Animation Resources

287

288

Use Android animation XML resources for transitions:

289

290

```java

291

public class AnimationResourceActivity extends AppCompatActivity {

292

293

public void useAnimationResources() {

294

// Create animation XML file: res/anim/fade_in.xml

295

/*

296

<?xml version="1.0" encoding="utf-8"?>

297

<alpha xmlns:android="http://schemas.android.com/apk/res/android"

298

android:fromAlpha="0.0"

299

android:toAlpha="1.0"

300

android:duration="600" />

301

*/

302

303

// Apply animation resource

304

Glide.with(this)

305

.load(imageUrl)

306

.transition(DrawableTransitionOptions.withCrossFade(600, R.anim.fade_in))

307

.into(imageView);

308

309

// Scale animation: res/anim/scale_up.xml

310

/*

311

<?xml version="1.0" encoding="utf-8"?>

312

<scale xmlns:android="http://schemas.android.com/apk/res/android"

313

android:fromXScale="0.8"

314

android:fromYScale="0.8"

315

android:toXScale="1.0"

316

android:toYScale="1.0"

317

android:pivotX="50%"

318

android:pivotY="50%"

319

android:duration="400"

320

android:interpolator="@android:anim/decelerate_interpolator" />

321

*/

322

323

ViewTransition scaleTransition = ViewTransition.withAnimation(R.anim.scale_up);

324

Glide.with(this)

325

.load(imageUrl)

326

.transition(DrawableTransitionOptions.with(

327

new TransitionFactory<Drawable>() {

328

@Override

329

public Transition<Drawable> build(DataSource dataSource, boolean isFirstResource) {

330

return scaleTransition;

331

}

332

}

333

))

334

.into(imageView);

335

}

336

}

337

```

338

339

## Custom Transitions

340

341

### Simple Custom Transition

342

343

Create custom transition effects by implementing the Transition interface:

344

345

```java

346

public class FadeInTransition implements Transition<Drawable> {

347

348

@Override

349

public boolean transition(Drawable current, Transition.ViewAdapter adapter) {

350

View view = adapter.getView();

351

352

// Set initial alpha and drawable

353

view.setAlpha(0f);

354

adapter.setDrawable(current);

355

356

// Animate fade in

357

view.animate()

358

.alpha(1f)

359

.setDuration(500)

360

.setInterpolator(new DecelerateInterpolator())

361

.start();

362

363

return true;

364

}

365

}

366

367

public class CustomTransitionActivity extends AppCompatActivity {

368

369

public void useCustomTransition() {

370

TransitionFactory<Drawable> fadeInFactory = new TransitionFactory<Drawable>() {

371

@Override

372

public Transition<Drawable> build(DataSource dataSource, boolean isFirstResource) {

373

return new FadeInTransition();

374

}

375

};

376

377

Glide.with(this)

378

.load(imageUrl)

379

.transition(DrawableTransitionOptions.with(fadeInFactory))

380

.into(imageView);

381

}

382

}

383

```

384

385

### Advanced Custom Transitions

386

387

Create complex animations with multiple effects:

388

389

```java

390

public class SlideUpFadeTransition implements Transition<Drawable> {

391

392

@Override

393

public boolean transition(Drawable current, Transition.ViewAdapter adapter) {

394

View view = adapter.getView();

395

float originalY = view.getTranslationY();

396

397

// Set initial state

398

view.setAlpha(0f);

399

view.setTranslationY(view.getHeight() * 0.3f);

400

adapter.setDrawable(current);

401

402

// Create animator set for combined effects

403

ObjectAnimator fadeAnimator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f);

404

ObjectAnimator slideAnimator = ObjectAnimator.ofFloat(view, "translationY", view.getTranslationY(), originalY);

405

406

AnimatorSet animatorSet = new AnimatorSet();

407

animatorSet.playTogether(fadeAnimator, slideAnimator);

408

animatorSet.setDuration(600);

409

animatorSet.setInterpolator(new DecelerateInterpolator());

410

animatorSet.start();

411

412

return true;

413

}

414

}

415

416

public class CrossFadeTransition implements Transition<Drawable> {

417

private final int duration;

418

419

public CrossFadeTransition() {

420

this.duration = 300;

421

}

422

423

public CrossFadeTransition(int duration) {

424

this.duration = duration;

425

}

426

427

@Override

428

public boolean transition(Drawable current, Transition.ViewAdapter adapter) {

429

Drawable previous = adapter.getCurrentDrawable();

430

431

if (previous == null) {

432

adapter.setDrawable(current);

433

return false;

434

}

435

436

// Create cross-fade effect

437

TransitionDrawable crossFadeDrawable = new TransitionDrawable(new Drawable[]{previous, current});

438

adapter.setDrawable(crossFadeDrawable);

439

crossFadeDrawable.startTransition(duration);

440

441

return true;

442

}

443

}

444

```

445

446

### Conditional Transitions

447

448

Apply different transitions based on data source or conditions:

449

450

```java

451

public class ConditionalTransitionFactory implements TransitionFactory<Drawable> {

452

453

@Override

454

public Transition<Drawable> build(DataSource dataSource, boolean isFirstResource) {

455

// No transition for cached images (already fast)

456

if (dataSource == DataSource.MEMORY_CACHE) {

457

return null;

458

}

459

460

// Slow fade for remote images (user expects loading time)

461

if (dataSource == DataSource.REMOTE) {

462

return new CrossFadeTransition(500);

463

}

464

465

// Quick fade for local images

466

if (dataSource == DataSource.LOCAL) {

467

return new CrossFadeTransition(200);

468

}

469

470

// Custom transition for first load

471

if (isFirstResource) {

472

return new SlideUpFadeTransition();

473

}

474

475

// Default cross-fade

476

return new CrossFadeTransition();

477

}

478

}

479

480

public class ConditionalTransitionsActivity extends AppCompatActivity {

481

482

public void useConditionalTransitions() {

483

Glide.with(this)

484

.load(imageUrl)

485

.transition(DrawableTransitionOptions.with(new ConditionalTransitionFactory()))

486

.into(imageView);

487

}

488

}

489

```

490

491

## Animation Timing and Customization

492

493

### Transition Timing Control

494

495

Control animation duration and timing:

496

497

```java

498

public class TimingControlActivity extends AppCompatActivity {

499

500

public void variableTimingTransitions() {

501

// Fast transition for thumbnails

502

RequestOptions thumbnailOptions = new RequestOptions()

503

.override(100, 100)

504

.centerCrop();

505

506

Glide.with(this)

507

.load(thumbnailUrl)

508

.apply(thumbnailOptions)

509

.transition(DrawableTransitionOptions.withCrossFade(150))

510

.into(thumbnailView);

511

512

// Slow transition for hero images

513

Glide.with(this)

514

.load(heroImageUrl)

515

.transition(DrawableTransitionOptions.withCrossFade(800))

516

.into(heroImageView);

517

518

// No transition for rapid scrolling

519

if (isRapidScrolling) {

520

Glide.with(this)

521

.load(imageUrl)

522

.dontAnimate()

523

.into(imageView);

524

}

525

}

526

}

527

```

528

529

### Interpolator Customization

530

531

Use different interpolators for varied animation feels:

532

533

```java

534

public class InterpolatorTransition implements Transition<Drawable> {

535

private final long duration;

536

private final Interpolator interpolator;

537

538

public InterpolatorTransition() {

539

this.duration = 300;

540

this.interpolator = new AccelerateDecelerateInterpolator();

541

}

542

543

public InterpolatorTransition(long duration, Interpolator interpolator) {

544

this.duration = duration;

545

this.interpolator = interpolator;

546

}

547

548

@Override

549

public boolean transition(Drawable current, Transition.ViewAdapter adapter) {

550

View view = adapter.getView();

551

552

view.setAlpha(0f);

553

adapter.setDrawable(current);

554

555

view.animate()

556

.alpha(1f)

557

.setDuration(duration)

558

.setInterpolator(interpolator)

559

.start();

560

561

return true;

562

}

563

}

564

565

public class InterpolatorActivity extends AppCompatActivity {

566

567

public void useInterpolators() {

568

// Bouncy animation

569

TransitionFactory<Drawable> bounceFactory = new TransitionFactory<Drawable>() {

570

@Override

571

public Transition<Drawable> build(DataSource dataSource, boolean isFirstResource) {

572

return new InterpolatorTransition(600, new BounceInterpolator());

573

}

574

};

575

576

// Overshoot animation

577

TransitionFactory<Drawable> overshootFactory = new TransitionFactory<Drawable>() {

578

@Override

579

public Transition<Drawable> build(DataSource dataSource, boolean isFirstResource) {

580

return new InterpolatorTransition(500, new OvershootInterpolator());

581

}

582

};

583

584

Glide.with(this)

585

.load(imageUrl)

586

.transition(DrawableTransitionOptions.with(bounceFactory))

587

.into(imageView);

588

}

589

}

590

```

591

592

## Global Transition Configuration

593

594

### Default Transitions

595

596

Set default transitions through GlideModule:

597

598

```java

599

public class GlobalTransitionModule extends AppGlideModule {

600

601

@Override

602

public void applyOptions(Context context, GlideBuilder builder) {

603

// Set default drawable transitions

604

builder.setDefaultTransitionOptions(

605

Drawable.class,

606

DrawableTransitionOptions.withCrossFade(400)

607

);

608

609

// Set default bitmap transitions

610

builder.setDefaultTransitionOptions(

611

Bitmap.class,

612

BitmapTransitionOptions.withCrossFade(300)

613

);

614

}

615

}

616

```

617

618

### RequestOptions with Transitions

619

620

Create reusable transition configurations:

621

622

```java

623

public class TransitionPresets {

624

625

public static final RequestOptions INSTANT = new RequestOptions()

626

.dontAnimate();

627

628

public static final RequestOptions FAST_FADE = new RequestOptions()

629

.transition(DrawableTransitionOptions.withCrossFade(200));

630

631

public static final RequestOptions SLOW_FADE = new RequestOptions()

632

.transition(DrawableTransitionOptions.withCrossFade(600));

633

634

public static final RequestOptions CUSTOM_SLIDE = new RequestOptions()

635

.transition(DrawableTransitionOptions.with(

636

new TransitionFactory<Drawable>() {

637

@Override

638

public Transition<Drawable> build(DataSource dataSource, boolean isFirstResource) {

639

return new SlideUpFadeTransition();

640

}

641

}

642

));

643

}

644

645

public class TransitionPresetsActivity extends AppCompatActivity {

646

647

public void usePresets() {

648

// Gallery thumbnails - fast

649

Glide.with(this)

650

.load(thumbnailUrl)

651

.apply(TransitionPresets.FAST_FADE)

652

.into(thumbnailView);

653

654

// Featured image - slow elegant fade

655

Glide.with(this)

656

.load(featuredUrl)

657

.apply(TransitionPresets.SLOW_FADE)

658

.into(featuredView);

659

660

// Profile image - custom slide effect

661

Glide.with(this)

662

.load(profileUrl)

663

.apply(TransitionPresets.CUSTOM_SLIDE)

664

.into(profileView);

665

}

666

}

667

```

668

669

## Performance Considerations

670

671

### Optimized Transitions

672

673

Balance visual appeal with performance:

674

675

```java

676

public class PerformanceOptimizedTransitions extends AppCompatActivity {

677

678

public void optimizeForPerformance() {

679

// Disable transitions during fast scrolling

680

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

681

@Override

682

public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

683

boolean useTransitions = newState != RecyclerView.SCROLL_STATE_SETTLING;

684

685

if (useTransitions) {

686

// Normal transitions when not scrolling

687

Glide.with(PerformanceOptimizedTransitions.this)

688

.setDefaultRequestOptions(TransitionPresets.FAST_FADE);

689

} else {

690

// No transitions during scroll

691

Glide.with(PerformanceOptimizedTransitions.this)

692

.setDefaultRequestOptions(TransitionPresets.INSTANT);

693

}

694

}

695

});

696

}

697

698

public void adaptiveTransitions() {

699

// Adjust transitions based on device performance

700

boolean isLowEndDevice = !ActivityManager.isHighPerformanceDevice();

701

702

DrawableTransitionOptions transitionOptions;

703

if (isLowEndDevice) {

704

// Minimal transitions on low-end devices

705

transitionOptions = DrawableTransitionOptions.withCrossFade(150);

706

} else {

707

// Rich transitions on capable devices

708

transitionOptions = DrawableTransitionOptions.withCrossFade(400);

709

}

710

711

Glide.with(this)

712

.load(imageUrl)

713

.transition(transitionOptions)

714

.into(imageView);

715

}

716

}

717

```

718

719

## Best Practices

720

721

### Transition Guidelines

722

723

1. **Performance**: Disable transitions during rapid scrolling for smooth performance

724

2. **Consistency**: Use consistent transition timing across similar UI elements

725

3. **Context Awareness**: Adapt transition duration based on image source and size

726

4. **Device Capability**: Consider device performance when choosing transition complexity

727

5. **User Experience**: Match transitions to user expectations and app personality

728

729

### Common Patterns

730

731

```java

732

public class TransitionBestPractices {

733

734

// Context-aware transition selection

735

public static DrawableTransitionOptions getOptimalTransition(Context context, ImageSize imageSize) {

736

switch (imageSize) {

737

case THUMBNAIL:

738

return DrawableTransitionOptions.withCrossFade(150);

739

case MEDIUM:

740

return DrawableTransitionOptions.withCrossFade(300);

741

case LARGE:

742

return DrawableTransitionOptions.withCrossFade(500);

743

case HERO:

744

return DrawableTransitionOptions.withCrossFade(800);

745

default:

746

return DrawableTransitionOptions.withCrossFade(300);

747

}

748

}

749

750

// Scroll-state aware transitions

751

public static DrawableTransitionOptions getScrollAwareTransition(boolean isScrolling) {

752

if (isScrolling) {

753

return DrawableTransitionOptions.withNoTransition();

754

} else {

755

return DrawableTransitionOptions.withCrossFade(250);

756

}

757

}

758

}

759

```

760

761

This comprehensive transition system provides the tools needed to create smooth, visually appealing image loading experiences while maintaining optimal performance across different device capabilities and usage patterns.