Skip to content

Instantly share code, notes, and snippets.

@PaponAhasan
Last active January 4, 2024 06:34
Show Gist options
  • Save PaponAhasan/a3de7c666926da0f75eb01e25282e9be to your computer and use it in GitHub Desktop.
Save PaponAhasan/a3de7c666926da0f75eb01e25282e9be to your computer and use it in GitHub Desktop.
Image Slider

Set lottie loading_animation

implementation 'com.airbnb.android:lottie:6.2.0'

@raw/loading_animation.json

<RelativeLayout
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:layout_marginHorizontal="16dp"
    android:layout_marginTop="16dp"
    android:gravity="center">

       <com.airbnb.lottie.LottieAnimationView
           android:id="@+id/lottieAnimationView"
           android:layout_width="80dp"
           android:layout_height="80dp"
           app:lottie_autoPlay="true"
           app:lottie_loop="true"
           app:lottie_rawRes="@raw/loading_animation" />

        <androidx.viewpager2.widget.ViewPager2
           android:id="@+id/viewPager"
           android:layout_width="match_parent"
           android:layout_height="150dp"
           android:visibility="gone" />

        <com.itmedicus.hpl.adapter.SliderIndicator
            android:id="@+id/sliderIndicator"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="16dp"
            android:visibility="gone" />
</RelativeLayout>
//com.itmedicus.hpl.adapter.SliderIndicator

class SliderIndicator @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    private var dotSize = 14
    private var dotSpacing = 8
    private var dotDrawableRes: Int = R.drawable.dot_selector

    fun setupWithViewPager(viewPager: ViewPager2) {
        viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                updateIndicator(position)
            }
        })

        addDots(viewPager.adapter?.itemCount ?: 0)
    }

    private fun addDots(count: Int) {
        removeAllViews()

        for (i in 0 until count) {
            val dot = ImageView(context)
            val params = LayoutParams(dotSize, dotSize)
            params.setMargins(dotSpacing, 0, dotSpacing, 0)
            dot.layoutParams = params
            dot.setImageResource(dotDrawableRes)
            dot.scaleType = ImageView.ScaleType.CENTER_INSIDE
            addView(dot)
        }

        updateIndicator(0) // Set the initial state of the dots
    }

    private fun updateIndicator(position: Int) {
        for (i in 0 until childCount) {
            val dot = getChildAt(i) as ImageView
            dot.isSelected = i == position
        }
    }
}

//item_image_slider

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    app:cardCornerRadius="10dp"
    android:elevation="0dp"
    android:gravity="center">
    <ImageView
        android:id="@+id/sImage"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/rounded_corner"
        android:scaleType="fitXY"/>
<!--    <ProgressBar-->
<!--        android:layout_width="30dp"-->
<!--        android:layout_height="30dp"-->
<!--        android:id="@+id/progress_image"/>-->
</androidx.cardview.widget.CardView>
//adapter
class ImageSliderAdapter(private val images: List<SliderListDataItem>) : RecyclerView.Adapter<ImageSliderAdapter.ImageSliderViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ImageSliderViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_image_slider, parent, false)
        return ImageSliderViewHolder(view)
    }

    override fun onBindViewHolder(holder: ImageSliderViewHolder, position: Int) {
        holder.bind(images[position])
    }

    override fun getItemCount(): Int = images.size

    inner class ImageSliderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(image: SliderListDataItem) {
            Glide.with(itemView.context)
                .load(image.image)
                .into(itemView.findViewById(R.id.sImage))

          //private val imageView: ImageView = itemView.findViewById(R.id.imageView)
          //imageView.setImageResource(imageResId)
        }
    }
}
class ProductBrief : AppCompatActivity(){

    private lateinit var imageSliderAdapter: ImageSliderAdapter
    private var currentPage = 0
    lateinit var lottieAnimationView: LottieAnimationView

    private lateinit var binding: ActivityProductBriefBinding
    private lateinit var productVM: ProductViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityProductBriefBinding.inflate(layoutInflater)
        setContentView(binding.root)

        productVM = ViewModelProvider(this)[ProductViewModel::class.java]
        lottieAnimationView = binding.lottieAnimationView

