or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buttons-and-selection.mdfeedback-and-communication.mdindex.mdinput-and-forms.mdlayout-and-containers.mdnavigation-components.mdpickers-and-selection.mdtheming-and-styling.md

layout-and-containers.mddocs/

0

# Layout and Containers

1

2

Structural components for organizing and containing content, including app bars, cards, bottom sheets, and specialized layouts.

3

4

## Core Imports

5

6

```java

7

import com.google.android.material.appbar.AppBarLayout;

8

import com.google.android.material.appbar.CollapsingToolbarLayout;

9

import com.google.android.material.card.MaterialCardView;

10

import com.google.android.material.bottomsheet.BottomSheetBehavior;

11

import com.google.android.material.bottomsheet.BottomSheetDialog;

12

import com.google.android.material.bottomsheet.BottomSheetDialogFragment;

13

import com.google.android.material.sidesheet.SideSheetBehavior;

14

import com.google.android.material.sidesheet.SideSheetDialog;

15

import com.google.android.material.imageview.ShapeableImageView;

16

import com.google.android.material.divider.MaterialDivider;

17

import com.google.android.material.divider.MaterialDividerItemDecoration;

18

import com.google.android.material.carousel.CarouselLayoutManager;

19

import com.google.android.material.carousel.CarouselStrategy;

20

import com.google.android.material.carousel.CarouselSnapHelper;

21

import com.google.android.material.carousel.MaskableFrameLayout;

22

```

23

24

## Material Card View

25

26

Card container with Material Design styling, elevation, and interactive states.

27

28

```java { .api }

29

class MaterialCardView extends CardView {

30

MaterialCardView(Context context);

31

MaterialCardView(Context context, AttributeSet attrs);

32

33

// Stroke configuration

34

void setStrokeColor(@ColorInt int strokeColor);

35

void setStrokeColor(ColorStateList strokeColor);

36

int getStrokeColor();

37

ColorStateList getStrokeColorStateList();

38

void setStrokeWidth(@Dimension int strokeWidth);

39

int getStrokeWidth();

40

41

// Card foreground

42

void setCardForegroundColor(ColorStateList foregroundColor);

43

ColorStateList getCardForegroundColor();

44

45

// Ripple effect

46

void setRippleColor(ColorStateList rippleColor);

47

ColorStateList getRippleColor();

48

void setRippleColorResource(@ColorRes int rippleColorResourceId);

49

ColorStateList getRippleColorResource();

50

51

// Checkable state

52

void setCheckable(boolean checkable);

53

boolean isCheckable();

54

void setChecked(boolean checked);

55

boolean isChecked();

56

void toggle();

57

void setOnCheckedChangeListener(OnCheckedChangeListener listener);

58

59

// Shape appearance

60

void setShapeAppearanceModel(ShapeAppearanceModel shapeAppearanceModel);

61

ShapeAppearanceModel getShapeAppearanceModel();

62

}

63

64

interface MaterialCardView.OnCheckedChangeListener {

65

void onCheckedChanged(MaterialCardView card, boolean isChecked);

66

}

67

```

68

69

### Usage Example

70

71

```java

72

MaterialCardView cardView = findViewById(R.id.card_view);

73

74

// Configure appearance

75

cardView.setStrokeWidth(2);

76

cardView.setStrokeColor(ContextCompat.getColor(this, R.color.stroke_color));

77

cardView.setRippleColor(ColorStateList.valueOf(ContextCompat.getColor(this, R.color.ripple_color)));

78

79

// Make checkable for selection

80

cardView.setCheckable(true);

81

cardView.setOnCheckedChangeListener((card, isChecked) -> {

82

if (isChecked) {

83

// Handle card selection

84

card.setStrokeColor(ContextCompat.getColor(this, R.color.selected_stroke));

85

} else {

86

// Handle card deselection

87

card.setStrokeColor(ContextCompat.getColor(this, R.color.normal_stroke));

88

}

89

});

90

91

// Custom shape

92

ShapeAppearanceModel shapeAppearanceModel = ShapeAppearanceModel.builder()

93

.setTopLeftCorner(CornerFamily.ROUNDED, 16f)

94

.setTopRightCorner(CornerFamily.ROUNDED, 16f)

95

.setBottomLeftCorner(CornerFamily.CUT, 8f)

96

.setBottomRightCorner(CornerFamily.CUT, 8f)

97

.build();

98

cardView.setShapeAppearanceModel(shapeAppearanceModel);

99

```

100

101

## Bottom Sheet Behavior

102

103

Behavior for implementing bottom sheet interactions with CoordinatorLayout.

104

105

```java { .api }

106

class BottomSheetBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {

107

// Factory method

108

static <V extends View> BottomSheetBehavior<V> from(V view);

109

110

// State management

111

void setState(int state);

112

int getState();

113

114

// Collapsing behavior

115

void setSkipCollapsed(boolean skipCollapsed);

116

boolean getSkipCollapsed();

117

118

// Hideable configuration

119

void setHideable(boolean hideable);

120

boolean isHideable();

121

122

// Peek height

123

void setPeekHeight(int peekHeight);

124

int getPeekHeight();

125

void setPeekHeightAuto(boolean peekHeightAuto);

126

boolean getPeekHeightAuto();

127

128

// Fit to contents

129

void setFitToContents(boolean fitToContents);

130

boolean isFitToContents();

131

132

// Half expanded ratio

133

void setHalfExpandedRatio(@FloatRange(from = 0.0f, to = 1.0f) float ratio);

134

@FloatRange(from = 0.0f, to = 1.0f) float getHalfExpandedRatio();

135

136

// Callbacks

137

void addBottomSheetCallback(BottomSheetCallback callback);

138

void removeBottomSheetCallback(BottomSheetCallback callback);

139

140

// Dragging

141

void setDraggable(boolean draggable);

142

boolean isDraggable();

143

144

// Save flags

145

void setSaveFlags(int flags);

146

int getSaveFlags();

147

}

148

149

abstract class BottomSheetBehavior.BottomSheetCallback {

150

abstract void onStateChanged(@NonNull View bottomSheet, int newState);

151

void onSlide(@NonNull View bottomSheet, float slideOffset);

152

}

153

```

154

155

### Bottom Sheet State Constants

156

157

```java { .api }

158

public static final int STATE_DRAGGING = 1;

159

public static final int STATE_SETTLING = 2;

160

public static final int STATE_EXPANDED = 3;

161

public static final int STATE_COLLAPSED = 4;

162

public static final int STATE_HIDDEN = 5;

163

public static final int STATE_HALF_EXPANDED = 6;

164

```

165

166

### Usage Example

167

168

```java

169

// Get bottom sheet behavior from view

170

View bottomSheet = findViewById(R.id.bottom_sheet);

171

BottomSheetBehavior<View> behavior = BottomSheetBehavior.from(bottomSheet);

172

173

// Configure behavior

174

behavior.setPeekHeight(200);

175

behavior.setHideable(true);

176

behavior.setFitToContents(false);

177

behavior.setHalfExpandedRatio(0.6f);

178

179

// Add callback to listen for state changes

180

behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {

181

@Override

182

public void onStateChanged(@NonNull View bottomSheet, int newState) {

183

switch (newState) {

184

case BottomSheetBehavior.STATE_EXPANDED:

185

// Bottom sheet is fully expanded

186

break;

187

case BottomSheetBehavior.STATE_COLLAPSED:

188

// Bottom sheet is collapsed to peek height

189

break;

190

case BottomSheetBehavior.STATE_HIDDEN:

191

// Bottom sheet is hidden

192

break;

193

case BottomSheetBehavior.STATE_DRAGGING:

194

// User is dragging the bottom sheet

195

break;

196

case BottomSheetBehavior.STATE_SETTLING:

197

// Bottom sheet is settling to a final position

198

break;

199

}

200

}

201

202

@Override

203

public void onSlide(@NonNull View bottomSheet, float slideOffset) {

204

// Handle slide offset changes (0.0 = collapsed, 1.0 = expanded)

205

updateBackdropAlpha(slideOffset);

206

}

207

});

208

209

// Programmatically control state

210

behavior.setState(BottomSheetBehavior.STATE_EXPANDED);

211

```

