{"id":13786897,"url":"https://github.com/ImaginativeShohag/Why-Not-Image-Carousel","last_synced_at":"2025-05-12T00:30:38.412Z","repository":{"id":37234763,"uuid":"240220327","full_name":"ImaginativeShohag/Why-Not-Image-Carousel","owner":"ImaginativeShohag","description":"Why Not use Image Carousel if you have lots of images to show!","archived":false,"fork":false,"pushed_at":"2024-05-08T13:50:15.000Z","size":67732,"stargazers_count":482,"open_issues_count":8,"forks_count":67,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-09T10:04:36.005Z","etag":null,"topics":["android","android-carousel","carousel","carousel-view","image-carousel","slideshow"],"latest_commit_sha":null,"homepage":"https://imaginativeshohag.github.io/Why-Not-Image-Carousel/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ImaginativeShohag.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://www.buymeacoffee.com/ImShohag"]}},"created_at":"2020-02-13T09:18:02.000Z","updated_at":"2025-04-05T08:19:11.000Z","dependencies_parsed_at":"2025-01-06T11:34:40.338Z","dependency_job_id":null,"html_url":"https://github.com/ImaginativeShohag/Why-Not-Image-Carousel","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImaginativeShohag%2FWhy-Not-Image-Carousel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImaginativeShohag%2FWhy-Not-Image-Carousel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImaginativeShohag%2FWhy-Not-Image-Carousel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImaginativeShohag%2FWhy-Not-Image-Carousel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ImaginativeShohag","download_url":"https://codeload.github.com/ImaginativeShohag/Why-Not-Image-Carousel/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253645311,"owners_count":21941314,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-carousel","carousel","carousel-view","image-carousel","slideshow"],"created_at":"2024-08-03T20:00:20.842Z","updated_at":"2025-05-12T00:30:33.398Z","avatar_url":"https://github.com/ImaginativeShohag.png","language":"Kotlin","funding_links":["https://www.buymeacoffee.com/ImShohag"],"categories":["Library"],"sub_categories":[],"readme":"![Why Not! Image Carousel! Logo](docs/images/logo.svg)\n\n# Why Not! Image Carousel!\n\nAn easy, super simple and customizable image carousel view for Android.\n\n[![Developer](https://img.shields.io/badge/Maintainer-ImaginativeShohag-green)](https://github.com/ImaginativeShohag)\n[![GitHub release](https://img.shields.io/github/release/ImaginativeShohag/Why-Not-Image-Carousel.svg)](https://github.com/ImaginativeShohag/Why-Not-Image-Carousel/releases)\n[![Android Arsenal]( https://img.shields.io/badge/Android%20Arsenal-Why%20Not!%20Image%20Carousel!-green.svg?style=flat )]( https://android-arsenal.com/details/1/8053)\n[![API](https://img.shields.io/badge/API-21%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=21)\n\n## Preview\n\n| ![Screenshot](docs/images/preview_1.gif) |  ![Preview](docs/images/preview_2.gif)   |\n| :---------------------------------: | :---------------------------------: |\n| ![Screenshot](docs/images/preview_3.gif) | ![Screenshot](docs/images/preview_4.gif) |\n\n## Usage\n\n### Dependency\n\n#### Add the followings to your project level `build.gradle` file.\n\n```groovy\ndependencies {\n    // Material Components for Android. Replace the version with the latest version of Material Components library.\n    implementation 'com.google.android.material:material:1.5.0'\n\n    // Circle Indicator (To fix the xml preview \"Missing classes\" error)\n    implementation 'me.relex:circleindicator:2.1.6'\n\n    implementation 'org.imaginativeworld.whynotimagecarousel:whynotimagecarousel:2.1.0'\n}\n```\n\n### Requirements\n\n**0.** Minimum SDK for this library is **API 21** (Android 5.0 Lollipop).\n\n**1.** Your application have to use **AndroidX** to use this library.\n\n**2.** Your have to use **\\*.MaterialComponents.\\*** in you styles.\n\n### Finally\n\nAdd the view `org.imaginativeworld.whynotimagecarousel.ImageCarousel` in your layout:\n\n```xml\n\u003corg.imaginativeworld.whynotimagecarousel.ImageCarousel\n    android:id=\"@+id/carousel\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"256dp\" /\u003e\n```\n\nUse the `CarouselItem` class for data item. Initialize the `ImageCarousel` with data using `setData()` function:\n\n```kotlin\n// Kotlin\nval carousel: ImageCarousel = findViewById(R.id.carousel)\n\n// Register lifecycle. For activity this will be lifecycle/getLifecycle() and for fragment it will be viewLifecycleOwner/getViewLifecycleOwner().\ncarousel.registerLifecycle(lifecycle)\n\nval list = mutableListOf\u003cCarouselItem\u003e()\n\n// Image URL with caption\nlist.add(\n    CarouselItem(\n        imageUrl = \"https://images.unsplash.com/photo-1532581291347-9c39cf10a73c?w=1080\",\n        caption = \"Photo by Aaron Wu on Unsplash\"\n    )\n)\n\n// Just image URL\nlist.add(\n    CarouselItem(\n        imageUrl = \"https://images.unsplash.com/photo-1534447677768-be436bb09401?w=1080\"\n    )\n)\n\n// Image URL with header\nval headers = mutableMapOf\u003cString, String\u003e()\nheaders[\"header_key\"] = \"header_value\"\n\nlist.add(\n    CarouselItem(\n        imageUrl = \"https://images.unsplash.com/photo-1534447677768-be436bb09401?w=1080\",\n        headers = headers\n    )\n)\n\n// Image drawable with caption\nlist.add(\n    CarouselItem(\n        imageDrawable = R.drawable.image_1,\n        caption = \"Photo by Kimiya Oveisi on Unsplash\"\n    )\n)\n\n// Just image drawable\nlist.add(\n    CarouselItem(\n        imageDrawable = R.drawable.image_2\n    )\n)\n\n// ...\n\ncarousel.setData(list)\n```\n\n```java\n// Java\nImageCarousel carousel = findViewById(R.id.carousel);\n\n// Register lifecycle. For activity this will be lifecycle/getLifecycle() and for fragments it will be viewLifecycleOwner/getViewLifecycleOwner().\ncarousel.registerLifecycle(getLifecycle());\n\nList\u003cCarouselItem\u003e list = new ArrayList\u003c\u003e();\n\n// Image URL with caption\nlist.add(\n    new CarouselItem(\n        \"https://images.unsplash.com/photo-1532581291347-9c39cf10a73c?w=1080\",\n        \"Photo by Aaron Wu on Unsplash\"\n    )\n);\n\n// Just image URL\nlist.add(\n    new CarouselItem(\n        \"https://images.unsplash.com/photo-1534447677768-be436bb09401?w=1080\"\n    )\n);\n\n// Image URL with header\nMap\u003cString, String\u003e headers = new HashMap\u003c\u003e();\nheaders.put(\"header_key\", \"header_value\");\n\nlist.add(\n    new CarouselItem(\n        \"https://images.unsplash.com/photo-1534447677768-be436bb09401?w=1080\",\n        headers\n    )\n);\n\n// Image drawable with caption\nlist.add(\n    new CarouselItem(\n        R.drawable.image_1,\n        \"Photo by Kimiya Oveisi on Unsplash\"\n    )\n);\n\n// Just image drawable\nlist.add(\n    new CarouselItem(\n        R.drawable.image_2\n    )\n);\n\n// ...\n\ncarousel.setData(list);\n```\n\nThat's all you need to use the library! :)\n\nDetail examples can be found [here](/sample).\n\n## `ImageCarousel` XML attributes\n\nAll the custom XML attributes for `ImageCarousel` view with default values are given below. All attributes are optional.\n\n```xml\n\u003corg.imaginativeworld.whynotimagecarousel.ImageCarousel\n    android:id=\"@+id/carousel\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    \n    app:showTopShadow=\"true\"\n    app:topShadowAlpha=\"0.6\"\n    app:topShadowHeight=\"32dp\"\n    \n    app:showBottomShadow=\"true\"\n    app:bottomShadowAlpha=\"0.6\"\n    app:bottomShadowHeight=\"64dp\"\n    \n    app:showCaption=\"true\"\n    app:captionMargin=\"0dp\"\n    app:captionTextSize=\"14sp\"\n\n    app:showIndicator=\"true\"\n    app:indicatorMargin=\"0dp\"\n    \n    app:imageScaleType=\"centerCrop\"\n    \n    app:carouselBackground=\"#00000000\"\n    app:imagePlaceholder=\"@drawable/ic_picture\"\n\n    app:carouselPadding=\"0dp\"\n    app:carouselPaddingBottom=\"0dp\"\n    app:carouselPaddingEnd=\"0dp\"\n    app:carouselPaddingStart=\"0dp\"\n    app:carouselPaddingTop=\"0dp\"\n\n    app:showNavigationButtons=\"true\"\n    app:previousButtonLayout=\"@layout/previous_button_layout\"\n    app:previousButtonId=\"@id/btn_previous\"\n    app:previousButtonMargin=\"4dp\"\n    app:nextButtonLayout=\"@layout/next_button_layout\"\n    app:nextButtonId=\"@id/btn_next\"\n    app:nextButtonMargin=\"4dp\"\n    \n    app:carouselType=\"BLOCK\"\n    app:carouselGravity=\"CENTER\"\n    \n    app:scaleOnScroll=\"false\"\n    app:scalingFactor=\"0.15\"\n    app:autoWidthFixing=\"true\"\n    app:autoPlay=\"false\"\n    app:autoPlayDelay=\"3000\"\n    app:infiniteCarousel=\"true\"\n    app:touchToPause=\"true\" /\u003e\n```\n\n## `ImageCarousel` methods\n\nYou can also set all the attributes programmatically. All the methods and their usages given below.\n\n### Kotlin\n\n```kotlin\nval carousel: ImageCarousel = findViewById(R.id.carousel)\n\n// Attributes\ncarousel.carouselPadding = 0.dpToPx(context)\ncarousel.carouselPaddingStart = 0.dpToPx(context)\ncarousel.carouselPaddingTop = 0.dpToPx(context)\ncarousel.carouselPaddingEnd = 0.dpToPx(context)\ncarousel.carouselPaddingBottom = 0.dpToPx(context)\n\ncarousel.showTopShadow = true\ncarousel.topShadowAlpha = 0.6f // 0 to 1, 1 means 100%\ncarousel.topShadowHeight = 32.dpToPx(context) // px value of dp\n\ncarousel.showBottomShadow = true\ncarousel.bottomShadowAlpha = 0.6f // 0 to 1, 1 means 100%\ncarousel.bottomShadowHeight = 64.dpToPx(context) // px value of dp\n\ncarousel.showCaption = true\ncarousel.captionMargin = 0.dpToPx(context) // px value of dp\ncarousel.captionTextSize = 14.spToPx(context) // px value of sp\n\ncarousel.showIndicator = true\ncarousel.indicatorMargin = 0.dpToPx(context) // px value of dp\n\ncarousel.showNavigationButtons = true\ncarousel.imageScaleType = ImageView.ScaleType.CENTER_CROP\ncarousel.carouselBackground = ColorDrawable(Color.parseColor(\"#333333\"))\ncarousel.imagePlaceholder = ContextCompat.getDrawable(\n    context,\n    R.drawable.ic_picture\n)\n\n// For custom previous or next button layout,\n// set the layout using \"previousButtonLayout\" attribute and\n// give the View/Button id in \"previousButtonId\" attribute.\ncarousel.previousButtonLayout = R.layout.previous_button_layout\ncarousel.previousButtonId = R.id.btn_previous\ncarousel.previousButtonMargin = 4.dpToPx(context) // px value of dp\n\ncarousel.nextButtonLayout = R.layout.next_button_layout\ncarousel.nextButtonId = R.id.btn_next\ncarousel.nextButtonMargin = 4.dpToPx(context) // px value of dp\n\ncarousel.carouselType = CarouselType.BLOCK\ncarousel.scaleOnScroll = false\ncarousel.scalingFactor = .15f // 0 to 1; 1 means 100\n\n// If the width of a single item in ImageCarousel is not greater then\n// half of the whole ImageCarousel view width, then the ImageCarousel\n// will not work as expected, So it is recommended to set this value\n// true all the time. So, the carousel will automatically increase the\n// width of the items if necessary.\ncarousel.autoWidthFixing = true\n\n// If you want auto slide, turn this feature on.\ncarousel.autoPlay = false\ncarousel.autoPlayDelay = 3000 // Milliseconds\n\n// Touch to pause autoPlay.\ncarousel.touchToPause = true\n\n// Infinite scroll for the carousel.\ncarousel.infiniteCarousel = true\n\n// Scroll listener\ncarousel.onScrollListener = object : CarouselOnScrollListener {\n    override fun onScrollStateChanged(\n        recyclerView: RecyclerView,\n        newState: Int,\n        position: Int,\n        carouselItem: CarouselItem?\n    ) {\n        // ...\n    }\n\n    override fun onScrolled(\n        recyclerView: RecyclerView, \n        dx: Int, \n        dy: Int,\n        position: Int,\n        carouselItem: CarouselItem?\n    ) {\n        // ...\n    }\n}\n\n// Carousel listener\ncarousel.carouselListener = object : CarouselListener {\n    override fun onCreateViewHolder(\n        layoutInflater: LayoutInflater,\n        parent: ViewGroup\n    ): ViewBinding? {\n        // ...\n    }\n\n    override fun onBindViewHolder(\n        binding: ViewBinding,\n        imageScaleType: ImageView.ScaleType,\n        item: CarouselItem,\n        position: Int\n    ) {\n        // ...\n    }\n    \n    override fun onClick(position: Int, carouselItem: CarouselItem) {\n        // ...\n    }\n\n    override fun onLongClick(position: Int, dataObject: CarouselItem) {\n        // ...\n    }\n\n}\n\n// Goto next slide/item\ncarousel.next()\n\n// Goto previous slide/item\ncarousel.previous()\n\n// Start auto play\ncarousel.start()\n\n// Stop auto play\ncarousel.stop()\n\n// If you need custom indicator, use the CircleIndicator2 from CircleIndicator (https://github.com/ongakuer/CircleIndicator).\n// Then pass the view to the ImageCarousel.\nval customIndicator: CircleIndicator2 = findViewById(R.id.custom_indicator)\ncarousel.setIndicator(customIndicator)\n\n// For activity this will be lifecycle/getLifecycle() and for fragment it will be viewLifecycleOwner/getViewLifecycleOwner().\ncarousel.registerLifecycle(lifecycle)\n\n// ...\n\n// You can use the following methods to add CarouselItem data to the carousel:\n// 1. setData(data: List\u003cCarouselItem\u003e): Set a list of CarouselItem. This will remove previous data from the carousel.\n// 2. addData(data: List\u003cCarouselItem\u003e): Append list of CarouselItem with existing data.\n// 3. addData(item: CarouselItem): Append a CarouselItem with existing data.\ncarousel.setData(list)\n```\n\n### Java\n\n```java\nImageCarousel carousel = findViewById(R.id.carousel);\n\n// Attributes\ncarousel.setCarouselPadding(Utils.dpToPx(0, context));\ncarousel.setCarouselPaddingStart(Utils.dpToPx(0, context));\ncarousel.setCarouselPaddingTop(Utils.dpToPx(0, context));\ncarousel.setCarouselPaddingEnd(Utils.dpToPx(0, context));\ncarousel.setCarouselPaddingBottom(Utils.dpToPx(0, context));\n\ncarousel.setShowTopShadow(true);\ncarousel.setTopShadowAlpha(0.6f); // 0 to 1, 1 means 100%\ncarousel.setTopShadowHeight(Utils.dpToPx(32, context)); // px value of dp\n\ncarousel.setShowBottomShadow(true);\ncarousel.setBottomShadowAlpha(0.6f); // 0 to 1, 1 means 100%\ncarousel.setBottomShadowHeight(Utils.dpToPx(64, context)); // px value of dp\n\ncarousel.setShowCaption(true);\ncarousel.setCaptionMargin(Utils.dpToPx(0, context)); // px value of dp\ncarousel.setCaptionTextSize(Utils.spToPx(14, context)); // px value of sp\n\ncarousel.setShowIndicator(true);\ncarousel.setIndicatorMargin(Utils.dpToPx(0, context)); // px value of dp\n\ncarousel.setShowNavigationButtons(true);\ncarousel.setImageScaleType(ImageView.ScaleType.CENTER);\ncarousel.setCarouselBackground(new ColorDrawable(Color.parseColor(\"#333333\")));\ncarousel.setImagePlaceholder(ContextCompat.getDrawable(\n        context,\n        R.drawable.ic_picture\n));\n\n// See kotlin code for details.\ncarousel.setPreviousButtonLayout(R.layout.previous_button_layout);\ncarousel.setPreviousButtonId(R.id.btn_previous);\ncarousel.setPreviousButtonMargin(Utils.dpToPx(4, context)); // px value of dp\n\ncarousel.setNextButtonLayout(R.layout.next_button_layout);\ncarousel.setNextButtonId(R.id.btn_next);\ncarousel.setNextButtonMargin(Utils.dpToPx(4, context)); // px value of dp\n\ncarousel.setCarouselType(CarouselType.BLOCK);\ncarousel.setScaleOnScroll(false);\ncarousel.setScalingFactor(.15f);\n\n// See kotlin code for details.\ncarousel.setAutoWidthFixing(true);\n\n// See kotlin code for details.\ncarousel.setAutoPlay(false);\ncarousel.setAutoPlayDelay(3000); // Milliseconds\n\n// Touch to pause autoPlay.\ncarousel.setTouchToPause(true);\n\n// Infinite scroll for the carousel.\ncarousel.setInfiniteCarousel(true);\n\n// Scroll listener\ncarousel.setOnScrollListener(new CarouselOnScrollListener() {\n    @Override\n    public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy, int position, @Nullable CarouselItem carouselItem) {\n        // ...\n    }\n\n    @Override\n    public void onScrollStateChanged(@NotNull RecyclerView recyclerView, int newState, int position, @Nullable CarouselItem carouselItem) {\n        // ...\n    }\n});\n\n// Carousel listener\ncarousel.setCarouselListener(new CarouselListener() {\n    @Nullable\n    @Override\n    public ViewBinding onCreateViewHolder(@NotNull LayoutInflater layoutInflater, @NotNull ViewGroup parent) {\n        // ...\n    }\n    \n    @Override\n    public void onBindViewHolder(@NotNull ViewBinding binding, @NotNull ImageView.ScaleType imageScaleType, @NotNull CarouselItem item, int position) {\n        // ...\n    }\n\n    @Override\n    public void onLongClick(int position, @NotNull CarouselItem dataObject) {\n        // ...\n    }\n\n    @Override\n    public void onClick(int position, @NotNull CarouselItem carouselItem) {\n        // ...\n    }\n});\n\n// Goto next slide/item\ncarousel.next()\n\n// Goto previous slide/item\ncarousel.previous()\n\n// Start auto play\ncarousel.start()\n\n// Stop auto play\ncarousel.stop()\n\n// See kotlin code for details.\nCircleIndicator2 indicator = findViewById(R.id.custom_indicator);\ncarousel.setIndicator(indicator);\n\n// See kotlin code for details.\ncarousel.registerLifecycle(lifecycle)\n\n// ...\n\n// See kotlin code for details.\ncarousel.setData(list)\n```\n\n## Register Lifecycle\n\n`ImageCarousel` is a [lifecycle-aware component](https://developer.android.com/topic/libraries/architecture/lifecycle). You can use the `registerLifecycle()` method to register a lifecycle. For activity the parameter will be `lifecycle`/`getLifecycle()` and for fragment it will be `viewLifecycleOwner`/`getViewLifecycleOwner()`.\n\nIt is recommended to register `ImageCarousel` to a lifecycle, so that the auto-play/scroll will pause when the app is in the background and resume when the app is resumed.\n\nIt is also used to correctly initialize the infinite carousel when the app is in the background.\n\nSo it is recommended if you enabled `autoPlay` \u0026 `infiniteCarousel`.\n\n## Infinite Carousel\n\n![Infinite Carousel](docs/images/infinite_carousel.gif)\n\nThe library now supports an infinite carousel, which means that the item view is looped infinitely. This feature is enabled by default, but you can disable it by setting the `infiniteCarousel` property to `false`.\n\n## Indicator\n\nThe carousel is bundled with a default indicator. We used the [CircleIndicator](https://github.com/ongakuer/CircleIndicator) library for the indicator. You can use all the customization supported by the library in our carousel. You can get the default indicator by the `getIndicator()` method. If you wish to add your custom indicator, then just use the `CircleIndicator2` from the [CircleIndicator](https://github.com/ongakuer/CircleIndicator) library and set the view using the `setIndicator(indicator)` method. For details usage see the [sample](/sample).\n\n## Custom View\n\nThe carousel supports the view-binding for the custom view. `CarouselListener` has two methods `onCreateViewHolder()` and `onBindViewHolder()` for adding a custom view to the carousel. If you use the `RecyclerView.Adapter` then you should remember the names of the methods. Both are mapped with the same methods in the `RecyclerView.Adapter`.\n\nAdding a custom view is straightforward. An example is given below:\n\n```kotlin\n// Kotlin\ncarousel.carouselListener = object : CarouselListener {\n    override fun onCreateViewHolder(\n        layoutInflater: LayoutInflater,\n        parent: ViewGroup\n    ): ViewBinding {\n        // Here, our XML layout file name is custom_item_layout.xml. So our view binding generated class name is CustomItemLayoutBinding.\n        return CustomItemLayoutBinding.inflate(layoutInflater, parent, false)\n    }\n\n    override fun onBindViewHolder(\n        binding: ViewBinding,\n        imageScaleType: ImageView.ScaleType,\n        item: CarouselItem,\n        position: Int\n    ) {\n        // Cast the binding to the returned view binding class of the onCreateViewHolder() method.\n        val currentBinding = binding as CustomItemLayoutBinding\n\n        // Do the bindings...\n        currentBinding.imageView.apply {\n            scaleType = imageScaleType\n\n            // setImage() is an extension function to load image to an ImageView using CarouselItem object. We need to provide current CarouselItem data and the place holder Drawable or drawable resource id to the function. placeholder parameter is optional.\n            setImage(item, R.drawable.ic_wb_cloudy_with_padding)\n        }\n    }\n}\n```\n\n```java\n// Java\nbinding.carousel.setCarouselListener(new CarouselListener() {\n    @Nullable\n    @Override\n    public ViewBinding onCreateViewHolder(@NotNull LayoutInflater layoutInflater, @NotNull ViewGroup parent) {\n        // Here, our XML layout file name is custom_item_layout.xml. So our view binding generated class name is CustomItemLayoutBinding.\n        return ItemCustomFixedSizeLayout1Binding.inflate(layoutInflater, parent, false);\n    }\n\n    @Override\n    public void onBindViewHolder(@NotNull ViewBinding binding, @NotNull ImageView.ScaleType imageScaleType, @NotNull CarouselItem item, int position) {\n         // Cast the binding to the returned view binding class of the onCreateViewHolder() method.\n        ItemCustomFixedSizeLayout1Binding currentBinding = (ItemCustomFixedSizeLayout1Binding) binding;\n\n        // Do the bindings...\n        currentBinding.imageView.setScaleType(imageScaleType);\n\n        // setImage() is an extension function to load image to an ImageView using CarouselItem object. We need to provide current CarouselItem data and the place holder Drawable or drawable resource id to the function. placeholder parameter is optional.\n        Utils.setImage(currentBinding.imageView, item, R.drawable.ic_wb_cloudy_with_padding);\n    }\n});\n```\n\n**Using custom view, you can create any type of carousel, even a carousel without any image!** See the [sample](/sample) app for some example.\n\n## Carousel Type (`carouselType`)\n\n![Carousel type preview](docs/images/carousel_type.png)\n\n`ImageCarousel` has following types:\n\n#### 1. `CarouselType.BLOCK`\n\nIf you need one item view at a time, then use this carousel type.\n\n#### 2. `CarouselType.SHOWCASE`\n\nIf you need multiple item view at a time, use this carousel type.\n\nYou can also use the `scaleOnScroll` and `scalingFactor` attributes with this carousel type.\n\n### Scale Item View On Scroll (`scaleOnScroll`)\n\n![Scale-on-scroll preview](docs/images/scale_on_scroll.png)\n\nYou can use `scaleOnScroll` attribute to scaling down the adjacent views like above. Use `scalingFactor` to define scale down percentage. Value should be 0.0 to 1.0.\n\n## Carousel Gravity (`carouselGravity`)\n\n![Carousel gravity preview](docs/images/carousel_gravity.png)\n\nFor `CarouselType.SHOWCASE`, you can set carousel gravity. Supported gravities ase:\n\n#### 1. `CarouselGravity.CENTER`\n\nCurrent selected item will be at the center of the view.\n\n#### 2. `CarouselGravity.START`\n\nCurrent selected item will be at the start of the view.\n\n## Credits\n\nThis library is using the [CircleIndicator](https://github.com/ongakuer/CircleIndicator) library for the indicator.\nInspired by [CarouselView](https://github.com/jama5262/CarouselView) library.\nAll the images from [Unsplash](https://unsplash.com).\n\n## Change Log\n\nSee the change log [here](CHANGELOG.md).\n\n## License\n\n```\nCopyright 2021 Md. Mahmudul Hasan Shohag\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FImaginativeShohag%2FWhy-Not-Image-Carousel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FImaginativeShohag%2FWhy-Not-Image-Carousel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FImaginativeShohag%2FWhy-Not-Image-Carousel/lists"}