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
```