212

213

## Bottom Sheet Dialog

214

215

Dialog with bottom sheet behavior for modal presentations.

216

217

```java { .api }

218

class BottomSheetDialog extends AppCompatDialog {

219

BottomSheetDialog(Context context);

220

BottomSheetDialog(Context context, int theme);

221

222

// Content view

223

void setContentView(@LayoutRes int layoutResId);

224

void setContentView(View view);

225

void setContentView(View view, ViewGroup.LayoutParams params);

226

227

// Behavior access

228

BottomSheetBehavior<FrameLayout> getBehavior();

229

230

// Dismiss animation

231

void setDismissWithAnimation(boolean dismissWithAnimation);

232

boolean getDismissWithAnimation();

233

234

// Edge-to-edge

235

boolean getEdgeToEdgeEnabled();

236

void setEdgeToEdgeEnabled(boolean edgeToEdgeEnabled);

237

}

238

```

239

240

### Usage Example

241

242

```java

243

// Create bottom sheet dialog

244

BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(this);

245

bottomSheetDialog.setContentView(R.layout.bottom_sheet_dialog);

246

247

// Configure behavior

248

BottomSheetBehavior<FrameLayout> behavior = bottomSheetDialog.getBehavior();

249

behavior.setPeekHeight(400);

250

behavior.setState(BottomSheetBehavior.STATE_EXPANDED);

251

252

// Setup content

253

TextView title = bottomSheetDialog.findViewById(R.id.title);

254

title.setText("Bottom Sheet Title");

255

256

MaterialButton actionButton = bottomSheetDialog.findViewById(R.id.action_button);

257

actionButton.setOnClickListener(v -> {

258

// Handle action

259

bottomSheetDialog.dismiss();

260

});

261

262

// Show dialog

263

bottomSheetDialog.show();

264

```

265

266

## Bottom Sheet Dialog Fragment

267

268

DialogFragment with built-in bottom sheet behavior.

269

270

```java { .api }

271

class BottomSheetDialogFragment extends AppCompatDialogFragment {

272

BottomSheetDialogFragment();

273

274

// Dialog access

275

BottomSheetDialog getDialog();

276

}

277

```

278

279

### Usage Example

280

281

```java

282

public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment {

283

284

@Override

285

public void onCreate(@Nullable Bundle savedInstanceState) {

286

super.onCreate(savedInstanceState);

287

// Set style if needed

288

setStyle(DialogFragment.STYLE_NORMAL, R.style.CustomBottomSheetDialogTheme);

289

}

290

291

@Nullable

292

@Override

293

public View onCreateView(@NonNull LayoutInflater inflater,

294

@Nullable ViewGroup container,

295

@Nullable Bundle savedInstanceState) {

296

return inflater.inflate(R.layout.bottom_sheet_fragment, container, false);

297

}

298

299

@Override

300

public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {

301

super.onViewCreated(view, savedInstanceState);

302

303

// Configure behavior

304

BottomSheetDialog dialog = (BottomSheetDialog) getDialog();

305

if (dialog != null) {

306

BottomSheetBehavior<FrameLayout> behavior = dialog.getBehavior();

307

behavior.setPeekHeight(300);

308

behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

309

}

310

311

// Setup views

312

MaterialButton closeButton = view.findViewById(R.id.close_button);

313

closeButton.setOnClickListener(v -> dismiss());

314

}

315

}

316

317

// Usage

318

CustomBottomSheetDialogFragment fragment = new CustomBottomSheetDialogFragment();

319

fragment.show(getSupportFragmentManager(), "bottom_sheet");

320

```

321

322

## Side Sheet Behavior

323

324

Behavior for implementing side sheet interactions (left or right edge).

325

326

```java { .api }

327

class SideSheetBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {

328

// Factory method

329

static <V extends View> SideSheetBehavior<V> from(V view);

330

331

// State management

332

void setState(int state);

333

int getState();

334

335

// Hideable configuration

336

void setHideable(boolean hideable);

337

boolean isHideable();

338

339

// Callbacks

340

void addCallback(SideSheetCallback callback);

341

void removeCallback(SideSheetCallback callback);

342

343

// Dragging

344

void setDraggable(boolean draggable);

345

boolean isDraggable();

346

}

347

348

abstract class SideSheetBehavior.SideSheetCallback {

349

abstract void onStateChanged(@NonNull View sheet, int newState);

350

void onSlide(@NonNull View sheet, float slideOffset);

351

}

352

```

