欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android?Compose?自定義滑動進度條的實現(xiàn)代碼

 更新時間:2025年06月12日 10:16:46   作者:小鐵-Android  
這篇文章主要介紹了Android?Compose自定義滑動進度條的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧

Android Compose 自定義滑動進度條

androidx.compose.material3 我用1.2.0版本的Slider非常好用,但是升級到1.3.2后滑軌后面多了個點,滑塊背景也移除不掉而且默認透明了我暫時沒有找到讓他不透明。所以自定義了一個先用著。

@Composable
fun CustomSlider(
    state: CustomSliderState,
    modifier: Modifier = Modifier,
    trackHeight: Dp = 4.dp,
    thumbSize: Dp = 24.dp,
    trackColor: Color = Color.Gray,
    progressColor: Color = Color.Blue,
    thumbColor: Color = Color.White,
    onValueChange: ((Float) -> Unit)? = null,
    onValueChangeFinished: ((Float) -> Unit)? = null
) {
    var sliderWidth by remember { mutableFloatStateOf(0f) }
    Box(
        modifier = modifier
            .height(thumbSize + 16.dp) // 確保足夠高度容納滑塊
            .pointerInput(Unit) {
                awaitEachGesture {
                    val event = awaitPointerEvent(PointerEventPass.Initial)
                    if (event.changes.firstOrNull()?.changedToDown() == true) {
                        val down = awaitFirstDown(requireUnconsumed = true)
                        state.setPressed(true)
                        val newPosition = (event.changes.first().position.x / sliderWidth).coerceIn(0f, 1f)
                        val newValue = state.range.start + newPosition * (state.range.endInclusive - state.range.start)
                        state.updateValue(newValue)
                        onValueChange?.invoke(state.value)
                        var drag: PointerInputChange?
                        do {
                            drag = awaitTouchSlopOrCancellation(down.id) { change, _ ->
                                if (change.positionChange() != Offset.Zero) change.consume()
                            }
                        } while (drag != null && !drag.isConsumed)
                        if (drag != null) {
                            val dragResult = drag(drag.id) {
                                val newPosition = (it.position.x / sliderWidth).coerceIn(0f, 1f)
                                val newValue = state.range.start + newPosition * (state.range.endInclusive - state.range.start)
                                state.updateValue(newValue)
                                onValueChange?.invoke(state.value)
                            }
                            // 確保完成回調(diào)被觸發(fā)
                            if (!dragResult || drag.isConsumed) {
                                onValueChangeFinished?.invoke(state.value)
                            }
                        } else {
                            onValueChangeFinished?.invoke(state.value)
                        }
                    }
                }
            },
        contentAlignment = Alignment.CenterStart
    ) {
        // 繪制軌道(Track)
        Canvas(
            modifier = Modifier
                .fillMaxWidth()
                .clip(CircleShape)
                .height(trackHeight)
                .align(Alignment.CenterStart)
                .onSizeChanged { size ->
                    sliderWidth = size.width.toFloat()
                }
        ) {
            // 背景軌道
            drawRect(
                color = trackColor,
                size = Size(size.width.toFloat(), trackHeight.toPx())
            )
            // 進度軌道
            drawRect(
                color = progressColor,
                size = Size(
                    width = (state.value - state.range.start) / (state.range.endInclusive - state.range.start) * size.width,
                    height = trackHeight.toPx()
                )
            )
        }
        // 滑塊(Thumb)根據(jù)你自己需求替換
        Box(
            modifier = Modifier
                .offset {
                    IntOffset(
                        x = ((state.value - state.range.start) / (state.range.endInclusive - state.range.start) * sliderWidth - thumbSize.toPx()/2).toInt(),
                        y = 0
                    )
                }
                .shadow(4.dp, CircleShape)
                .size(thumbSize)
                .background(thumbColor, CircleShape)
        )
    }
}
class CustomSliderState(
    initialValue: Float,
    internal val range: ClosedFloatingPointRange<Float> = 0f..1f
) {
    private val _value = mutableFloatStateOf(initialValue.coerceIn(range))
    private val _isPressed = mutableStateOf(false) // 新增按下狀態(tài)
    val value: Float
        get() = _value.floatValue
    val isPressed: Boolean // 暴露給外部
        get() = _isPressed.value
    fun updateValue(newValue: Float) {
        _value.floatValue = newValue.coerceIn(range)
    }
    fun setPressed(pressed: Boolean) { // 更新按下狀態(tài)
        _isPressed.value = pressed
    }
}
@Composable
fun rememberCustomSliderState(
    initialValue: Float = 0f,
    range: ClosedFloatingPointRange<Float> = 0f..1f
): CustomSliderState {
    return remember { CustomSliderState(initialValue, range) }
}

