Skip to content

Commit 4ecba81

Browse files
committed
[Carousel] Release carousel component
PiperOrigin-RevId: 501635363
1 parent b892849 commit 4ecba81

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+5004
-3
lines changed

catalog/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def srcDirs = [
5656
'bottomsheet',
5757
'button',
5858
'card',
59+
'carousel',
5960
'checkbox',
6061
'chip',
6162
'color',
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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+
* https://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.carousel;
18+
19+
import io.material.catalog.R;
20+
21+
import androidx.recyclerview.widget.ListAdapter;
22+
import androidx.recyclerview.widget.DiffUtil;
23+
import android.view.LayoutInflater;
24+
import android.view.ViewGroup;
25+
import androidx.annotation.NonNull;
26+
27+
/** An adapter that displays {@link CarouselItem}s for a Carousel. */
28+
class CarouselAdapter extends ListAdapter<CarouselItem, CarouselItemViewHolder> {
29+
30+
private static final DiffUtil.ItemCallback<CarouselItem> DIFF_CALLBACK =
31+
new DiffUtil.ItemCallback<CarouselItem>() {
32+
@Override
33+
public boolean areItemsTheSame(
34+
@NonNull CarouselItem oldItem, @NonNull CarouselItem newItem) {
35+
// User properties may have changed if reloaded from the DB, but ID is fixed
36+
return oldItem == newItem;
37+
}
38+
39+
@Override
40+
public boolean areContentsTheSame(
41+
@NonNull CarouselItem oldItem, @NonNull CarouselItem newItem) {
42+
return false;
43+
}
44+
};
45+
46+
private final CarouselItemListener listener;
47+
48+
CarouselAdapter(CarouselItemListener listener) {
49+
super(DIFF_CALLBACK);
50+
this.listener = listener;
51+
}
52+
53+
@NonNull
54+
@Override
55+
public CarouselItemViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int pos) {
56+
return new CarouselItemViewHolder(
57+
LayoutInflater.from(viewGroup.getContext())
58+
.inflate(R.layout.cat_carousel_item, viewGroup, false), listener);
59+
}
60+
61+
@Override
62+
public void onBindViewHolder(@NonNull CarouselItemViewHolder carouselItemViewHolder, int pos) {
63+
carouselItemViewHolder.bind(getItem(pos));
64+
}
65+
66+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
* https://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.carousel;
18+
19+
import io.material.catalog.R;
20+
21+
import java.util.Arrays;
22+
import java.util.List;
23+
24+
/**
25+
* A data store used to populate Carousels.
26+
*/
27+
class CarouselData {
28+
29+
private CarouselData() { }
30+
31+
static List<CarouselItem> createItems() {
32+
return Arrays.asList(
33+
new CarouselItem(R.drawable.image_1, R.string.cat_carousel_image_1_content_desc),
34+
new CarouselItem(R.drawable.image_2, R.string.cat_carousel_image_2_content_desc),
35+
new CarouselItem(R.drawable.image_3, R.string.cat_carousel_image_3_content_desc),
36+
new CarouselItem(R.drawable.image_4, R.string.cat_carousel_image_4_content_desc),
37+
new CarouselItem(R.drawable.image_5, R.string.cat_carousel_image_5_content_desc),
38+
new CarouselItem(R.drawable.image_6, R.string.cat_carousel_image_6_content_desc),
39+
new CarouselItem(R.drawable.image_7, R.string.cat_carousel_image_7_content_desc),
40+
new CarouselItem(R.drawable.image_8, R.string.cat_carousel_image_8_content_desc),
41+
new CarouselItem(R.drawable.image_9, R.string.cat_carousel_image_9_content_desc),
42+
new CarouselItem(R.drawable.image_10, R.string.cat_carousel_image_10_content_desc)
43+
);
44+
}
45+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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+
* https://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.carousel;
18+
19+
import io.material.catalog.R;
20+
21+
import androidx.fragment.app.Fragment;
22+
import androidx.annotation.NonNull;
23+
import androidx.annotation.Nullable;
24+
import dagger.Provides;
25+
import dagger.android.ContributesAndroidInjector;
26+
import dagger.multibindings.IntoSet;
27+
import io.material.catalog.application.scope.ActivityScope;
28+
import io.material.catalog.application.scope.FragmentScope;
29+
import io.material.catalog.feature.Demo;
30+
import io.material.catalog.feature.DemoLandingFragment;
31+
import io.material.catalog.feature.FeatureDemo;
32+
import java.util.Arrays;
33+
import java.util.List;
34+
35+
/** A landing fragment that links to Carousel demos for the Catalog app. */
36+
public class CarouselFragment extends DemoLandingFragment {
37+
38+
@Override
39+
public int getTitleResId() {
40+
return R.string.cat_carousel_title;
41+
}
42+
43+
@Override
44+
public int getDescriptionResId() {
45+
return R.string.cat_carousel_description;
46+
}
47+
48+
@NonNull
49+
@Override
50+
public Demo getMainDemo() {
51+
return new Demo() {
52+
@Nullable
53+
@Override
54+
public Fragment createFragment() {
55+
return new CarouselMainDemoFragment();
56+
}
57+
};
58+
}
59+
60+
@NonNull
61+
@Override
62+
public List<Demo> getAdditionalDemos() {
63+
return Arrays.asList(
64+
new Demo(R.string.cat_carousel_multi_browse_demo_title) {
65+
@Override
66+
public Fragment createFragment() {
67+
return new MultiBrowseDemoFragment();
68+
}
69+
},
70+
new Demo(R.string.cat_carousel_default_list_demo_title) {
71+
@Override
72+
public Fragment createFragment() {
73+
return new DefaultListDemoFragment();
74+
}
75+
}
76+
);
77+
}
78+
79+
/** The Dagger module for {@link CarouselFragment} dependencies. */
80+
@dagger.Module
81+
public abstract static class Module {
82+
83+
@FragmentScope
84+
@ContributesAndroidInjector
85+
abstract CarouselFragment contributeInjector();
86+
87+
@IntoSet
88+
@Provides
89+
@ActivityScope
90+
static FeatureDemo provideFeatureDemo() {
91+
return new FeatureDemo(R.string.cat_carousel_title, R.drawable.ic_lists) {
92+
@Override
93+
public Fragment createFragment() {
94+
return new CarouselFragment();
95+
}
96+
};
97+
}
98+
}
99+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
* https://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.carousel;
18+
19+
import androidx.annotation.DrawableRes;
20+
import androidx.annotation.StringRes;
21+
22+
/**
23+
* A data class that holds all information related to an item inside a Carousel.
24+
*/
25+
class CarouselItem {
26+
27+
@DrawableRes
28+
private final int drawableRes;
29+
30+
@StringRes
31+
private final int contentDescRes;
32+
33+
CarouselItem(@DrawableRes int drawableRes, @StringRes int contentDescRes) {
34+
this.drawableRes = drawableRes;
35+
this.contentDescRes = contentDescRes;
36+
}
37+
38+
@DrawableRes
39+
int getDrawableRes() {
40+
return this.drawableRes;
41+
}
42+
43+
@StringRes
44+
int getContentDescRes() {
45+
return this.contentDescRes;
46+
}
47+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
* https://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.carousel;
18+
19+
/** An interface for items in a carousel. */
20+
interface CarouselItemListener {
21+
void onItemClicked(CarouselItem item, int position);
22+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
* https://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.carousel;
18+
19+
import io.material.catalog.R;
20+
21+
import androidx.recyclerview.widget.RecyclerView;
22+
import android.view.View;
23+
import android.widget.ImageView;
24+
import androidx.annotation.NonNull;
25+
import com.bumptech.glide.Glide;
26+
27+
/** An {@link RecyclerView.ViewHolder} that displays an item inside a Carousel. */
28+
class CarouselItemViewHolder extends RecyclerView.ViewHolder {
29+
30+
private final ImageView imageView;
31+
private final CarouselItemListener listener;
32+
33+
CarouselItemViewHolder(@NonNull View itemView, CarouselItemListener listener) {
34+
super(itemView);
35+
imageView = itemView.findViewById(R.id.carousel_image_view);
36+
this.listener = listener;
37+
}
38+
39+
void bind(CarouselItem item) {
40+
Glide.with(imageView.getContext()).load(item.getDrawableRes()).centerCrop().into(imageView);
41+
imageView.setContentDescription(imageView.getResources().getString(item.getContentDescRes()));
42+
itemView.setOnClickListener(v -> listener.onItemClicked(item, getBindingAdapterPosition()));
43+
}
44+
}

0 commit comments

Comments
 (0)