353

354

### Side Sheet State Constants

355

356

```java { .api }

357

public static final int STATE_DRAGGING = 1;

358

public static final int STATE_SETTLING = 2;

359

public static final int STATE_EXPANDED = 3;

360

public static final int STATE_HIDDEN = 5;

361

```

362

363

## Side Sheet Dialog

364

365

Dialog with side sheet behavior for edge-based modal presentations.

366

367

```java { .api }

368

class SideSheetDialog extends AppCompatDialog {

369

SideSheetDialog(Context context);

370

SideSheetDialog(Context context, int theme);

371

372

// Behavior access

373

SideSheetBehavior<View> getBehavior();

374

375

// Content view

376

void setContentView(@LayoutRes int layoutResId);

377

void setContentView(View view);

378

void setContentView(View view, ViewGroup.LayoutParams params);

379

}

380

```

381

382

## Shapeable Image View

383

384

ImageView that supports Material shape theming and stroke styling.

385

386

```java { .api }

387

class ShapeableImageView extends AppCompatImageView {

388

ShapeableImageView(Context context);

389

ShapeableImageView(Context context, AttributeSet attrs);

390

391

// Shape appearance

392

void setShapeAppearanceModel(ShapeAppearanceModel shapeAppearanceModel);

393

ShapeAppearanceModel getShapeAppearanceModel();

394

395

// Stroke configuration

396

void setStrokeColor(ColorStateList strokeColor);

397

ColorStateList getStrokeColor();

398

void setStrokeColorResource(@ColorRes int strokeColorResourceId);

399

void setStrokeWidth(@Dimension float strokeWidth);

400

float getStrokeWidth();

401

void setStrokeWidthResource(@DimenRes int strokeWidthResourceId);

402

}

403

```

404

405

### Usage Example

406

407

```java

408

ShapeableImageView imageView = findViewById(R.id.shapeable_image_view);

409

410

// Load image

411

Glide.with(this)

412

.load(imageUrl)

413

.into(imageView);

414

415

// Apply circular shape

416

ShapeAppearanceModel shapeAppearanceModel = ShapeAppearanceModel.builder()

417

.setAllCorners(CornerFamily.ROUNDED, 50f) // 50% for circular

418

.build();

419

imageView.setShapeAppearanceModel(shapeAppearanceModel);

420

421

// Add stroke

422

imageView.setStrokeColor(ColorStateList.valueOf(Color.WHITE));

423

imageView.setStrokeWidth(4f);

424

425

// Diamond shape example

426

ShapeAppearanceModel diamondShape = ShapeAppearanceModel.builder()

427

.setAllCorners(CornerFamily.CUT, 50f)

428

.build();

429

imageView.setShapeAppearanceModel(diamondShape);

430

```

431

432

## Material Divider

433

434

Material Design divider for separating content sections.

435

436

```java { .api }

437

class MaterialDivider extends View {

438

MaterialDivider(Context context);

439

MaterialDivider(Context context, AttributeSet attrs);

440

441

// Color configuration

442

void setDividerColor(@ColorInt int color);

443

int getDividerColor();

444

void setDividerColorResource(@ColorRes int colorResourceId);

445

446

// Thickness configuration

447

void setDividerThickness(@Dimension int thickness);

448

int getDividerThickness();

449

void setDividerThicknessResource(@DimenRes int thicknessResourceId);

450

451

// Inset configuration

452

void setDividerInsetStart(@Dimension int insetStart);

453

int getDividerInsetStart();

454

void setDividerInsetStartResource(@DimenRes int insetStartResourceId);

455

void setDividerInsetEnd(@Dimension int insetEnd);

456

int getDividerInsetEnd();

457

void setDividerInsetEndResource(@DimenRes int insetEndResourceId);

458

}

459

```

460

461

## Material Divider Item Decoration

462

463

