Skip to content

Commit

Permalink
[Adaptive] [Canonical Layouts] Added hero element to small screen con…
Browse files Browse the repository at this point in the history
…figurations.

The hero element was missing from compact width size screens in our single view hero canonical layout demo. This was WAI/following the mocks, but it turns out this was a "design bug" and the mocks were wrong. The demo is now updated to include the hero element as the point of focus.

Also updated the title text appearance and a whole bunch of margins that weren't to spec or could use improvement.

PiperOrigin-RevId: 429571537
  • Loading branch information
afohrman authored and hunterstich committed Feb 23, 2022
1 parent 2ce5f3b commit 0803a22
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 36 deletions.
Expand Up @@ -51,9 +51,8 @@ public View onCreateView(

// Set up constraint sets.
ConstraintLayout constraintLayout = view.findViewById(R.id.hero_constraint_layout);
ConstraintSet smallLayout = new ConstraintSet();
smallLayout.clone(constraintLayout);
ConstraintSet mediumLayout = getMediumLayout(constraintLayout);
ConstraintSet smallLayout = getSmallLayout(constraintLayout);
ConstraintSet mediumLayout = getMediumLayout(smallLayout);
ConstraintSet largeLayout = getLargeLayout(mediumLayout);

int screenWidth = getResources().getConfiguration().screenWidthDp;
Expand All @@ -68,16 +67,25 @@ public View onCreateView(
return view;
}

/* Returns the constraint set to be used for the medium layout configuration. */
private ConstraintSet getMediumLayout(@NonNull ConstraintLayout constraintLayout) {
int marginVertical =
getResources().getDimensionPixelOffset(R.dimen.cat_adaptive_margin_vertical);
int marginHorizontal =
getResources().getDimensionPixelOffset(R.dimen.cat_adaptive_margin_horizontal);
/* Returns the constraint set to be used for the small layout configuration. */
private ConstraintSet getSmallLayout(@NonNull ConstraintLayout constraintLayout) {
ConstraintSet constraintSet = new ConstraintSet();
// Use the constraint set from the constraint layout.
constraintSet.clone(constraintLayout);
// Hero container.
constraintSet.setVisibility(R.id.hero_top_content, View.VISIBLE);
return constraintSet;
}

/* Returns the constraint set to be used for the medium layout configuration. */
private ConstraintSet getMediumLayout(@NonNull ConstraintSet smallLayout) {
int marginHorizontal = getResources().getDimensionPixelOffset(R.dimen.cat_adaptive_hero_margin);
int noMargin = getResources().getDimensionPixelOffset(R.dimen.cat_adaptive_margin_none);
int marginHorizontalAdditional =
getResources()
.getDimensionPixelOffset(R.dimen.cat_adaptive_hero_margin_horizontal_additional);

ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(smallLayout);

// Main content.
constraintSet.connect(
R.id.hero_main_content, ConstraintSet.TOP, R.id.hero_top_content, ConstraintSet.BOTTOM);
Expand All @@ -91,8 +99,11 @@ private ConstraintSet getMediumLayout(@NonNull ConstraintLayout constraintLayout
ConstraintSet.BOTTOM,
ConstraintSet.PARENT_ID,
ConstraintSet.BOTTOM);
constraintSet.setMargin(R.id.hero_main_content, ConstraintSet.TOP, marginVertical);
constraintSet.setMargin(R.id.hero_main_content, ConstraintSet.END, marginHorizontal);
constraintSet.setMargin(R.id.hero_top_content, ConstraintSet.START, noMargin);
constraintSet.setMargin(R.id.hero_top_content, ConstraintSet.LEFT, noMargin);
constraintSet.setMargin(R.id.hero_top_content, ConstraintSet.END, marginHorizontalAdditional);
constraintSet.setMargin(R.id.hero_top_content, ConstraintSet.RIGHT, marginHorizontalAdditional);

// Side content.
constraintSet.connect(
R.id.hero_side_content_container,
Expand All @@ -106,13 +117,24 @@ private ConstraintSet getMediumLayout(@NonNull ConstraintLayout constraintLayout
ConstraintSet.END);
constraintSet.constrainPercentWidth(R.id.hero_side_content_container, 0.4f);

constraintSet.setMargin(
R.id.hero_side_content_container, ConstraintSet.START, marginHorizontal);
constraintSet.setMargin(R.id.hero_side_content_container, ConstraintSet.LEFT, marginHorizontal);

// Add more margin to the right/end of the side content to make sure there is a 24dp margin on
// the right/end of the side content.
constraintSet.setMargin(
R.id.hero_side_content_container, ConstraintSet.RIGHT, marginHorizontalAdditional);
constraintSet.setMargin(
R.id.hero_side_content_container, ConstraintSet.END, marginHorizontalAdditional);
return constraintSet;
}

/* Returns the constraint set to be used for the large layout configuration. */
private ConstraintSet getLargeLayout(@NonNull ConstraintSet mediumLayout) {
int marginHorizontal =
getResources().getDimensionPixelOffset(R.dimen.cat_adaptive_margin_horizontal);
int noMargin = getResources().getDimensionPixelOffset(R.dimen.cat_adaptive_margin_none);
int marginHorizontal = getResources().getDimensionPixelOffset(R.dimen.cat_adaptive_hero_margin);

ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(mediumLayout);
// Hero container.
Expand All @@ -121,14 +143,20 @@ private ConstraintSet getLargeLayout(@NonNull ConstraintSet mediumLayout) {
ConstraintSet.END,
R.id.hero_side_content_container,
ConstraintSet.START);
constraintSet.setMargin(R.id.hero_top_content, ConstraintSet.END, marginHorizontal);

// Side content.
constraintSet.connect(
R.id.hero_side_content_container,
ConstraintSet.TOP,
ConstraintSet.PARENT_ID,
ConstraintSet.TOP);

// Remove the margin from the main content since it no longer is at the right/end side.
constraintSet.setMargin(R.id.hero_main_content, ConstraintSet.RIGHT, noMargin);
constraintSet.setMargin(R.id.hero_main_content, ConstraintSet.END, noMargin);

constraintSet.setMargin(R.id.hero_top_content, ConstraintSet.RIGHT, marginHorizontal);
constraintSet.setMargin(R.id.hero_top_content, ConstraintSet.END, marginHorizontal);
return constraintSet;
}

Expand Down
Expand Up @@ -17,39 +17,46 @@

<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/hero_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:clipChildren="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/hero_constraint_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">

android:layout_height="wrap_content"
android:layout_marginStart="@dimen/cat_adaptive_hero_margin"
android:layout_marginEnd="@dimen/cat_adaptive_hero_margin"
android:layout_marginLeft="@dimen/cat_adaptive_hero_margin"
android:layout_marginRight="@dimen/cat_adaptive_hero_margin">
<com.google.android.material.card.MaterialCardView
android:id="@+id/hero_top_content"
android:visibility="gone"
android:layout_width="0dp"
android:layout_height="362dp"
android:layout_height="0dp"
android:layout_marginTop="@dimen/cat_adaptive_hero_margin"
android:layout_marginStart="-16dp"
android:layout_marginLeft="-16dp"
android:layout_marginEnd="-16dp"
android:layout_marginRight="-16dp"
app:layout_constrainedWidth="true"
android:layout_marginTop="16dp"
app:layout_constraintHeight_min="310dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:strokeWidth="0dp"
app:cardBackgroundColor="?attr/colorSurfaceVariant"/>
app:cardBackgroundColor="?attr/colorSurfaceVariant"
tools:ignore="NegativeMargin" />

<com.google.android.material.card.MaterialCardView
android:id="@+id/hero_main_content"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHeight_min="437dp"
app:layout_constraintHeight_min="200dp"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/cat_adaptive_hero_margin"
app:layout_constraintTop_toBottomOf="@id/hero_top_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:strokeColor="?attr/colorSurfaceVariant"/>
Expand All @@ -58,23 +65,23 @@
android:id="@+id/hero_side_content_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="@dimen/cat_adaptive_hero_margin"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="1"
android:orientation="vertical"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/hero_main_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:layout_marginBottom="6dp"
android:textAppearance="?attr/textAppearanceSubtitle1"
android:text="@string/cat_hero_fragment_title"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/hero_side_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content" />
</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
Expand Down
Expand Up @@ -18,4 +18,9 @@
<resources>
<dimen name="cat_adaptive_margin_horizontal">12dp</dimen>
<dimen name="cat_adaptive_margin_vertical">16dp</dimen>
<dimen name="cat_adaptive_margin_none">0dp</dimen>

<dimen name="cat_adaptive_hero_margin">16dp</dimen>
<!-- Add 8dp to the existing 16dp margin to get 24dp. -->
<dimen name="cat_adaptive_hero_margin_horizontal_additional">8dp</dimen>
</resources>
7 changes: 4 additions & 3 deletions docs/adaptive/CanonicalLayouts.md
Expand Up @@ -396,9 +396,10 @@ Landscape:

!["Single View Hero demo landscape in landscape."](assets/canonical_layouts/hero_landscape.png)

This demo is an example of a layout that shows a main content view followed by a
list view of supporting items. In bigger screens it also reveals a large top
content view on top, also called a hero view.
This demo shows a large top content view on top of the layout, also called a
hero view, as well as a main content view and a list view of supporting items.
The hero and other containers take on different layout configurations depending
on the screen size.

### Implementation

Expand Down

0 comments on commit 0803a22

Please sign in to comment.