使用

 val sliderState = rememberCustomSliderState(
        initialValue = 0.5f,
        range = 0f..100f
    )
    CustomSlider(
        state = sliderState,
        modifier = Modifier.fillMaxWidth().padding(horizontal = 36.dp),
        trackHeight = 12.dp,
        thumbSize = 24.dp,
        trackColor = Color.LightGray,
        progressColor = Color(0xFF6200EE),
        thumbColor = Color.White,
        onValueChange = {
            Log.e("onValueChange","float---$it")
        },
        onValueChangeFinished = {
            Log.e("onValueChangeFinished","float---$it")
        }
    )

補充:Compose筆記(十五)--進度條

          這一節(jié)了解一下Compose中的進度條,有兩種類型的進度條可供使用,分別是線性進度條(LinearProgressIndicator)和圓形進度條(CircularProgressIndicator),每種進度條又可分為確定模式和不確定模式。

1. 不確定模式
在不確定模式下,進度條會持續(xù)滾動,用于表示操作正在進行,但無法確定具體的完成進度。
2. 確定模式
在確定模式下,需要傳入 progress 參數(shù),該參數(shù)的值范圍是 0 到 1,表示操作的完成進度。

栗子:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
@Composable
fun ProgressBarsExample() {
    Column(
        modifier = Modifier.padding(top = 40.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        // 不確定線性進度條
        IndeterminateLinearProgressBar()
        // 確定線性進度條
        DeterminateLinearProgressBar()
        // 不確定圓形進度條
        IndeterminateCircularProgressBar()
        // 確定圓形進度條
        DeterminateCircularProgressBar()
        // 自定義進度條樣式
        CircularProgressBarExample()
    }
}
@Composable
fun IndeterminateLinearProgressBar() {
    LinearProgressIndicator()
}
@Composable
fun DeterminateLinearProgressBar() {
    var progress by remember {  mutableStateOf(0.5f)}
    LinearProgressIndicator(
        progress = progress
    )
}
@Composable
fun IndeterminateCircularProgressBar() {
    CircularProgressIndicator()
}
@Composable
fun DeterminateCircularProgressBar() {
    var progress by remember { mutableStateOf(0.7f)}
    CircularProgressIndicator(
        progress = progress
    )
}
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun CircularProgressBarExample() {
    var progress by remember {  mutableStateOf(0.2f) }
    Column(
        modifier = Modifier.size(400.dp).padding(top = 20.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        CircularProgressBar(
            progress = progress,
            modifier = Modifier.size(150.dp),
            indicatorStrokeWidth = 4.dp,
            backgroundCircleColor = if(progress in 0.0..0.2) Color.Yellow
            else if(progress>0.2 && progress<=0.5)
                Color.Red
            else if(progress>0.5 && progress<0.8)
                Color.Blue
            else Color.White,
            fontSize = 12.sp
        )
        Button(
            modifier = Modifier.padding(top = 20.dp),
            onClick = {
                progress = if (progress < 1f) progress + 0.1f else 0f
            }
        ) {
            Text(text = "進度測試")
        }
    }
}
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun CircularProgressBar(
    progress: Float,
    modifier: Modifier = Modifier,
    backgroundIndicatorColor: Color = Color.LightGray,
    indicatorColor: Color = Color.Blue,
    indicatorStrokeWidth: Dp = 10.dp,
    backgroundCircleColor: Color = Color.White,
    textColor: Color = Color.Black,
    fontSize: TextUnit = 20.sp
) {
    Box(
        modifier = modifier,
        contentAlignment = Alignment.Center
    ) {
        Canvas(modifier = modifier) {
            drawBackgroundCircle(backgroundCircleColor)
            drawBackgroundIndicator(backgroundIndicatorColor, indicatorStrokeWidth)
            drawProgressIndicator(progress, indicatorColor, indicatorStrokeWidth)
        }
        Text(
            text = "${(progress * 100).toInt()}%",
            color = textColor,
            fontSize = fontSize,
            fontWeight = FontWeight.Bold
        )
    }
}
private fun DrawScope.drawBackgroundCircle(color: Color) {
    drawCircle(
        color = color,
        radius = size.minDimension / 2
    )
}
private fun DrawScope.drawBackgroundIndicator(
    color: Color,
    strokeWidth: Dp
) {
    drawArc(
        color = color,
        startAngle = -90f,
        sweepAngle = 360f,
        useCenter = false,
        style = Stroke(
            width = strokeWidth.toPx(),
            cap = StrokeCap.Round
        ),
        size = Size(size.width, size.height)
    )
}
private fun DrawScope.drawProgressIndicator(
    progress: Float,
    color: Color,
    strokeWidth: Dp
) {
    drawArc(
        color = color,
        startAngle = -90f,
        sweepAngle = 360f * progress,
        useCenter = false,
        style = Stroke(
            width = strokeWidth.toPx(),
            cap = StrokeCap.Round
        ),
        size = Size(size.width, size.height)
    )
}

如圖:

到此這篇關(guān)于Android Compose 自定義滑動進度條的文章就介紹到這了,更多相關(guān)Android Compose滑動進度條內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論