ItemDecoration for adding Material dividers to RecyclerView items.

464

465

```java { .api }

466

class MaterialDividerItemDecoration extends RecyclerView.ItemDecoration {

467

MaterialDividerItemDecoration(Context context, int orientation);

468

MaterialDividerItemDecoration(Context context, int orientation, int insetType);

469

470

// Color configuration

471

void setDividerColor(@ColorInt int color);

472

int getDividerColor();

473

void setDividerColorResource(@ColorRes int colorResourceId);

474

475

// Thickness configuration

476

void setDividerThickness(@Dimension int thickness);

477

int getDividerThickness();

478

void setDividerThicknessResource(@DimenRes int thicknessResourceId);

479

480

// Inset configuration

481

void setDividerInsetStart(@Dimension int insetStart);

482

int getDividerInsetStart();

483

void setDividerInsetStartResource(@DimenRes int insetStartResourceId);

484

void setDividerInsetEnd(@Dimension int insetEnd);

485

int getDividerInsetEnd();

486

void setDividerInsetEndResource(@DimenRes int insetEndResourceId);

487

488

// Last item decoration

489

void setLastItemDecorated(boolean lastItemDecorated);

490

boolean isLastItemDecorated();

491

}

492

```

493

494

### Divider Orientation Constants

495

496

```java { .api }

497

public static final int HORIZONTAL = LinearLayout.HORIZONTAL;

498

public static final int VERTICAL = LinearLayout.VERTICAL;

499

```

500

501

### Usage Example

502

503

```java

504

RecyclerView recyclerView = findViewById(R.id.recycler_view);

505

506

// Add vertical dividers between items

507

MaterialDividerItemDecoration dividerItemDecoration =

508

new MaterialDividerItemDecoration(this, MaterialDividerItemDecoration.VERTICAL);

509

510

// Configure divider appearance

511

dividerItemDecoration.setDividerColor(ContextCompat.getColor(this, R.color.divider_color));

512

dividerItemDecoration.setDividerThickness(1);

513

dividerItemDecoration.setDividerInsetStart(16);

514

dividerItemDecoration.setDividerInsetEnd(16);

515

516

// Don't show divider after last item

517

dividerItemDecoration.setLastItemDecorated(false);

518

519

// Add to RecyclerView

520

recyclerView.addItemDecoration(dividerItemDecoration);

521

```

522

523

## Behavior Utilities

524

525

Helper behaviors for common scrolling interactions.

526

527

### Hide Bottom View On Scroll Behavior

528

529

```java { .api }

530

class HideBottomViewOnScrollBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {

531

HideBottomViewOnScrollBehavior();

532

HideBottomViewOnScrollBehavior(Context context, AttributeSet attrs);

533

534

// Manual control

535

void slideUp(V child);

536

void slideDown(V child);

537

538

// State queries

539

boolean isScrolledUp();

540

boolean isScrolledDown();

541

}

542

```

543

544

### Swipe Dismiss Behavior

545

546

```java { .api }

547

class SwipeDismissBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {

548

SwipeDismissBehavior();

549

550

// Swipe direction

551

void setSwipeDirection(int direction);

552

int getSwipeDirection();

553

554

// Drag distances

555

void setDragDismissDistance(float distance);

556

float getDragDismissDistance();

557

void setStartAlphaSwipeDistance(float distance);

558

float getStartAlphaSwipeDistance();

559

void setEndAlphaSwipeDistance(float distance);

560

float getEndAlphaSwipeDistance();

561

562

// Sensitivity

563

void setSensitivity(float sensitivity);

564

float getSensitivity();

565

566

// Listener

567

void setListener(OnDismissListener listener);

568

}

569

570

interface SwipeDismissBehavior.OnDismissListener {

571

void onDismiss(View view);

572

void onDragStateChanged(int state);

573

}

574

```

575

576

### Swipe Direction Constants

577

578

```java { .api }

579

public static final int SWIPE_DIRECTION_START_TO_END = 0;

580

public static final int SWIPE_DIRECTION_END_TO_START = 1;

581

public static final int SWIPE_DIRECTION_ANY = 2;

582

```

583

584

## Layout Examples

585

