Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selected item indicator color can't edit #186

Open
Aminul-Haque-Aome opened this issue Sep 17, 2023 · 2 comments
Open

Selected item indicator color can't edit #186

Aminul-Haque-Aome opened this issue Sep 17, 2023 · 2 comments

Comments

@Aminul-Haque-Aome
Copy link

In ShiftIndicatorType, How can I change selected item indicator color

@notsatria
Copy link

I also faced this problem, and the solution is by creating my own Indicator, maybe you can use mine as a reference:

@Composable
fun Indicator(
    dotCount: Int,
    currentPage: Int,
    modifier: Modifier = Modifier,
    dotSpacing: Dp = 8.dp,
    dotSize: Dp = 12.dp,
) {
    Row(
        horizontalArrangement = Arrangement.spacedBy(dotSpacing),
        verticalAlignment = Alignment.CenterVertically,
        modifier = modifier
    ) {
        for (i in 0 until dotCount) {
            val isActive = currentPage == i
            val color by animateColorAsState(targetValue =  if (isActive) Purple else DotIndicatorDefault,
                label = ""
            )
            val width by animateDpAsState(targetValue = if (isActive) dotSize * 3 else dotSize,
                label = ""
            )
            Box(
                modifier = Modifier
                    .width(width)
                    .height(dotSize)
                    .clip(CircleShape)
                    .background(color)
            )
        }
    }
}

Usage:

 Indicator(
                dotCount = pagerState.pageCount,
                currentPage = pagerState.currentPage,
                dotSpacing = 4.dp,
                modifier = Modifier
                    .align(Alignment.BottomCenter)
                    .padding(bottom = 8.dp)
                    .height(12.dp)
            )

@ivanboltyshev
Copy link

ivanboltyshev commented Dec 27, 2024

I fixed my problem by extending the IndicatorType class.

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.times
import com.tbuonomo.viewpagerdotsindicator.compose.model.DotGraphic
import com.tbuonomo.viewpagerdotsindicator.compose.type.IndicatorType
import kotlin.math.absoluteValue
import kotlin.math.roundToInt

class CustomBalloonIndicatorType(
    private val dotsGraphic: DotGraphic = DotGraphic(size = 12.dp),
    private val selectedDotColor: Color = dotsGraphic.color,
    private val balloonSizeFactor: Float = 1.5f,
) : IndicatorType() {
    @Composable
    override fun IndicatorTypeComposable(
        globalOffsetProvider: () -> Float,
        modifier: Modifier,
        dotCount: Int,
        dotSpacing: Dp,
        onDotClicked: ((Int) -> Unit)?,
    ) {
        Box(modifier = modifier) {
            LazyRow(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(dotsGraphic.size * balloonSizeFactor),
                content = {
                    items(dotCount) { dotIndex ->
                        val dotSize by remember(globalOffsetProvider()) {
                            derivedStateOf { computeDotWidth(dotIndex, globalOffsetProvider()) }
                        }
                        val isSelected = remember(globalOffsetProvider()) {
                            derivedStateOf { dotIndex == globalOffsetProvider().roundToInt() }
                        }
                        val dotColor = if (isSelected.value) selectedDotColor else dotsGraphic.color
                        val dotModifier by remember(dotSize) {
                            mutableStateOf(
                                Modifier
                                    .scale(dotSize)
                                    .clickable {
                                        onDotClicked?.invoke(dotIndex)
                                    })
                        }
                        CustomDot(dotsGraphic.copy(color = dotColor), dotModifier)
                    }
                },
                horizontalArrangement = Arrangement.spacedBy(
                    dotSpacing, alignment = Alignment.CenterHorizontally
                ),
                contentPadding = PaddingValues(start = dotSpacing, end = dotSpacing),
                verticalAlignment = Alignment.CenterVertically
            )
        }
    }

    private fun computeDotWidth(currentDotIndex: Int, globalOffset: Float): Float {
        val diffFactor = 1f - (currentDotIndex - globalOffset).absoluteValue.coerceAtMost(1f)
        val sizeToAdd = ((balloonSizeFactor - 1f).coerceAtLeast(0f) * dotsGraphic.size * diffFactor)
        return (dotsGraphic.size + sizeToAdd) / dotsGraphic.size
    }
}

@Composable
private fun CustomDot(
    graphic: DotGraphic,
    modifier: Modifier,
) {
    Box(
        modifier = modifier
            .background(
                color = graphic.color,
                shape = graphic.shape,
            )
            .size(graphic.size)
            .let {
                graphic.borderWidth?.let { borderWidth ->
                    it.border(
                        width = borderWidth,
                        color = graphic.borderColor,
                        shape = graphic.shape
                    )
                } ?: it
            }
    )
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants