Skip to content

Commit

Permalink
[Carousel] Release carousel component
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 501635363
  • Loading branch information
hunterstich committed Jan 12, 2023
1 parent b892849 commit 4ecba81
Show file tree
Hide file tree
Showing 50 changed files with 5,004 additions and 3 deletions.
1 change: 1 addition & 0 deletions catalog/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def srcDirs = [
'bottomsheet',
'button',
'card',
'carousel',
'checkbox',
'chip',
'color',
Expand Down
66 changes: 66 additions & 0 deletions catalog/java/io/material/catalog/carousel/CarouselAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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
*
* 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 androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.DiffUtil;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;

/** An adapter that displays {@link CarouselItem}s for a Carousel. */
class CarouselAdapter extends ListAdapter<CarouselItem, CarouselItemViewHolder> {

private static final DiffUtil.ItemCallback<CarouselItem> DIFF_CALLBACK =
new DiffUtil.ItemCallback<CarouselItem>() {
@Override
public boolean areItemsTheSame(
@NonNull CarouselItem oldItem, @NonNull CarouselItem newItem) {
// User properties may have changed if reloaded from the DB, but ID is fixed
return oldItem == newItem;
}

@Override
public boolean areContentsTheSame(
@NonNull CarouselItem oldItem, @NonNull CarouselItem newItem) {
return false;
}
};

private final CarouselItemListener listener;

CarouselAdapter(CarouselItemListener listener) {
super(DIFF_CALLBACK);
this.listener = listener;
}

@NonNull
@Override
public CarouselItemViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int pos) {
return new CarouselItemViewHolder(
LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.cat_carousel_item, viewGroup, false), listener);
}

@Override
public void onBindViewHolder(@NonNull CarouselItemViewHolder carouselItemViewHolder, int pos) {
carouselItemViewHolder.bind(getItem(pos));
}

}
45 changes: 45 additions & 0 deletions catalog/java/io/material/catalog/carousel/CarouselData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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
*
* 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 java.util.Arrays;
import java.util.List;

/**
* A data store used to populate Carousels.
*/
class CarouselData {

private CarouselData() { }

static List<CarouselItem> createItems() {
return Arrays.asList(
new CarouselItem(R.drawable.image_1, R.string.cat_carousel_image_1_content_desc),
new CarouselItem(R.drawable.image_2, R.string.cat_carousel_image_2_content_desc),
new CarouselItem(R.drawable.image_3, R.string.cat_carousel_image_3_content_desc),
new CarouselItem(R.drawable.image_4, R.string.cat_carousel_image_4_content_desc),
new CarouselItem(R.drawable.image_5, R.string.cat_carousel_image_5_content_desc),
new CarouselItem(R.drawable.image_6, R.string.cat_carousel_image_6_content_desc),
new CarouselItem(R.drawable.image_7, R.string.cat_carousel_image_7_content_desc),
new CarouselItem(R.drawable.image_8, R.string.cat_carousel_image_8_content_desc),
new CarouselItem(R.drawable.image_9, R.string.cat_carousel_image_9_content_desc),
new CarouselItem(R.drawable.image_10, R.string.cat_carousel_image_10_content_desc)
);
}
}
99 changes: 99 additions & 0 deletions catalog/java/io/material/catalog/carousel/CarouselFragment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* 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
*
* 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 androidx.fragment.app.Fragment;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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;
import java.util.Arrays;
import java.util.List;

/** A landing fragment that links to Carousel demos for the Catalog app. */
public class CarouselFragment extends DemoLandingFragment {

@Override
public int getTitleResId() {
return R.string.cat_carousel_title;
}

@Override
public int getDescriptionResId() {
return R.string.cat_carousel_description;
}

@NonNull
@Override
public Demo getMainDemo() {
return new Demo() {
@Nullable
@Override
public Fragment createFragment() {
return new CarouselMainDemoFragment();
}
};
}

@NonNull
@Override
public List<Demo> getAdditionalDemos() {
return Arrays.asList(
new Demo(R.string.cat_carousel_multi_browse_demo_title) {
@Override
public Fragment createFragment() {
return new MultiBrowseDemoFragment();
}
},
new Demo(R.string.cat_carousel_default_list_demo_title) {
@Override
public Fragment createFragment() {
return new DefaultListDemoFragment();
}
}
);
}

/** The Dagger module for {@link CarouselFragment} dependencies. */
@dagger.Module
public abstract static class Module {

@FragmentScope
@ContributesAndroidInjector
abstract CarouselFragment contributeInjector();

@IntoSet
@Provides
@ActivityScope
static FeatureDemo provideFeatureDemo() {
return new FeatureDemo(R.string.cat_carousel_title, R.drawable.ic_lists) {
@Override
public Fragment createFragment() {
return new CarouselFragment();
}
};
}
}
}
47 changes: 47 additions & 0 deletions catalog/java/io/material/catalog/carousel/CarouselItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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
*
* 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 androidx.annotation.DrawableRes;
import androidx.annotation.StringRes;

/**
* A data class that holds all information related to an item inside a Carousel.
*/
class CarouselItem {

@DrawableRes
private final int drawableRes;

@StringRes
private final int contentDescRes;

CarouselItem(@DrawableRes int drawableRes, @StringRes int contentDescRes) {
this.drawableRes = drawableRes;
this.contentDescRes = contentDescRes;
}

@DrawableRes
int getDrawableRes() {
return this.drawableRes;
}

@StringRes
int getContentDescRes() {
return this.contentDescRes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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
*
* 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;

/** An interface for items in a carousel. */
interface CarouselItemListener {
void onItemClicked(CarouselItem item, int position);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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
*
* 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 androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;

/** An {@link RecyclerView.ViewHolder} that displays an item inside a Carousel. */
class CarouselItemViewHolder extends RecyclerView.ViewHolder {

private final ImageView imageView;
private final CarouselItemListener listener;

CarouselItemViewHolder(@NonNull View itemView, CarouselItemListener listener) {
super(itemView);
imageView = itemView.findViewById(R.id.carousel_image_view);
this.listener = listener;
}

void bind(CarouselItem item) {
Glide.with(imageView.getContext()).load(item.getDrawableRes()).centerCrop().into(imageView);
imageView.setContentDescription(imageView.getResources().getString(item.getContentDescRes()));
itemView.setOnClickListener(v -> listener.onItemClicked(item, getBindingAdapterPosition()));
}
}
Loading

0 comments on commit 4ecba81

Please sign in to comment.