586

### Coordinated Scrolling Layout

587

588

```java

589

// Activity with coordinated scrolling behavior

590

public class ScrollingActivity extends AppCompatActivity {

591

@Override

592

protected void onCreate(Bundle savedInstanceState) {

593

super.onCreate(savedInstanceState);

594

setContentView(R.layout.activity_scrolling);

595

596

// Setup toolbar

597

MaterialToolbar toolbar = findViewById(R.id.toolbar);

598

setSupportActionBar(toolbar);

599

600

// Configure collapsing toolbar

601

CollapsingToolbarLayout collapsingToolbar = findViewById(R.id.collapsing_toolbar);

602

collapsingToolbar.setTitle("Scrolling Example");

603

604

// Setup FloatingActionButton with hide behavior

605

FloatingActionButton fab = findViewById(R.id.fab);

606

CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();

607

params.setBehavior(new HideBottomViewOnScrollBehavior<FloatingActionButton>());

608

609

// Configure app bar scrolling

610

AppBarLayout appBarLayout = findViewById(R.id.app_bar_layout);

611

appBarLayout.addOnOffsetChangedListener((appBarLayout1, verticalOffset) -> {

612

// Update UI based on collapse state

613

float ratio = Math.abs(verticalOffset) / (float) appBarLayout1.getTotalScrollRange();

614

fab.setAlpha(1f - ratio);

615

});

616

}

617

}

618

```

619

620

### Card Grid Layout

621

622

```java

623

// Fragment with card grid and selection

624

public class CardGridFragment extends Fragment {

625

private RecyclerView recyclerView;

626

private CardAdapter adapter;

627

private Set<Integer> selectedItems = new HashSet<>();

628

629

@Nullable

630

@Override

631

public View onCreateView(@NonNull LayoutInflater inflater,

632

@Nullable ViewGroup container,

633

@Nullable Bundle savedInstanceState) {

634

View view = inflater.inflate(R.layout.fragment_card_grid, container, false);

635

636

recyclerView = view.findViewById(R.id.recycler_view);

637

setupRecyclerView();

638

639

return view;

640

}

641

642

private void setupRecyclerView() {

643

// Grid layout with 2 columns

644

GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2);

645

recyclerView.setLayoutManager(layoutManager);

646

647

// Add item spacing

648

int spacing = getResources().getDimensionPixelSize(R.dimen.card_spacing);

649

recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, spacing, true));

650

651

// Setup adapter

652

adapter = new CardAdapter(getCardData(), this::onCardClicked);

653

recyclerView.setAdapter(adapter);

654

}

655

656

private void onCardClicked(int position) {

657

if (selectedItems.contains(position)) {

658

selectedItems.remove(position);

659

} else {

660

selectedItems.add(position);

661

}

662

adapter.notifyItemChanged(position);

663

}

664

}

665

666

// Card adapter with selection support

667

class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder> {

668

private List<CardData> items;

669

private OnCardClickListener listener;

670

671

interface OnCardClickListener {

672

void onCardClick(int position);

673

}

674

675

class CardViewHolder extends RecyclerView.ViewHolder {

676

MaterialCardView cardView;

677

ImageView imageView;

678

TextView titleView;

679

680

CardViewHolder(View view) {

681

super(view);

682

cardView = view.findViewById(R.id.card_view);

683

imageView = view.findViewById(R.id.image_view);

684

titleView = view.findViewById(R.id.title_view);

685

686

cardView.setOnClickListener(v -> {

687

if (listener != null) {

688

listener.onCardClick(getAdapterPosition());

689

}

690

});

691

}

692

693

void bind(CardData data, boolean isSelected) {

694

titleView.setText(data.getTitle());

695

// Load image with Glide/Picasso

696

697

// Update selection state

698

cardView.setChecked(isSelected);

699

cardView.setStrokeWidth(isSelected ? 4 : 1);

700

}

701

}

702

}

703

```

704

705

## Carousel Components

706

707

### Carousel Layout Manager

708

709

A specialized RecyclerView LayoutManager for creating carousel-style layouts with masking and item transformation effects.

710

711

