From ad6afbf6d85d81a85fa855830c8dadba43095905 Mon Sep 17 00:00:00 2001 From: rightnao Date: Fri, 30 Jun 2023 18:03:20 +0000 Subject: [PATCH] [Carousel][Catalog] Add fullscreen demo to catalog PiperOrigin-RevId: 544700979 --- .../catalog/carousel/CarouselFragment.java | 9 +- .../FullScreenStrategyDemoFragment.java | 171 ++++++++++++++++++ .../cat_carousel_bottom_sheet_contents.xml | 93 ++++++++++ .../cat_carousel_full_screen_fragment.xml | 54 ++++++ .../res/layout/cat_carousel_item_vertical.xml | 33 ++++ .../catalog/carousel/res/values/strings.xml | 6 + 6 files changed, 364 insertions(+), 2 deletions(-) create mode 100644 catalog/java/io/material/catalog/carousel/FullScreenStrategyDemoFragment.java create mode 100644 catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_bottom_sheet_contents.xml create mode 100644 catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_full_screen_fragment.xml create mode 100644 catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_item_vertical.xml diff --git a/catalog/java/io/material/catalog/carousel/CarouselFragment.java b/catalog/java/io/material/catalog/carousel/CarouselFragment.java index 09d8b77efee..f1bbb79c54c 100644 --- a/catalog/java/io/material/catalog/carousel/CarouselFragment.java +++ b/catalog/java/io/material/catalog/carousel/CarouselFragment.java @@ -73,13 +73,18 @@ public Fragment createFragment() { return new HeroCarouselDemoFragment(); } }, + new Demo(R.string.cat_carousel_fullscreen_demo_title) { + @Override + public Fragment createFragment() { + return new FullScreenStrategyDemoFragment(); + } + }, new Demo(R.string.cat_carousel_default_list_demo_title) { @Override public Fragment createFragment() { return new DefaultListDemoFragment(); } - } - ); + }); } /** The Dagger module for {@link CarouselFragment} dependencies. */ diff --git a/catalog/java/io/material/catalog/carousel/FullScreenStrategyDemoFragment.java b/catalog/java/io/material/catalog/carousel/FullScreenStrategyDemoFragment.java new file mode 100644 index 00000000000..b4b18df868b --- /dev/null +++ b/catalog/java/io/material/catalog/carousel/FullScreenStrategyDemoFragment.java @@ -0,0 +1,171 @@ +/* + * Copyright 2023 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 + * + * https://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.carousel; + +import io.material.catalog.R; + +import android.os.Bundle; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.SnapHelper; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.google.android.material.carousel.CarouselLayoutManager; +import com.google.android.material.carousel.CarouselSnapHelper; +import com.google.android.material.carousel.FullScreenCarouselStrategy; +import com.google.android.material.divider.MaterialDividerItemDecoration; +import com.google.android.material.materialswitch.MaterialSwitch; +import com.google.android.material.slider.Slider; +import com.google.android.material.slider.Slider.OnSliderTouchListener; +import io.material.catalog.feature.DemoFragment; + +/** A fragment that displays the fullscreen variant of the Carousel. */ +public class FullScreenStrategyDemoFragment extends DemoFragment { + + private MaterialDividerItemDecoration horizontalDivider; + private BottomSheetDialog bottomSheetDialog; + + @NonNull + @Override + public View onCreateDemoView( + @NonNull LayoutInflater layoutInflater, + @Nullable ViewGroup viewGroup, + @Nullable Bundle bundle) { + return layoutInflater.inflate( + R.layout.cat_carousel_full_screen_fragment, viewGroup, false /* attachToRoot */); + } + + @Override + @SuppressWarnings("RestrictTo") + public void onViewCreated(@NonNull View view, @Nullable Bundle bundle) { + super.onViewCreated(view, bundle); + + bottomSheetDialog = new BottomSheetDialog(view.getContext()); + bottomSheetDialog.setContentView(R.layout.cat_carousel_bottom_sheet_contents); + // Opt in to perform swipe to dismiss animation when dismissing bottom sheet dialog. + bottomSheetDialog.setDismissWithAnimation(true); + + horizontalDivider = + new MaterialDividerItemDecoration( + requireContext(), MaterialDividerItemDecoration.HORIZONTAL); + + Button showBottomSheetButton = view.findViewById(R.id.show_bottomsheet_button); + showBottomSheetButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + bottomSheetDialog.show(); + } + }); + + MaterialSwitch debugSwitch = bottomSheetDialog.findViewById(R.id.debug_switch); + MaterialSwitch drawDividers = bottomSheetDialog.findViewById(R.id.draw_dividers_switch); + MaterialSwitch enableFlingSwitch = bottomSheetDialog.findViewById(R.id.enable_fling_switch); + AutoCompleteTextView itemCountDropdown = + bottomSheetDialog.findViewById(R.id.item_count_dropdown); + Slider positionSlider = bottomSheetDialog.findViewById(R.id.position_slider); + + // A vertical fullscreen carousel + RecyclerView fullscreenRecyclerView = + view.findViewById(R.id.fullscreen_carousel_recycler_view); + CarouselLayoutManager carouselLayoutManager = + new CarouselLayoutManager(new FullScreenCarouselStrategy(), + RecyclerView.VERTICAL); + carouselLayoutManager.setDebuggingEnabled( + fullscreenRecyclerView, debugSwitch.isChecked()); + fullscreenRecyclerView.setLayoutManager(carouselLayoutManager); + fullscreenRecyclerView.setNestedScrollingEnabled(false); + + debugSwitch.setOnCheckedChangeListener( + (buttonView, isChecked) -> { + carouselLayoutManager.setOrientation(CarouselLayoutManager.VERTICAL); + fullscreenRecyclerView.setBackgroundResource( + isChecked ? R.drawable.dashed_outline_rectangle : 0); + carouselLayoutManager.setDebuggingEnabled( + fullscreenRecyclerView, isChecked); + }); + + drawDividers.setOnCheckedChangeListener( + (buttonView, isChecked) -> { + if (isChecked) { + fullscreenRecyclerView.addItemDecoration(horizontalDivider); + } else { + fullscreenRecyclerView.removeItemDecoration(horizontalDivider); + } + }); + + CarouselAdapter adapter = + new CarouselAdapter( + (item, position) -> fullscreenRecyclerView.scrollToPosition(position), + R.layout.cat_carousel_item_vertical); + + SnapHelper flingDisabledSnapHelper = new CarouselSnapHelper(); + SnapHelper flingEnabledSnapHelper = new CarouselSnapHelper(false); + + flingDisabledSnapHelper.attachToRecyclerView(fullscreenRecyclerView); + + enableFlingSwitch.setOnCheckedChangeListener( + (buttonView, isChecked) -> { + if (isChecked) { + flingDisabledSnapHelper.attachToRecyclerView(null); + flingEnabledSnapHelper.attachToRecyclerView(fullscreenRecyclerView); + } else { + flingEnabledSnapHelper.attachToRecyclerView(null); + flingDisabledSnapHelper.attachToRecyclerView(fullscreenRecyclerView); + } + }); + + itemCountDropdown.setOnItemClickListener( + (parent, view1, position, id) -> + adapter.submitList( + CarouselData.createItems().subList(0, position), + updateSliderRange(positionSlider, adapter))); + + positionSlider.addOnSliderTouchListener( + new OnSliderTouchListener() { + @Override + public void onStartTrackingTouch(@NonNull Slider slider) {} + + @Override + public void onStopTrackingTouch(@NonNull Slider slider) { + fullscreenRecyclerView.smoothScrollToPosition((int) slider.getValue() - 1); + } + }); + + fullscreenRecyclerView.setAdapter(adapter); + adapter.submitList(CarouselData.createItems(), updateSliderRange(positionSlider, adapter)); + } + + private static Runnable updateSliderRange(Slider slider, CarouselAdapter adapter) { + return () -> { + if (adapter.getItemCount() <= 1) { + slider.setEnabled(false); + return; + } + + slider.setValueFrom(1); + slider.setValue(1); + slider.setValueTo(adapter.getItemCount()); + slider.setEnabled(true); + }; + } +} diff --git a/catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_bottom_sheet_contents.xml b/catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_bottom_sheet_contents.xml new file mode 100644 index 00000000000..a1d793d0b56 --- /dev/null +++ b/catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_bottom_sheet_contents.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_full_screen_fragment.xml b/catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_full_screen_fragment.xml new file mode 100644 index 00000000000..ebfc5643305 --- /dev/null +++ b/catalog/java/io/material/catalog/carousel/res/layout/cat_carousel_full_screen_fragment.xml @@ -0,0 +1,54 @@ + + + + + + + +