-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Adaptive] [Side Sheet] Rebrand "Adaptive Sheets" demo to "Side Sheet".
PiperOrigin-RevId: 493759533
- Loading branch information
Showing
6 changed files
with
610 additions
and
0 deletions.
There are no files selected for viewing
77 changes: 77 additions & 0 deletions
77
catalog/java/io/material/catalog/sidesheet/SideSheetFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright 2022 The Android Open Source Project | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.material.catalog.sidesheet; | ||
|
||
import io.material.catalog.R; | ||
|
||
import androidx.fragment.app.Fragment; | ||
import androidx.annotation.NonNull; | ||
import dagger.Provides; | ||
import dagger.android.ContributesAndroidInjector; | ||
import dagger.multibindings.IntoSet; | ||
import io.material.catalog.application.scope.ActivityScope; | ||
import io.material.catalog.application.scope.FragmentScope; | ||
import io.material.catalog.feature.Demo; | ||
import io.material.catalog.feature.DemoLandingFragment; | ||
import io.material.catalog.feature.FeatureDemo; | ||
|
||
/** A landing fragment that links to Side Sheet demos for the Catalog app. */ | ||
public class SideSheetFragment extends DemoLandingFragment { | ||
|
||
@Override | ||
public int getTitleResId() { | ||
return R.string.cat_sidesheet_title; | ||
} | ||
|
||
@Override | ||
public int getDescriptionResId() { | ||
return R.string.cat_sidesheet_description; | ||
} | ||
|
||
@NonNull | ||
@Override | ||
public Demo getMainDemo() { | ||
return new Demo() { | ||
@NonNull | ||
@Override | ||
public Fragment createFragment() { | ||
return new SideSheetMainDemoFragment(); | ||
} | ||
}; | ||
} | ||
|
||
/** The Dagger module for {@link SideSheetMainDemoFragment} dependencies. */ | ||
@dagger.Module | ||
public abstract static class Module { | ||
|
||
@FragmentScope | ||
@ContributesAndroidInjector | ||
abstract SideSheetFragment contributeInjector(); | ||
|
||
@IntoSet | ||
@Provides | ||
@ActivityScope | ||
static FeatureDemo provideFeatureDemo() { | ||
return new FeatureDemo(R.string.cat_sidesheet_title, R.drawable.ic_side_navigation_24px) { | ||
@Override | ||
public Fragment createFragment() { | ||
return new SideSheetFragment(); | ||
} | ||
}; | ||
} | ||
} | ||
} |
213 changes: 213 additions & 0 deletions
213
catalog/java/io/material/catalog/sidesheet/SideSheetMainDemoFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
/* | ||
* Copyright 2022 The Android Open Source Project | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.material.catalog.sidesheet; | ||
|
||
import io.material.catalog.R; | ||
|
||
import android.os.Bundle; | ||
import androidx.appcompat.app.AppCompatActivity; | ||
import androidx.appcompat.app.AppCompatDialog; | ||
import androidx.appcompat.widget.Toolbar; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.Button; | ||
import android.widget.TextView; | ||
import androidx.annotation.IdRes; | ||
import androidx.annotation.LayoutRes; | ||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
import androidx.annotation.StringRes; | ||
import androidx.core.view.ViewCompat; | ||
import com.google.android.material.sidesheet.SideSheetBehavior; | ||
import com.google.android.material.sidesheet.SideSheetCallback; | ||
import com.google.android.material.sidesheet.SideSheetDialog; | ||
import io.material.catalog.feature.DemoFragment; | ||
import io.material.catalog.preferences.CatalogPreferencesHelper; | ||
|
||
/** A fragment that displays the main Side Sheet demo for the Catalog app. */ | ||
public final class SideSheetMainDemoFragment extends DemoFragment { | ||
|
||
@Nullable private CatalogPreferencesHelper catalogPreferencesHelper; | ||
|
||
@Override | ||
public void onCreate(@Nullable Bundle bundle) { | ||
super.onCreate(bundle); | ||
// The preferences helper is used in an adhoc way with the toolbar since the demo draws its own | ||
// action bar, in order to allow the side sheet to be 100% of the screen's height. | ||
catalogPreferencesHelper = new CatalogPreferencesHelper(getParentFragmentManager()); | ||
} | ||
|
||
@NonNull | ||
@Override | ||
public View onCreateDemoView( | ||
@NonNull LayoutInflater layoutInflater, | ||
@Nullable ViewGroup viewGroup, | ||
@Nullable Bundle bundle) { | ||
View view = layoutInflater.inflate(getDemoContent(), viewGroup, false /* attachToRoot */); | ||
setUpToolbar(view); | ||
|
||
// Set up standard side sheet. | ||
View standardRightSideSheet = | ||
setUpSideSheet( | ||
view, | ||
R.id.standard_side_sheet_container, | ||
R.id.show_standard_side_sheet_button, | ||
R.id.close_icon_button); | ||
|
||
setSideSheetCallback( | ||
standardRightSideSheet, R.id.side_sheet_state_text, R.id.side_sheet_slide_offset_text); | ||
|
||
// Set up vertically scrolling side sheet. | ||
View verticallyScrollingSideSheet = | ||
setUpSideSheet( | ||
view, | ||
R.id.vertically_scrolling_side_sheet_container, | ||
R.id.show_vertically_scrolling_side_sheet_button, | ||
R.id.vertically_scrolling_side_sheet_close_icon_button); | ||
|
||
setSideSheetCallback( | ||
verticallyScrollingSideSheet, | ||
R.id.vertically_scrolling_side_sheet_state_text, | ||
R.id.vertically_scrolling_side_sheet_slide_offset_text); | ||
|
||
// Set up modal side sheet. | ||
SideSheetDialog sideSheetDialog = new SideSheetDialog(requireContext()); | ||
setUpModalSheet( | ||
sideSheetDialog, | ||
R.layout.cat_sidesheet_content, | ||
R.id.m3_side_sheet, | ||
R.id.side_sheet_title_text, | ||
R.string.cat_sidesheet_modal_title); | ||
|
||
sideSheetDialog.setDismissWithSheetAnimationEnabled(true); | ||
View showModalSideSheetButton = view.findViewById(R.id.show_modal_side_sheet_button); | ||
showModalSideSheetButton.setOnClickListener(v -> sideSheetDialog.show()); | ||
|
||
sideSheetDialog | ||
.getBehavior() | ||
.addCallback( | ||
createSideSheetCallback( | ||
sideSheetDialog.findViewById(R.id.side_sheet_state_text), | ||
sideSheetDialog.findViewById(R.id.side_sheet_slide_offset_text))); | ||
|
||
View modalSideSheetCloseIconButton = sideSheetDialog.findViewById(R.id.close_icon_button); | ||
if (modalSideSheetCloseIconButton != null) { | ||
modalSideSheetCloseIconButton.setOnClickListener(v -> sideSheetDialog.hide()); | ||
} | ||
|
||
return view; | ||
} | ||
|
||
private View setUpSideSheet( | ||
@NonNull View view, | ||
@IdRes int sideSheetContainerId, | ||
@IdRes int showSideSheetButtonId, | ||
@IdRes int closeIconButtonId) { | ||
View sideSheet = view.findViewById(sideSheetContainerId); | ||
SideSheetBehavior<View> sideSheetBehavior = SideSheetBehavior.from(sideSheet); | ||
|
||
Button showSideSheetButton = view.findViewById(showSideSheetButtonId); | ||
showSideSheetButton.setOnClickListener(unusedView -> showSideSheet(sideSheetBehavior)); | ||
|
||
View standardSideSheetCloseIconButton = sideSheet.findViewById(closeIconButtonId); | ||
standardSideSheetCloseIconButton.setOnClickListener(v -> hideSideSheet(sideSheetBehavior)); | ||
|
||
return sideSheet; | ||
} | ||
|
||
private void setSideSheetCallback( | ||
View sideSheet, @IdRes int stateTextViewId, @IdRes int slideOffsetTextId) { | ||
SideSheetBehavior<View> sideSheetBehavior = SideSheetBehavior.from(sideSheet); | ||
sideSheetBehavior.addCallback( | ||
createSideSheetCallback( | ||
sideSheet.findViewById(stateTextViewId), sideSheet.findViewById(slideOffsetTextId))); | ||
} | ||
|
||
private void setUpModalSheet( | ||
@NonNull AppCompatDialog sheetDialog, | ||
@LayoutRes int sheetContentLayoutRes, | ||
@IdRes int sheetContentRootIdRes, | ||
@IdRes int sheetTitleIdRes, | ||
@StringRes int sheetTitleStringRes) { | ||
sheetDialog.setContentView(sheetContentLayoutRes); | ||
View modalSheetContent = sheetDialog.findViewById(sheetContentRootIdRes); | ||
if (modalSheetContent != null) { | ||
TextView modalSideSheetTitle = modalSheetContent.findViewById(sheetTitleIdRes); | ||
modalSideSheetTitle.setText(sheetTitleStringRes); | ||
} | ||
} | ||
|
||
private void setUpToolbar(@NonNull View view) { | ||
@NonNull Toolbar toolbar = ViewCompat.requireViewById(view, R.id.toolbar); | ||
@Nullable AppCompatActivity activity = (AppCompatActivity) getActivity(); | ||
if (activity != null) { | ||
toolbar.setNavigationOnClickListener(v -> activity.onBackPressed()); | ||
if (catalogPreferencesHelper != null) { | ||
catalogPreferencesHelper.onCreateOptionsMenu(toolbar.getMenu(), activity.getMenuInflater()); | ||
toolbar.setOnMenuItemClickListener(catalogPreferencesHelper::onOptionsItemSelected); | ||
} | ||
} | ||
} | ||
|
||
private void showSideSheet(SideSheetBehavior<View> sheetBehavior) { | ||
sheetBehavior.expand(); | ||
} | ||
|
||
private void hideSideSheet(SideSheetBehavior<View> sheetBehavior) { | ||
sheetBehavior.hide(); | ||
} | ||
|
||
@LayoutRes | ||
int getDemoContent() { | ||
return R.layout.cat_sidesheet_fragment; | ||
} | ||
|
||
@Override | ||
public boolean shouldShowDefaultDemoActionBar() { | ||
return false; | ||
} | ||
|
||
private SideSheetCallback createSideSheetCallback( | ||
TextView stateTextView, TextView slideOffsetTextView) { | ||
return new SideSheetCallback() { | ||
@Override | ||
public void onStateChanged(@NonNull View sheet, int newState) { | ||
switch (newState) { | ||
case SideSheetBehavior.STATE_DRAGGING: | ||
stateTextView.setText(R.string.cat_sidesheet_state_dragging); | ||
break; | ||
case SideSheetBehavior.STATE_EXPANDED: | ||
stateTextView.setText(R.string.cat_sidesheet_state_expanded); | ||
break; | ||
case SideSheetBehavior.STATE_SETTLING: | ||
stateTextView.setText(R.string.cat_sidesheet_state_settling); | ||
break; | ||
case SideSheetBehavior.STATE_HIDDEN: | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
@Override | ||
public void onSlide(@NonNull View sheet, float slideOffset) { | ||
slideOffsetTextView.setText( | ||
getResources().getString(R.string.cat_sidesheet_slide_offset_text, slideOffset)); | ||
} | ||
}; | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
catalog/java/io/material/catalog/sidesheet/res/layout/cat_sidesheet_content.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?xml version="1.0" encoding="utf-8"?><!-- | ||
Copyright 2022 The Android Open Source Project | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:padding="24dp" | ||
android:clickable="true" | ||
android:focusable="true" | ||
android:gravity="center_horizontal" | ||
android:orientation="vertical"> | ||
|
||
<Button | ||
android:id="@+id/close_icon_button" | ||
style="?attr/materialIconButtonStyle" | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:contentDescription="@string/cat_sidesheet_close_button_content_desc" | ||
app:icon="@drawable/ic_close_vd_theme_24px" | ||
app:layout_constraintEnd_toEndOf="parent" | ||
app:layout_constraintTop_toTopOf="@id/side_sheet_title_text" | ||
tools:ignore="ContentDescription" /> | ||
|
||
<TextView | ||
android:id="@+id/side_sheet_title_text" | ||
android:layout_width="0dp" | ||
android:layout_height="wrap_content" | ||
android:text="@string/cat_sidesheet_standard_title" | ||
android:textAppearance="?attr/textAppearanceHeadlineSmall" | ||
app:layout_constraintEnd_toStartOf="@id/close_icon_button" | ||
app:layout_constraintStart_toStartOf="parent" | ||
app:layout_constraintTop_toTopOf="parent" /> | ||
|
||
<TextView | ||
android:id="@+id/side_sheet_state_text" | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:text="@string/cat_sidesheet_state_settling" | ||
android:textAppearance="?attr/textAppearanceHeadlineSmall" | ||
app:layout_constraintEnd_toEndOf="parent" | ||
app:layout_constraintStart_toStartOf="parent" | ||
app:layout_constraintTop_toBottomOf="@id/side_sheet_title_text" /> | ||
|
||
<TextView | ||
android:id="@+id/side_sheet_slide_offset_text" | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:text="@string/cat_sidesheet_slide_offset_text" | ||
android:textAppearance="?attr/textAppearanceHeadlineSmall" | ||
app:layout_constraintEnd_toEndOf="parent" | ||
app:layout_constraintStart_toStartOf="parent" | ||
app:layout_constraintTop_toBottomOf="@id/side_sheet_state_text" /> | ||
|
||
</androidx.constraintlayout.widget.ConstraintLayout> |
Oops, something went wrong.