Skip to content

Commit 7f17891

Browse files
afohrmandsn5ft
authored andcommitted
[Adaptive] [Side Sheet] Rebrand "Adaptive Sheets" demo to "Side Sheet".
PiperOrigin-RevId: 493759533 (cherry picked from commit f0a0538)
1 parent 3bc1f6e commit 7f17891

6 files changed

Lines changed: 610 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.material.catalog.sidesheet;
18+
19+
import io.material.catalog.R;
20+
21+
import androidx.fragment.app.Fragment;
22+
import androidx.annotation.NonNull;
23+
import dagger.Provides;
24+
import dagger.android.ContributesAndroidInjector;
25+
import dagger.multibindings.IntoSet;
26+
import io.material.catalog.application.scope.ActivityScope;
27+
import io.material.catalog.application.scope.FragmentScope;
28+
import io.material.catalog.feature.Demo;
29+
import io.material.catalog.feature.DemoLandingFragment;
30+
import io.material.catalog.feature.FeatureDemo;
31+
32+
/** A landing fragment that links to Side Sheet demos for the Catalog app. */
33+
public class SideSheetFragment extends DemoLandingFragment {
34+
35+
@Override
36+
public int getTitleResId() {
37+
return R.string.cat_sidesheet_title;
38+
}
39+
40+
@Override
41+
public int getDescriptionResId() {
42+
return R.string.cat_sidesheet_description;
43+
}
44+
45+
@NonNull
46+
@Override
47+
public Demo getMainDemo() {
48+
return new Demo() {
49+
@NonNull
50+
@Override
51+
public Fragment createFragment() {
52+
return new SideSheetMainDemoFragment();
53+
}
54+
};
55+
}
56+
57+
/** The Dagger module for {@link SideSheetMainDemoFragment} dependencies. */
58+
@dagger.Module
59+
public abstract static class Module {
60+
61+
@FragmentScope
62+
@ContributesAndroidInjector
63+
abstract SideSheetFragment contributeInjector();
64+
65+
@IntoSet
66+
@Provides
67+
@ActivityScope
68+
static FeatureDemo provideFeatureDemo() {
69+
return new FeatureDemo(R.string.cat_sidesheet_title, R.drawable.ic_side_navigation_24px) {
70+
@Override
71+
public Fragment createFragment() {
72+
return new SideSheetFragment();
73+
}
74+
};
75+
}
76+
}
77+
}
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.material.catalog.sidesheet;
18+
19+
import io.material.catalog.R;
20+
21+
import android.os.Bundle;
22+
import androidx.appcompat.app.AppCompatActivity;
23+
import androidx.appcompat.app.AppCompatDialog;
24+
import androidx.appcompat.widget.Toolbar;
25+
import android.view.LayoutInflater;
26+
import android.view.View;
27+
import android.view.ViewGroup;
28+
import android.widget.Button;
29+
import android.widget.TextView;
30+
import androidx.annotation.IdRes;
31+
import androidx.annotation.LayoutRes;
32+
import androidx.annotation.NonNull;
33+
import androidx.annotation.Nullable;
34+
import androidx.annotation.StringRes;
35+
import androidx.core.view.ViewCompat;
36+
import com.google.android.material.sidesheet.SideSheetBehavior;
37+
import com.google.android.material.sidesheet.SideSheetCallback;
38+
import com.google.android.material.sidesheet.SideSheetDialog;
39+
import io.material.catalog.feature.DemoFragment;
40+
import io.material.catalog.preferences.CatalogPreferencesHelper;
41+
42+
/** A fragment that displays the main Side Sheet demo for the Catalog app. */
43+
public final class SideSheetMainDemoFragment extends DemoFragment {
44+
45+
@Nullable private CatalogPreferencesHelper catalogPreferencesHelper;
46+
47+
@Override
48+
public void onCreate(@Nullable Bundle bundle) {
49+
super.onCreate(bundle);
50+
// The preferences helper is used in an adhoc way with the toolbar since the demo draws its own
51+
// action bar, in order to allow the side sheet to be 100% of the screen's height.
52+
catalogPreferencesHelper = new CatalogPreferencesHelper(getParentFragmentManager());
53+
}
54+
55+
@NonNull
56+
@Override
57+
public View onCreateDemoView(
58+
@NonNull LayoutInflater layoutInflater,
59+
@Nullable ViewGroup viewGroup,
60+
@Nullable Bundle bundle) {
61+
View view = layoutInflater.inflate(getDemoContent(), viewGroup, false /* attachToRoot */);
62+
setUpToolbar(view);
63+
64+
// Set up standard side sheet.
65+
View standardRightSideSheet =
66+
setUpSideSheet(
67+
view,
68+
R.id.standard_side_sheet_container,
69+
R.id.show_standard_side_sheet_button,
70+
R.id.close_icon_button);
71+
72+
setSideSheetCallback(
73+
standardRightSideSheet, R.id.side_sheet_state_text, R.id.side_sheet_slide_offset_text);
74+
75+
// Set up vertically scrolling side sheet.
76+
View verticallyScrollingSideSheet =
77+
setUpSideSheet(
78+
view,
79+
R.id.vertically_scrolling_side_sheet_container,
80+
R.id.show_vertically_scrolling_side_sheet_button,
81+
R.id.vertically_scrolling_side_sheet_close_icon_button);
82+
83+
setSideSheetCallback(
84+
verticallyScrollingSideSheet,
85+
R.id.vertically_scrolling_side_sheet_state_text,
86+
R.id.vertically_scrolling_side_sheet_slide_offset_text);
87+
88+
// Set up modal side sheet.
89+
SideSheetDialog sideSheetDialog = new SideSheetDialog(requireContext());
90+
setUpModalSheet(
91+
sideSheetDialog,
92+
R.layout.cat_sidesheet_content,
93+
R.id.m3_side_sheet,
94+
R.id.side_sheet_title_text,
95+
R.string.cat_sidesheet_modal_title);
96+
97+
sideSheetDialog.setDismissWithSheetAnimationEnabled(true);
98+
View showModalSideSheetButton = view.findViewById(R.id.show_modal_side_sheet_button);
99+
showModalSideSheetButton.setOnClickListener(v -> sideSheetDialog.show());
100+
101+
sideSheetDialog
102+
.getBehavior()
103+
.addCallback(
104+
createSideSheetCallback(
105+
sideSheetDialog.findViewById(R.id.side_sheet_state_text),
106+
sideSheetDialog.findViewById(R.id.side_sheet_slide_offset_text)));
107+
108+
View modalSideSheetCloseIconButton = sideSheetDialog.findViewById(R.id.close_icon_button);
109+
if (modalSideSheetCloseIconButton != null) {
110+
modalSideSheetCloseIconButton.setOnClickListener(v -> sideSheetDialog.hide());
111+
}
112+
113+
return view;
114+
}
115+
116+
private View setUpSideSheet(
117+
@NonNull View view,
118+
@IdRes int sideSheetContainerId,
119+
@IdRes int showSideSheetButtonId,
120+
@IdRes int closeIconButtonId) {
121+
View sideSheet = view.findViewById(sideSheetContainerId);
122+
SideSheetBehavior<View> sideSheetBehavior = SideSheetBehavior.from(sideSheet);
123+
124+
Button showSideSheetButton = view.findViewById(showSideSheetButtonId);
125+
showSideSheetButton.setOnClickListener(unusedView -> showSideSheet(sideSheetBehavior));
126+
127+
View standardSideSheetCloseIconButton = sideSheet.findViewById(closeIconButtonId);
128+
standardSideSheetCloseIconButton.setOnClickListener(v -> hideSideSheet(sideSheetBehavior));
129+
130+
return sideSheet;
131+
}
132+
133+
private void setSideSheetCallback(
134+
View sideSheet, @IdRes int stateTextViewId, @IdRes int slideOffsetTextId) {
135+
SideSheetBehavior<View> sideSheetBehavior = SideSheetBehavior.from(sideSheet);
136+
sideSheetBehavior.addCallback(
137+
createSideSheetCallback(
138+
sideSheet.findViewById(stateTextViewId), sideSheet.findViewById(slideOffsetTextId)));
139+
}
140+
141+
private void setUpModalSheet(
142+
@NonNull AppCompatDialog sheetDialog,
143+
@LayoutRes int sheetContentLayoutRes,
144+
@IdRes int sheetContentRootIdRes,
145+
@IdRes int sheetTitleIdRes,
146+
@StringRes int sheetTitleStringRes) {
147+
sheetDialog.setContentView(sheetContentLayoutRes);
148+
View modalSheetContent = sheetDialog.findViewById(sheetContentRootIdRes);
149+
if (modalSheetContent != null) {
150+
TextView modalSideSheetTitle = modalSheetContent.findViewById(sheetTitleIdRes);
151+
modalSideSheetTitle.setText(sheetTitleStringRes);
152+
}
153+
}
154+
155+
private void setUpToolbar(@NonNull View view) {
156+
@NonNull Toolbar toolbar = ViewCompat.requireViewById(view, R.id.toolbar);
157+
@Nullable AppCompatActivity activity = (AppCompatActivity) getActivity();
158+
if (activity != null) {
159+
toolbar.setNavigationOnClickListener(v -> activity.onBackPressed());
160+
if (catalogPreferencesHelper != null) {
161+
catalogPreferencesHelper.onCreateOptionsMenu(toolbar.getMenu(), activity.getMenuInflater());
162+
toolbar.setOnMenuItemClickListener(catalogPreferencesHelper::onOptionsItemSelected);
163+
}
164+
}
165+
}
166+
167+
private void showSideSheet(SideSheetBehavior<View> sheetBehavior) {
168+
sheetBehavior.expand();
169+
}
170+
171+
private void hideSideSheet(SideSheetBehavior<View> sheetBehavior) {
172+
sheetBehavior.hide();
173+
}
174+
175+
@LayoutRes
176+
int getDemoContent() {
177+
return R.layout.cat_sidesheet_fragment;
178+
}
179+
180+
@Override
181+
public boolean shouldShowDefaultDemoActionBar() {
182+
return false;
183+
}
184+
185+
private SideSheetCallback createSideSheetCallback(
186+
TextView stateTextView, TextView slideOffsetTextView) {
187+
return new SideSheetCallback() {
188+
@Override
189+
public void onStateChanged(@NonNull View sheet, int newState) {
190+
switch (newState) {
191+
case SideSheetBehavior.STATE_DRAGGING:
192+
stateTextView.setText(R.string.cat_sidesheet_state_dragging);
193+
break;
194+
case SideSheetBehavior.STATE_EXPANDED:
195+
stateTextView.setText(R.string.cat_sidesheet_state_expanded);
196+
break;
197+
case SideSheetBehavior.STATE_SETTLING:
198+
stateTextView.setText(R.string.cat_sidesheet_state_settling);
199+
break;
200+
case SideSheetBehavior.STATE_HIDDEN:
201+
default:
202+
break;
203+
}
204+
}
205+
206+
@Override
207+
public void onSlide(@NonNull View sheet, float slideOffset) {
208+
slideOffsetTextView.setText(
209+
getResources().getString(R.string.cat_sidesheet_slide_offset_text, slideOffset));
210+
}
211+
};
212+
}
213+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
Copyright 2022 The Android Open Source Project
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
17+
xmlns:app="http://schemas.android.com/apk/res-auto"
18+
xmlns:tools="http://schemas.android.com/tools"
19+
android:layout_width="match_parent"
20+
android:layout_height="match_parent"
21+
android:padding="24dp"
22+
android:clickable="true"
23+
android:focusable="true"
24+
android:gravity="center_horizontal"
25+
android:orientation="vertical">
26+
27+
<Button
28+
android:id="@+id/close_icon_button"
29+
style="?attr/materialIconButtonStyle"
30+
android:layout_width="wrap_content"
31+
android:layout_height="wrap_content"
32+
android:contentDescription="@string/cat_sidesheet_close_button_content_desc"
33+
app:icon="@drawable/ic_close_vd_theme_24px"
34+
app:layout_constraintEnd_toEndOf="parent"
35+
app:layout_constraintTop_toTopOf="@id/side_sheet_title_text"
36+
tools:ignore="ContentDescription" />
37+
38+
<TextView
39+
android:id="@+id/side_sheet_title_text"
40+
android:layout_width="0dp"
41+
android:layout_height="wrap_content"
42+
android:text="@string/cat_sidesheet_standard_title"
43+
android:textAppearance="?attr/textAppearanceHeadlineSmall"
44+
app:layout_constraintEnd_toStartOf="@id/close_icon_button"
45+
app:layout_constraintStart_toStartOf="parent"
46+
app:layout_constraintTop_toTopOf="parent" />
47+
48+
<TextView
49+
android:id="@+id/side_sheet_state_text"
50+
android:layout_width="wrap_content"
51+
android:layout_height="wrap_content"
52+
android:text="@string/cat_sidesheet_state_settling"
53+
android:textAppearance="?attr/textAppearanceHeadlineSmall"
54+
app:layout_constraintEnd_toEndOf="parent"
55+
app:layout_constraintStart_toStartOf="parent"
56+
app:layout_constraintTop_toBottomOf="@id/side_sheet_title_text" />
57+
58+
<TextView
59+
android:id="@+id/side_sheet_slide_offset_text"
60+
android:layout_width="wrap_content"
61+
android:layout_height="wrap_content"
62+
android:text="@string/cat_sidesheet_slide_offset_text"
63+
android:textAppearance="?attr/textAppearanceHeadlineSmall"
64+
app:layout_constraintEnd_toEndOf="parent"
65+
app:layout_constraintStart_toStartOf="parent"
66+
app:layout_constraintTop_toBottomOf="@id/side_sheet_state_text" />
67+
68+
</androidx.constraintlayout.widget.ConstraintLayout>

0 commit comments

Comments
 (0)