        //------------------To Pass Data from API-----------------------//
        /**
         * Load slider here
         */
        productVM.requestHomeSlider()
        productVM.isRequesting.observe(this, Observer {
            when (it) {
                true -> {
                    binding.apply {
                        viewPager.visibility = View.GONE
                        sliderIndicator.visibility = View.GONE
                        lottieAnimationView.visibility = View.VISIBLE
                        lottieAnimationView.playAnimation()
//                        sliderProgress.visibility = View.VISIBLE
                    }
                }

                false -> {
                    binding.apply {
                        viewPager.visibility = View.VISIBLE
                        sliderIndicator.visibility = View.VISIBLE
                        lottieAnimationView.visibility - View.GONE
                        lottieAnimationView.cancelAnimation()
//                        sliderProgress.visibility = View.GONE

                    }
                }
            }
        })
        productVM.slideData.observe(this, Observer { it ->
            if (it.isNotEmpty()) {
          
                val SliderListProductItem = mutableListOf<SliderListDataItem>()
                imageSliderAdapter = ImageSliderAdapter(SliderListProductItem)
                binding.viewPager.adapter = imageSliderAdapter

                binding.sliderIndicator.setupWithViewPager(binding.viewPager)
                val handler = android.os.Handler()
                val update = Runnable {
                    if (currentPage == it.size) {
                        currentPage = 0
                    }
                    binding.viewPager.setCurrentItem(currentPage++, true)
                }

                val delay: Long = 5000

                val autoSlider = object : Runnable {
                    override fun run() {
                        update.run()
                        handler.postDelayed(this, delay)
                    }
                }
                handler.postDelayed(autoSlider, delay)
            }
        })

        /**
         * product here
         */
        productVM.requestProductList(limit = 10, page = 1, searchText = "")
        productVM.productListData.observe(this, Observer { data ->
            when (data.isEmpty()) {
                true -> Log.e("Product List", "No data found")
                false -> {
                    binding.apply {
                        productRecyclerView.layoutManager = LinearLayoutManager(this@ProductBrief)
                        productRecyclerView.adapter = ProductListAdapter(data, this@ProductBrief)
                    }

                }
            }
        })

        //-----------------------Progress bar-------------------------------//

        productVM.isRequesting.observe(this, Observer {
            binding.progressView.visibility = when (it) {
                true -> View.VISIBLE
                else -> View.GONE
            }
        })

    }
}
data class SliderListDataModel(
    @SerializedName("json_obj") val jsonObj: SliderListJsonObject,
    val success: Boolean,
    val status: Int,
    val message: Any
)

data class SliderListJsonObject(
    val data: List<SliderListDataItem>,
    val meta: SliderListMeta
)

data class SliderListDataItem(
    val id: Int,
    val title: String,
    val image: String,
    @SerializedName("external_link") val externalLink: String?,
    val type: String,
    val date: String,
    @SerializedName("created_at") val createdAt: String,
    @SerializedName("updated_at") val updatedAt: String
) : Serializable



data class SliderListMeta(
    @SerializedName("current_page") val currentPage: Int,
    val from: Int,
    @SerializedName("last_page") val lastPage: Int,
    val path: String,
    @SerializedName("per_page") val perPage: Int,
    val to: Int,
    val total: Int
)
class ProductViewModel (val context: Application) : AndroidViewModel(context) {

    val thisClass = "ProductClass"
    var isRequesting = MutableLiveData<Boolean>()

    val productListData: MutableLiveData<List<ProductListDataItem>> =
        MutableLiveData<List<ProductListDataItem>>()

    val slideData: MutableLiveData<List<SliderListDataItem>> =
        MutableLiveData<List<SliderListDataItem>>()

    init {
        isRequesting.value = false
    }

    fun requestProductList(limit: Int = 10, page: Int = 1, searchText: String) {
        viewModelScope.launch {

            try {
                isRequesting.value = true
                val response = RetrofitClient.instance().getProductList(
                    limit = limit,
                    page = page,
                    searchTxt = searchText,
                    token = "Bearer ${Prefrences(context).token}"
                )
                /**
                 * response has 2 property
                 * [success] [failed]
                 */
                if (response.isSuccessful) {
                    isRequesting.value = false

                    response.body().let {
                        Log.d(thisClass, it?.status.toString())
                        productListData.value = it?.jsonObj?.data
                    }

                } else {
                    isRequesting.value = false
                }
            } catch (e: Exception) {
                isRequesting.value = false
                Log.d(thisClass, e.toString())
            } finally {
                isRequesting.value = false
            }
        }
    }

    fun requestHomeSlider(limit: Int = 10, page: Int = 1, searchText: String = "") {
        viewModelScope.launch {

            try {
                isRequesting.value = true
                val response = RetrofitClient.instance().getSliderList(
                    limit = limit,
                    page = page,
                    searchTxt = searchText,
                    token = "Bearer ${Prefrences(context).token}"
                )

                /**
                 * response has 2 property
                 * [success] [failed]
                 */
                if (response.isSuccessful) {
                    isRequesting.value = false

                    response.body().let {
//                        Log.d(thisClass, it?.status.toString())
                        slideData.value = it?.jsonObj?.data
                    }

                } else {
                    isRequesting.value = false
                }

            } catch (e: Exception) {
                isRequesting.value = false
                Log.d(thisClass, e.toString())
            } finally {
                isRequesting.value = false
            }
        }
    }
}
    @GET("product/product-list")
    suspend fun getProductList(
        @Query("limit") limit:Int,
        @Query("page") page: Int,
        @Query("searchTxt") searchTxt: String,
        @Query("order") order: String = "desc",
        @Header("Authorization") token: String
    ): Response<ProductListDataModel>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment