Skip to content

Commit

Permalink
Bug fixed, onClick/onLongClick added, header sample added, doc added
Browse files Browse the repository at this point in the history
+ onClick and onLongClick implemented again
+ fix the clash with onClick/onLongClick and touchToPause feature
+ header example added to sample
+ documentation added to listener
+ jcenter removed
+ kotlin version updated
+ libraries updated
  • Loading branch information
ImaginativeShohag committed May 12, 2021
1 parent 33532d1 commit 35d32f2
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 58 deletions.
8 changes: 3 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.4.32'
ext.kotlin_version = '1.5.0'
repositories {
google()
jcenter()

mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.0'
Expand All @@ -18,8 +17,7 @@ buildscript {
allprojects {
repositories {
google()
jcenter()

mavenCentral()
}
}

Expand Down
4 changes: 2 additions & 2 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
Expand All @@ -66,5 +66,5 @@ dependencies {
kapt 'com.github.bumptech.glide:compiler:4.12.0'

// debugImplementation because LeakCanary should only run in debug builds.
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import me.relex.circleindicator.CircleIndicator2;

Expand Down Expand Up @@ -120,6 +122,16 @@ public ViewBinding onCreateViewHolder(@NotNull LayoutInflater layoutInflater, @N
// ...
return null;
}

@Override
public void onLongClick(int position, @NotNull CarouselItem dataObject) {
// ...
}

@Override
public void onClick(int position, @NotNull CarouselItem carouselItem) {
// ...
}
});

CircleIndicator2 indicator = findViewById(R.id.custom_indicator);
Expand All @@ -133,12 +145,17 @@ public ViewBinding onCreateViewHolder(@NotNull LayoutInflater layoutInflater, @N

List<CarouselItem> list = new ArrayList<>();

// Dummy header
Map<String, String> headers = new HashMap<>();
headers.put("header_key", "header_value");

int index = 1;
for (String item : DataSet.INSTANCE.getOne()) {
list.add(
new CarouselItem(
item,
"Image " + index++ + " of " + DataSet.INSTANCE.getOne().size()
"Image " + index++ + " of " + DataSet.INSTANCE.getOne().size(),
headers
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
Expand Down Expand Up @@ -99,34 +100,34 @@ class KotlinActivity : AppCompatActivity() {
infiniteCarousel = true
touchToPause = true

onScrollListener = object : CarouselOnScrollListener {
override fun onScrollStateChanged(
recyclerView: RecyclerView,
newState: Int,
position: Int,
carouselItem: CarouselItem?
) {
// ...
carouselListener = object : CarouselListener {
override fun onClick(position: Int, carouselItem: CarouselItem) {
Toast.makeText(this@KotlinActivity, "You clicked it.", Toast.LENGTH_SHORT)
.show()
}

override fun onScrolled(
recyclerView: RecyclerView,
dx: Int,
dy: Int,
position: Int,
carouselItem: CarouselItem?
) {
// ...
override fun onLongClick(position: Int, dataObject: CarouselItem) {
Toast.makeText(
this@KotlinActivity,
"You long clicked it.",
Toast.LENGTH_SHORT
)
.show()
}
}

// Dummy header
val headers = mutableMapOf<String, String>()
headers["header_key"] = "header_value"

val listOne = mutableListOf<CarouselItem>()

for ((index, item) in DataSet.one.withIndex()) {
listOne.add(
CarouselItem(
imageUrl = item,
caption = "Image ${index + 1} of ${DataSet.one.size}"
caption = "Image ${index + 1} of ${DataSet.one.size}",
headers = headers
)
)
}
Expand Down
1 change: 0 additions & 1 deletion whynotimagecarousel/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.imaginativeworld.whynotimagecarousel

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
Expand Down Expand Up @@ -478,25 +477,21 @@ class ImageCarousel(
initAdapter()
initListeners()
initAutoPlay()
initTouchListener()
}

@SuppressLint("ClickableViewAccessibility")
private fun initTouchListener() {
recyclerView.setOnTouchListener { _, event ->
if (touchToPause) {
when (event?.action) {
MotionEvent.ACTION_UP -> {
resumeAutoPlay()
}
MotionEvent.ACTION_DOWN -> {
pauseAutoPlay()
}
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
if (touchToPause) {
when (event?.action) {
MotionEvent.ACTION_UP -> {
resumeAutoPlay()
}
MotionEvent.ACTION_DOWN -> {
pauseAutoPlay()
}
}

false
}

return super.onInterceptTouchEvent(event)
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,13 @@ open class FiniteCarouselAdapter(
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val item = getItem(position) ?: return

/**
* If the sum of consecutive two items of a [RecyclerView] is not greater than
* the [ImageCarousel] view width, then the [scrollToPosition] method will not work
* as expected. So we will check the width of the element and increase the minimum width
* for fixing the problem if [autoWidthFixing] is true.
*/
val realItemPosition = getRealDataPosition(position)
val item = getItem(realItemPosition) ?: return

// If the sum of consecutive two items of a RecyclerView is not greater than
// the ImageCarousel view width, then the scrollToPosition() method will not work
// as expected. So we will check the width of the element and increase the minimum width
// for fixing the problem if autoWidthFixing is true.
if (autoWidthFixing && carouselType == CarouselType.SHOWCASE) {
val containerWidth = recyclerView.width
if (holder.itemView.layoutParams.width >= 0 &&
Expand All @@ -73,14 +72,26 @@ open class FiniteCarouselAdapter(
holder.binding.img.scaleType = imageScaleType

holder.binding.img.setImage(item, imagePlaceholder)

listener?.apply {
holder.itemView.setOnClickListener {
this.onClick(realItemPosition, item)
}

holder.itemView.setOnLongClickListener {
this.onLongClick(realItemPosition, item)

true
}
}
}

// Init listeners
listener?.onBindViewHolder(
holder.binding,
imageScaleType,
item,
getRealDataPosition(position)
realItemPosition
)

// Init start and end offsets
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,50 @@ import androidx.viewbinding.ViewBinding
import org.imaginativeworld.whynotimagecarousel.model.CarouselItem

interface CarouselListener {
fun onCreateViewHolder(layoutInflater: LayoutInflater, parent: ViewGroup): ViewBinding?
/**
* Inflate custom view here using view binding.
* It's mapped with RecyclerView.Adapter#onCreateViewHolder.
*
* @param layoutInflater for inflating layout.
* @param parent the parent of the generated hierarchy.
* @return ViewBinding of the custom view.
*/
fun onCreateViewHolder(layoutInflater: LayoutInflater, parent: ViewGroup): ViewBinding? = null

/**
* Bind view with data.
* It's mapped with RecyclerView.Adapter#onBindViewHolder.
*
* @param binding The ViewBinding returned in onCreateViewHolder.
* @param imageScaleType selected ImageView.ScaleType provided in imageScaleType attribute.
* @param item current CarouselItem item for bind.
* @param position current data position.
*/
fun onBindViewHolder(
binding: ViewBinding,
imageScaleType: ImageView.ScaleType,
item: CarouselItem,
position: Int
)
) {
}

/**
* When an item view is clicked it will be invoked.
*
* Note: It will not work for the custom layout.
*
* @param position Data item position.
* @param carouselItem Data item of the clicked view.
*/
fun onClick(position: Int, carouselItem: CarouselItem) {}

/**
* When an item view is long clicked it will be invoked.
*
* Note: It will not work for the custom layout.
*
* @param position Data item position.
* @param carouselItem Data item of the long clicked view.
*/
fun onLongClick(position: Int, dataObject: CarouselItem) {}
}

0 comments on commit 35d32f2

Please sign in to comment.