```java { .api }

712

public class CarouselLayoutManager extends RecyclerView.LayoutManager implements Carousel {

713

public CarouselLayoutManager();

714

public CarouselLayoutManager(Context context, AttributeSet attrs);

715

716

// Strategy management

717

public void setCarouselStrategy(CarouselStrategy carouselStrategy);

718

public CarouselStrategy getCarouselStrategy();

719

720

// Orientation

721

public void setOrientation(int orientation);

722

public int getOrientation();

723

724

// Debugging

725

public void setDebuggingEnabled(boolean isDebuggingEnabled);

726

public boolean isDebuggingEnabled();

727

728

// Scroll position

729

public void scrollToPosition(int position);

730

public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position);

731

732

// Constants

733

public static final int HORIZONTAL = 0;

734

public static final int VERTICAL = 1;

735

}

736

```

737

738

### Carousel Strategy

739

740

Abstract base class for defining carousel layout strategies.

741

742

```java { .api }

743

public abstract class CarouselStrategy {

744

// Strategy creation

745

public static CarouselStrategy createForFullScreen();

746

public static CarouselStrategy createForHero();

747

public static CarouselStrategy createForMultiBrowse();

748

public static CarouselStrategy createForUncontained();

749

750

// Abstract methods implemented by strategies

751

public abstract KeylineState onFirstChildMeasuredWithMargins(Carousel carousel, View child);

752

753

// Strategy types

754

public enum StrategyType {

755

CONTAINED, UNCONTAINED, FULL_SCREEN, HERO, MULTI_BROWSE

756

}

757

}

758

```

759

760

### Carousel Snap Helper

761

762

SnapHelper for carousel smooth snapping behavior.

763

764

```java { .api }

765

public class CarouselSnapHelper extends RecyclerView.SnapHelper {

766

public CarouselSnapHelper();

767

768

// Snap behavior

769

public void attachToRecyclerView(@Nullable RecyclerView recyclerView);

770

771

// Snap target calculation

772

public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY);

773

public View findSnapView(RecyclerView.LayoutManager layoutManager);

774

775

// Distance calculations

776

public int[] calculateDistanceToFinalSnap(RecyclerView.LayoutManager layoutManager, View targetView);

777

public RecyclerView.SmoothScroller createScroller(RecyclerView.LayoutManager layoutManager);

778

}

779

```

780

781

**Usage Example:**

782

783

```java

784

// Setup RecyclerView with Carousel

785

RecyclerView recyclerView = findViewById(R.id.carousel_recycler_view);

786

787

// Create and configure CarouselLayoutManager

788

CarouselLayoutManager layoutManager = new CarouselLayoutManager();

789

layoutManager.setCarouselStrategy(CarouselStrategy.createForHero());

790

recyclerView.setLayoutManager(layoutManager);

791

792

// Attach snap helper

793

CarouselSnapHelper snapHelper = new CarouselSnapHelper();

794

snapHelper.attachToRecyclerView(recyclerView);

795

796

// Set adapter (items must use MaskableFrameLayout as root)

797

CarouselAdapter adapter = new CarouselAdapter(carouselItems);

798

recyclerView.setAdapter(adapter);

799

800

// Optional: Enable debugging to see keylines

801

layoutManager.setDebuggingEnabled(BuildConfig.DEBUG);

802

```

803

804

### Carousel Item Layout Requirements

805

806

Carousel items must use MaskableFrameLayout as the root ViewGroup:

807

808

```xml

809

<com.google.android.material.carousel.MaskableFrameLayout

810

android:layout_width="200dp"

811

android:layout_height="200dp"

812

app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.ExtraLarge">

813

814

<ImageView

815

android:layout_width="match_parent"

816

android:layout_height="match_parent"

817

android:scaleType="centerCrop" />

818

819

<View

820

android:layout_width="match_parent"

821

android:layout_height="40dp"

822

android:layout_gravity="bottom"

823

android:background="@color/surface_variant" />

824

825

<TextView

826

android:layout_width="match_parent"

827

android:layout_height="wrap_content"

828

android:layout_gravity="bottom"

829

android:padding="8dp" />

830

831

</com.google.android.material.carousel.MaskableFrameLayout>

832

```