最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android?Compose?自定義滑動(dòng)進(jìn)度條的實(shí)現(xiàn)代碼

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

Android Compose 自定義滑動(dòng)進(jìn)度條

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

@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())
            )
            // 進(jìn)度軌道
            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")
        }
    )

補(bǔ)充:Compose筆記(十五)--進(jìn)度條

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

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

栗子:

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)
    ) {
        // 不確定線性進(jìn)度條
        IndeterminateLinearProgressBar()
        // 確定線性進(jìn)度條
        DeterminateLinearProgressBar()
        // 不確定圓形進(jìn)度條
        IndeterminateCircularProgressBar()
        // 確定圓形進(jìn)度條
        DeterminateCircularProgressBar()
        // 自定義進(jìn)度條樣式
        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 = "進(jìn)度測試")
        }
    }
}
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 自定義滑動(dòng)進(jìn)度條的文章就介紹到這了,更多相關(guān)Android Compose滑動(dòng)進(jìn)度條內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • android中把文件保存到sdcard代碼實(shí)例

    android中把文件保存到sdcard代碼實(shí)例

    這篇文章主要介紹了android中把文件保存到sdcard代碼實(shí)例,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-05-05
  • Android實(shí)現(xiàn)動(dòng)態(tài)添加數(shù)據(jù)與堆疊折線圖詳解流程

    Android實(shí)現(xiàn)動(dòng)態(tài)添加數(shù)據(jù)與堆疊折線圖詳解流程

    堆疊折線圖是折線圖的一種,堆積折線圖用于顯示每一數(shù)值所占大小隨時(shí)間或有序類別而變化的趨勢,可能顯示數(shù)據(jù)點(diǎn)以表示單個(gè)數(shù)據(jù)值,也可能不顯示這些數(shù)據(jù)點(diǎn)。堆疊折線圖中,類別數(shù)據(jù)沿水平軸均勻分布,所有值數(shù)據(jù)沿垂直軸均勻分布
    2021-10-10
  • Android開發(fā)實(shí)戰(zhàn)鬧鐘項(xiàng)目

    Android開發(fā)實(shí)戰(zhàn)鬧鐘項(xiàng)目

    這篇文章主要介紹了Android開發(fā)實(shí)戰(zhàn)鬧鐘項(xiàng)目,根據(jù)我們手機(jī)鬧鐘設(shè)計(jì)的一個(gè)鬧鐘APP,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Android學(xué)習(xí)之Flux架構(gòu)入門

    Android學(xué)習(xí)之Flux架構(gòu)入門

    Flux是Facebook在14年提出的一種Web前端架構(gòu),主要用來處理復(fù)雜的UI邏輯的一致性問題(當(dāng)時(shí)是為了解決Web頁面的消息通知問題)。接下來從其特點(diǎn)和使用上來介紹Flux架構(gòu)。本文主要目的是讓你對(duì)Flux的一個(gè)架構(gòu)大體面貌有個(gè)了解。
    2016-08-08
  • android TabLayout的指示器寬度問題

    android TabLayout的指示器寬度問題

    這篇文章主要介紹了android TabLayout的指示器寬度問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • Android View 完美實(shí)現(xiàn)EditText 在軟鍵盤上邊的示例

    Android View 完美實(shí)現(xiàn)EditText 在軟鍵盤上邊的示例

    本篇文章主要介紹了Android View 完美實(shí)現(xiàn)EditText 在軟鍵盤上邊的示例,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • Android開發(fā) Activity和Fragment詳解

    Android開發(fā) Activity和Fragment詳解

    本文主要介紹Android開發(fā) Activity和Fragment,這里對(duì)Activity和Fragment的知識(shí)做了詳細(xì)講解,并附簡單代碼示例,有興趣的小伙伴可以參考下
    2016-08-08
  • Android 啟動(dòng)模式FLAG_ACTIVITY_CLEAR_TOP案例詳解

    Android 啟動(dòng)模式FLAG_ACTIVITY_CLEAR_TOP案例詳解

    這篇文章主要介紹了Android 啟動(dòng)模式FLAG_ACTIVITY_CLEAR_TOP案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Android UI實(shí)現(xiàn)多行文本折疊展開效果

    Android UI實(shí)現(xiàn)多行文本折疊展開效果

    這篇文章主要為大家詳細(xì)介紹了Android UI實(shí)現(xiàn)多行文本折疊展開效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Android 仿硅谷新聞下拉刷新/上拉加載更多

    Android 仿硅谷新聞下拉刷新/上拉加載更多

    這篇文章主要介紹了Android 仿硅谷新聞下拉刷新/上拉加載更多的實(shí)現(xiàn)代碼,非常不錯(cuò)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2016-10-10

最新評(píng)論

临朐县| 邵武市| 连云港市| 邢台市| 濉溪县| 壤塘县| 呼图壁县| 保德县| 同江市| 白城市| 元朗区| 安宁市| 平舆县| 讷河市| 博客| 长顺县| 泰安市| 策勒县| 偃师市| 大兴区| 噶尔县| 龙山县| 彭水| 临沭县| 蓝田县| 郴州市| 邯郸县| 华安县| 罗江县| 汽车| 桃源县| 青海省| 井陉县| 彰武县| 岳阳县| 平安县| 嘉义县| 南和县| 永吉县| 洞头县| 广宁县|