diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 84861e7..69403ed 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -46,5 +46,4 @@ dependencies {
// Extra dependencies for the library
implementation(libs.picasso)
implementation(libs.androidx.multidex)
- implementation(libs.carousels.kotlin)
}
\ No newline at end of file
diff --git a/carousel/.gitignore b/carousel/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/carousel/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/carousel/build.gradle.kts b/carousel/build.gradle.kts
new file mode 100644
index 0000000..d78c70d
--- /dev/null
+++ b/carousel/build.gradle.kts
@@ -0,0 +1,51 @@
+plugins {
+ alias(libs.plugins.android.application)
+ alias(libs.plugins.kotlin.android)
+}
+
+android {
+ namespace = "com.example.carousel"
+ compileSdk = 35
+
+ defaultConfig {
+ applicationId = "com.example.carousel"
+ minSdk = 22
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0"
+
+ multiDexEnabled = true
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+ kotlinOptions {
+ jvmTarget = "11"
+ }
+}
+
+dependencies {
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+// Dependencies for the library
+ api(libs.picasso)
+ implementation(libs.glide)
+ implementation(libs.androidx.multidex)
+}
\ No newline at end of file
diff --git a/carousel/proguard-rules.pro b/carousel/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/carousel/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/carousel/src/androidTest/java/com/example/carousel/ExampleInstrumentedTest.kt b/carousel/src/androidTest/java/com/example/carousel/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..5dc5c4d
--- /dev/null
+++ b/carousel/src/androidTest/java/com/example/carousel/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.carousel
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.example.carousel", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/carousel/src/main/AndroidManifest.xml b/carousel/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9558c49
--- /dev/null
+++ b/carousel/src/main/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/java/com/example/carousel/ImageSlider.kt b/carousel/src/main/java/com/example/carousel/ImageSlider.kt
new file mode 100644
index 0000000..bc1dd9e
--- /dev/null
+++ b/carousel/src/main/java/com/example/carousel/ImageSlider.kt
@@ -0,0 +1,148 @@
+package com.example.carousel
+
+import android.content.Context
+import android.os.Handler
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import androidx.core.content.ContextCompat
+import androidx.viewpager.widget.ViewPager
+import com.example.carousel.adapters.ViewPagerAdapter
+import com.example.carousel.interfaces.ItemClickListener
+import com.example.carousel.models.SlideModel
+import java.util.*
+
+class ImageSlider @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
+ RelativeLayout(context, attrs, defStyleAttr) {
+
+ private var viewPager: ViewPager? = null
+ private var pagerDots: LinearLayout? = null
+ private var viewPagerAdapter: ViewPagerAdapter? = null
+
+ private var dots: Array? = null
+
+ private var currentPage = 0
+ private var imageCount = 0
+
+ private var cornerRadius: Int = 0
+ private var period: Long = 0
+ private var delay: Long = 0
+ private var autoCycle = false
+
+ private var selectedDot = 0
+ private var unselectedDot = 0
+ private var errorImage = 0
+ private var placeholder = 0
+ private var swipeTimer = Timer()
+
+ init {
+ LayoutInflater.from(getContext()).inflate(R.layout.image_slider, this, true)
+ viewPager = findViewById(R.id.view_pager)
+ pagerDots = findViewById(R.id.pager_dots)
+
+ val typedArray = context.theme.obtainStyledAttributes(
+ attrs,
+ R.styleable.ImageSlider,
+ defStyleAttr,
+ defStyleAttr
+ )
+
+ cornerRadius = typedArray.getInt(R.styleable.ImageSlider_corner_radius, 0)
+ period = typedArray.getInt(R.styleable.ImageSlider_period, 1000).toLong()
+ delay = typedArray.getInt(R.styleable.ImageSlider_delay, 1000).toLong()
+ autoCycle = typedArray.getBoolean(R.styleable.ImageSlider_auto_cycle, false)
+ placeholder =
+ typedArray.getResourceId(R.styleable.ImageSlider_placeholder, R.drawable.placeholder)
+ errorImage = typedArray.getResourceId(R.styleable.ImageSlider_error_image, R.drawable.error)
+ selectedDot = typedArray.getResourceId(
+ R.styleable.ImageSlider_selected_dot,
+ R.drawable.default_selected_dot
+ )
+ unselectedDot = typedArray.getResourceId(
+ R.styleable.ImageSlider_unselected_dot,
+ R.drawable.default_unselected_dot
+ )
+
+ }
+
+ fun setImageList(imageList: List, centerCrop: Boolean = false) {
+ viewPagerAdapter =
+ ViewPagerAdapter(context, imageList, cornerRadius, errorImage, placeholder, centerCrop)
+ viewPager!!.adapter = viewPagerAdapter
+ imageCount = imageList.size
+ if (imageList.size > 1) {
+ setupDots(imageList.size)
+ if (autoCycle) {
+ startSliding()
+ }
+ }
+ }
+
+ private fun setupDots(size: Int) {
+ pagerDots!!.removeAllViews()
+ dots = arrayOfNulls(size)
+
+ for (i in 0 until size) {
+ dots!![i] = ImageView(context)
+ dots!![i]!!.setImageDrawable(ContextCompat.getDrawable(context, unselectedDot))
+ val params = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ )
+ params.setMargins(8, 0, 8, 0)
+ pagerDots!!.addView(dots!![i], params)
+ }
+ dots!![0]!!.setImageDrawable(ContextCompat.getDrawable(context, selectedDot))
+
+ viewPager!!.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int,
+ positionOffset: Float,
+ positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ currentPage = position
+ for (dot in dots!!) {
+ dot!!.setImageDrawable(ContextCompat.getDrawable(context, unselectedDot))
+ }
+ dots!![position]!!.setImageDrawable(ContextCompat.getDrawable(context, selectedDot))
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ fun startSliding(changeablePeriod: Long = period) {
+ scheduleTimer(changeablePeriod)
+ }
+
+ fun stopSliding() {
+ swipeTimer.cancel()
+ swipeTimer.purge()
+ }
+
+ private fun scheduleTimer(period: Long) {
+ val handler = Handler()
+ val update = Runnable {
+ if (currentPage == imageCount) {
+ currentPage = 0
+ }
+ viewPager!!.setCurrentItem(currentPage++, true)
+ }
+ swipeTimer = Timer()
+ swipeTimer.schedule(object : TimerTask() {
+ override fun run() {
+ handler.post(update)
+ }
+ }, delay, period)
+ }
+
+ fun setItemClickListener(itemClickListener: ItemClickListener) {
+ viewPagerAdapter?.setItemClickListener(itemClickListener)
+ }
+}
+
diff --git a/carousel/src/main/java/com/example/carousel/adapters/ViewPagerAdapter.kt b/carousel/src/main/java/com/example/carousel/adapters/ViewPagerAdapter.kt
new file mode 100644
index 0000000..92aaef9
--- /dev/null
+++ b/carousel/src/main/java/com/example/carousel/adapters/ViewPagerAdapter.kt
@@ -0,0 +1,102 @@
+package com.example.carousel.adapters
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import android.widget.TextView
+import androidx.viewpager.widget.PagerAdapter
+import com.example.carousel.R
+import com.example.carousel.interfaces.ItemClickListener
+import com.example.carousel.models.SlideModel
+import com.example.carousel.transformation.RoundedTransformation
+import com.squareup.picasso.Picasso
+
+class ViewPagerAdapter(context: Context?, imageList: List, private var radius: Int, private var errorImage: Int, private var placeholder: Int, private var centerCrop: Boolean?) : PagerAdapter() {
+
+ private var imageList: List? = imageList
+ private var layoutInflater: LayoutInflater? = context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
+
+ private var itemClickListener: ItemClickListener? = null
+
+ override fun isViewFromObject(view: View, obj: Any): Boolean {
+ return view == obj
+ }
+
+ override fun getCount(): Int {
+ return imageList!!.size
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): View {
+
+ val itemView = layoutInflater!!.inflate(R.layout.pager_row, container, false)
+
+ val imageView = itemView.findViewById(R.id.image_view)
+ val linearLayout = itemView.findViewById(R.id.linear_layout)
+ val textView = itemView.findViewById(R.id.text_view)
+
+ if (imageList!![position].title != null){
+ textView.text = imageList!![position].title
+ }else{
+ linearLayout.visibility = View.INVISIBLE
+ }
+
+ if(imageList!![position].imageUrl == null){
+ if(centerCrop!! || imageList!![position].centerCrop){
+ Picasso.get()
+ .load(imageList!![position].imagePath!!) // Int
+ .fit()
+ .centerCrop()
+ .transform(RoundedTransformation(radius,0))
+ .placeholder(placeholder)
+ .error(errorImage)
+ .into(imageView)
+ }else {
+ Picasso.get()
+ .load(imageList!![position].imagePath!!) // Int
+ .fit()
+ .transform(RoundedTransformation(radius, 0))
+ .placeholder(placeholder)
+ .error(errorImage)
+ .into(imageView)
+ }
+ }else{
+ if(centerCrop!! || imageList!![position].centerCrop) {
+ Picasso.get()
+ .load(imageList!![position].imageUrl!!) // String
+ .fit()
+ .centerCrop()
+ .transform(RoundedTransformation(radius, 0))
+ .placeholder(placeholder)
+ .error(errorImage)
+ .into(imageView)
+ }else {
+ Picasso.get()
+ .load(imageList!![position].imageUrl!!) // String
+ .fit()
+ .transform(RoundedTransformation(radius, 0))
+ .placeholder(placeholder)
+ .error(errorImage)
+ .into(imageView)
+ }
+ }
+
+ container.addView(itemView)
+
+ imageView.setOnClickListener{itemClickListener?.onItemSelected(position)}
+
+ return itemView
+ }
+
+ fun setItemClickListener(itemClickListener: ItemClickListener) {
+ this.itemClickListener = itemClickListener
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
+ container.removeView(`object` as RelativeLayout)
+ }
+
+}
\ No newline at end of file
diff --git a/carousel/src/main/java/com/example/carousel/interfaces/ItemClickListener.kt b/carousel/src/main/java/com/example/carousel/interfaces/ItemClickListener.kt
new file mode 100644
index 0000000..bb31dbd
--- /dev/null
+++ b/carousel/src/main/java/com/example/carousel/interfaces/ItemClickListener.kt
@@ -0,0 +1,5 @@
+package com.example.carousel.interfaces
+
+interface ItemClickListener {
+ fun onItemSelected(position: Int)
+}
\ No newline at end of file
diff --git a/carousel/src/main/java/com/example/carousel/models/SlideModel.kt b/carousel/src/main/java/com/example/carousel/models/SlideModel.kt
new file mode 100644
index 0000000..d85012c
--- /dev/null
+++ b/carousel/src/main/java/com/example/carousel/models/SlideModel.kt
@@ -0,0 +1,49 @@
+package com.example.carousel.models
+
+class SlideModel {
+
+ var imageUrl: String? = null
+ var imagePath: Int? = 0
+ var title: String? = null
+ var centerCrop = false
+
+ constructor (imageUrl: String) {
+ this.imageUrl = imageUrl
+ }
+
+ constructor (imagePath: Int) {
+ this.imagePath = imagePath
+ }
+
+ constructor (imageUrl: String, title: String?) {
+ this.imageUrl = imageUrl
+ this.title = title
+ }
+
+ constructor (imagePath: Int, title: String?) {
+ this.imagePath = imagePath
+ this.title = title
+ }
+
+ constructor (imageUrl: String, centerCrop: Boolean) {
+ this.imageUrl = imageUrl
+ this.centerCrop = centerCrop
+ }
+
+ constructor (imagePath: Int, centerCrop: Boolean) {
+ this.imagePath = imagePath
+ this.centerCrop = centerCrop
+ }
+
+ constructor (imagePath: Int, title: String?, centerCrop: Boolean) {
+ this.imagePath = imagePath
+ this.title = title
+ this.centerCrop = centerCrop
+ }
+
+ constructor (imageUrl: String, title: String?, centerCrop: Boolean) {
+ this.imageUrl = imageUrl
+ this.title = title
+ this.centerCrop = centerCrop
+ }
+}
\ No newline at end of file
diff --git a/carousel/src/main/java/com/example/carousel/transformation/RoundedTransformation.kt b/carousel/src/main/java/com/example/carousel/transformation/RoundedTransformation.kt
new file mode 100644
index 0000000..2fd1046
--- /dev/null
+++ b/carousel/src/main/java/com/example/carousel/transformation/RoundedTransformation.kt
@@ -0,0 +1,175 @@
+package com.example.carousel.transformation
+
+import android.graphics.*
+import com.squareup.picasso.Transformation
+
+class RoundedTransformation @JvmOverloads constructor(radius:Int, margin:Int, cornerType: CornerType = CornerType.ALL):
+ Transformation {
+ private var mRadius:Float = 0f
+ private var mDiameter:Float = 0f
+ private var mMargin:Float = 0f
+ private var mCornerType: CornerType
+ enum class CornerType {
+ ALL,
+ TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,
+ TOP, BOTTOM, LEFT, RIGHT,
+ OTHER_TOP_LEFT, OTHER_TOP_RIGHT, OTHER_BOTTOM_LEFT, OTHER_BOTTOM_RIGHT,
+ DIAGONAL_FROM_TOP_LEFT, DIAGONAL_FROM_TOP_RIGHT
+ }
+ init{
+ mRadius = radius.toFloat()
+ mDiameter = (radius * 2).toFloat()
+ mMargin = margin.toFloat()
+ mCornerType = cornerType
+ }
+
+ override fun transform(source: Bitmap): Bitmap {
+ val width = source.getWidth()
+ val height = source.getHeight()
+ val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(bitmap)
+ val paint = Paint()
+ paint.setAntiAlias(true)
+ paint.setShader(BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP))
+ drawRoundRect(canvas, paint, width.toFloat(), height.toFloat())
+ source.recycle()
+ return bitmap
+ }
+ private fun drawRoundRect(canvas: Canvas, paint: Paint, width:Float, height:Float) {
+ val right = width - mMargin
+ val bottom = height - mMargin
+ when (mCornerType) {
+ CornerType.ALL -> canvas.drawRoundRect(RectF(mMargin, mMargin, right, bottom), mRadius, mRadius, paint)
+ CornerType.TOP_LEFT -> drawTopLeftRoundRect(canvas, paint, right, bottom)
+ CornerType.TOP_RIGHT -> drawTopRightRoundRect(canvas, paint, right, bottom)
+ CornerType.BOTTOM_LEFT -> drawBottomLeftRoundRect(canvas, paint, right, bottom)
+ CornerType.BOTTOM_RIGHT -> drawBottomRightRoundRect(canvas, paint, right, bottom)
+ CornerType.TOP -> drawTopRoundRect(canvas, paint, right, bottom)
+ CornerType.BOTTOM -> drawBottomRoundRect(canvas, paint, right, bottom)
+ CornerType.LEFT -> drawLeftRoundRect(canvas, paint, right, bottom)
+ CornerType.RIGHT -> drawRightRoundRect(canvas, paint, right, bottom)
+ CornerType.OTHER_TOP_LEFT -> drawOtherTopLeftRoundRect(canvas, paint, right, bottom)
+ CornerType.OTHER_TOP_RIGHT -> drawOtherTopRightRoundRect(canvas, paint, right, bottom)
+ CornerType.OTHER_BOTTOM_LEFT -> drawOtherBottomLeftRoundRect(canvas, paint, right, bottom)
+ CornerType.OTHER_BOTTOM_RIGHT -> drawOtherBottomRightRoundRect(canvas, paint, right, bottom)
+ CornerType.DIAGONAL_FROM_TOP_LEFT -> drawDiagonalFromTopLeftRoundRect(canvas, paint, right, bottom)
+ CornerType.DIAGONAL_FROM_TOP_RIGHT -> drawDiagonalFromTopRightRoundRect(canvas, paint, right, bottom)
+ //else -> canvas.drawRoundRect(RectF(mMargin, mMargin, right, bottom), mRadius, mRadius, paint)
+ }
+ }
+ private fun drawTopLeftRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, mMargin, mMargin + mDiameter, mMargin + mDiameter),
+ mRadius, mRadius, paint)
+ canvas.drawRect(RectF(mMargin, mMargin + mRadius, mMargin + mRadius, bottom), paint)
+ canvas.drawRect(RectF(mMargin + mRadius, mMargin, right, bottom), paint)
+ }
+ private fun drawTopRightRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(right - mDiameter, mMargin, right, mMargin + mDiameter), mRadius,
+ mRadius, paint)
+ canvas.drawRect(RectF(mMargin, mMargin, right - mRadius, bottom), paint)
+ canvas.drawRect(RectF(right - mRadius, mMargin + mRadius, right, bottom), paint)
+ }
+ private fun drawBottomLeftRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, bottom - mDiameter, mMargin + mDiameter, bottom),
+ mRadius, mRadius, paint)
+ canvas.drawRect(RectF(mMargin, mMargin, mMargin + mDiameter, bottom - mRadius), paint)
+ canvas.drawRect(RectF(mMargin + mRadius, mMargin, right, bottom), paint)
+ }
+ private fun drawBottomRightRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(right - mDiameter, bottom - mDiameter, right, bottom), mRadius,
+ mRadius, paint)
+ canvas.drawRect(RectF(mMargin, mMargin, right - mRadius, bottom), paint)
+ canvas.drawRect(RectF(right - mRadius, mMargin, right, bottom - mRadius), paint)
+ }
+ private fun drawTopRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
+ paint)
+ canvas.drawRect(RectF(mMargin, mMargin + mRadius, right, bottom), paint)
+ }
+ private fun drawBottomRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRect(RectF(mMargin, mMargin, right, bottom - mRadius), paint)
+ }
+ private fun drawLeftRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRect(RectF(mMargin + mRadius, mMargin, right, bottom), paint)
+ }
+ private fun drawRightRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRect(RectF(mMargin, mMargin, right - mRadius, bottom), paint)
+ }
+ private fun drawOtherTopLeftRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRoundRect(
+ RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRect(RectF(mMargin, mMargin, right - mRadius, bottom - mRadius), paint)
+ }
+ private fun drawOtherTopRightRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRoundRect(
+ RectF(mMargin, bottom - mDiameter, right, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRect(RectF(mMargin + mRadius, mMargin, right, bottom - mRadius), paint)
+ }
+ private fun drawOtherBottomLeftRoundRect(canvas: Canvas, paint: Paint, right:Float, bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
+ paint)
+ canvas.drawRoundRect(
+ RectF(right - mDiameter, mMargin, right, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRect(RectF(mMargin, mMargin + mRadius, right - mRadius, bottom), paint)
+ }
+ private fun drawOtherBottomRightRoundRect(canvas: Canvas, paint: Paint, right:Float,
+ bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, mMargin, right, mMargin + mDiameter), mRadius, mRadius,
+ paint)
+ canvas.drawRoundRect(
+ RectF(mMargin, mMargin, mMargin + mDiameter, bottom), mRadius, mRadius,
+ paint)
+ canvas.drawRect(RectF(mMargin + mRadius, mMargin + mRadius, right, bottom), paint)
+ }
+ private fun drawDiagonalFromTopLeftRoundRect(canvas: Canvas, paint: Paint, right:Float,
+ bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(mMargin, mMargin, mMargin + mDiameter, mMargin + mDiameter),
+ mRadius, mRadius, paint)
+ canvas.drawRoundRect(
+ RectF(right - mDiameter, bottom - mDiameter, right, bottom), mRadius,
+ mRadius, paint)
+ canvas.drawRect(RectF(mMargin, mMargin + mRadius, right - mDiameter, bottom), paint)
+ canvas.drawRect(RectF(mMargin + mDiameter, mMargin, right, bottom - mRadius), paint)
+ }
+ private fun drawDiagonalFromTopRightRoundRect(canvas: Canvas, paint: Paint, right:Float,
+ bottom:Float) {
+ canvas.drawRoundRect(
+ RectF(right - mDiameter, mMargin, right, mMargin + mDiameter), mRadius,
+ mRadius, paint)
+ canvas.drawRoundRect(
+ RectF(mMargin, bottom - mDiameter, mMargin + mDiameter, bottom),
+ mRadius, mRadius, paint)
+ canvas.drawRect(RectF(mMargin, mMargin, right - mRadius, bottom - mRadius), paint)
+ canvas.drawRect(RectF(mMargin + mRadius, mMargin + mRadius, right, bottom), paint)
+ }
+ override fun key():String {
+ return ("RoundedTransformation(radius=" + mRadius + ", margin=" + mMargin + ", diameter="
+ + mDiameter + ", cornerType=" + mCornerType.name + ")")
+ }
+}
\ No newline at end of file
diff --git a/carousel/src/main/res/drawable-v24/ic_launcher_foreground.xml b/carousel/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/carousel/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/drawable/default_selected_dot.xml b/carousel/src/main/res/drawable/default_selected_dot.xml
new file mode 100644
index 0000000..6ac42ce
--- /dev/null
+++ b/carousel/src/main/res/drawable/default_selected_dot.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/drawable/default_unselected_dot.xml b/carousel/src/main/res/drawable/default_unselected_dot.xml
new file mode 100644
index 0000000..ec78956
--- /dev/null
+++ b/carousel/src/main/res/drawable/default_unselected_dot.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/drawable/error.png b/carousel/src/main/res/drawable/error.png
new file mode 100644
index 0000000..4cd813c
Binary files /dev/null and b/carousel/src/main/res/drawable/error.png differ
diff --git a/carousel/src/main/res/drawable/gradient.xml b/carousel/src/main/res/drawable/gradient.xml
new file mode 100644
index 0000000..c2bc013
--- /dev/null
+++ b/carousel/src/main/res/drawable/gradient.xml
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/drawable/ic_launcher_background.xml b/carousel/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/carousel/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/carousel/src/main/res/drawable/placeholder.png b/carousel/src/main/res/drawable/placeholder.png
new file mode 100644
index 0000000..963c65f
Binary files /dev/null and b/carousel/src/main/res/drawable/placeholder.png differ
diff --git a/carousel/src/main/res/layout/image_slider.xml b/carousel/src/main/res/layout/image_slider.xml
new file mode 100644
index 0000000..0581de6
--- /dev/null
+++ b/carousel/src/main/res/layout/image_slider.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/layout/pager_row.xml b/carousel/src/main/res/layout/pager_row.xml
new file mode 100644
index 0000000..a2708d1
--- /dev/null
+++ b/carousel/src/main/res/layout/pager_row.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/carousel/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/carousel/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/carousel/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/carousel/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/mipmap-hdpi/ic_launcher.webp b/carousel/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/carousel/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/carousel/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/carousel/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/carousel/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/carousel/src/main/res/mipmap-mdpi/ic_launcher.webp b/carousel/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/carousel/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/carousel/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/carousel/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/carousel/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/carousel/src/main/res/mipmap-xhdpi/ic_launcher.webp b/carousel/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/carousel/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/carousel/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/carousel/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/carousel/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/carousel/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/carousel/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/carousel/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/carousel/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/carousel/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/carousel/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/carousel/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/carousel/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/carousel/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/carousel/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/carousel/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/carousel/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/carousel/src/main/res/values-night/themes.xml b/carousel/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..beff2b4
--- /dev/null
+++ b/carousel/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/values/attrs.xml b/carousel/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..fbc77c1
--- /dev/null
+++ b/carousel/src/main/res/values/attrs.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/main/res/values/colors.xml b/carousel/src/main/res/values/colors.xml
new file mode 100644
index 0000000..f8c6127
--- /dev/null
+++ b/carousel/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/carousel/src/main/res/values/strings.xml b/carousel/src/main/res/values/strings.xml
new file mode 100644
index 0000000..711b210
--- /dev/null
+++ b/carousel/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ carousel
+
\ No newline at end of file
diff --git a/carousel/src/main/res/values/themes.xml b/carousel/src/main/res/values/themes.xml
new file mode 100644
index 0000000..886a466
--- /dev/null
+++ b/carousel/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/carousel/src/test/java/com/example/carousel/ExampleUnitTest.kt b/carousel/src/test/java/com/example/carousel/ExampleUnitTest.kt
new file mode 100644
index 0000000..8f6b192
--- /dev/null
+++ b/carousel/src/test/java/com/example/carousel/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.carousel
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 20e2a01..316a8ed 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -20,4 +20,5 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
-android.nonTransitiveRClass=true
\ No newline at end of file
+android.nonTransitiveRClass=true
+org.gradle.configuration-cache=true
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4f118a6..2349fe4 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,7 +1,7 @@
[versions]
agp = "8.7.3"
androidMavenGradlePlugin = "1.4.1"
-carouselsKotlin = "0.0.2"
+glide = "4.10.0"
gradle = "3.5.4"
kotlin = "1.9.24"
coreKtx = "1.15.0"
@@ -18,7 +18,7 @@ picasso = "2.71828"
android-maven-gradle-plugin = { module = "com.github.dcendents:android-maven-gradle-plugin", version.ref = "androidMavenGradlePlugin" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-multidex = { module = "androidx.multidex:multidex", version.ref = "multidex" }
-carousels-kotlin = { module = "com.github.UmarAuna:Carousels-Kotlin", version.ref = "carouselsKotlin" }
+glide = { module = "com.github.bumptech.glide:glide", version.ref = "glide" }
gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 20ec24a..56b46ad 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -21,4 +21,5 @@ dependencyResolutionManagement {
}
rootProject.name = "Image Carousel Library"
-include(":app")
\ No newline at end of file
+include(":app")
+include(":carousel")