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

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)文章

  • android中把文件保存到sdcard代碼實例

    android中把文件保存到sdcard代碼實例

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

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

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

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

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

    Android學習之Flux架構(gòu)入門

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

    android TabLayout的指示器寬度問題

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

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

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

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

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

    Android 啟動模式FLAG_ACTIVITY_CLEAR_TOP案例詳解

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

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

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

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

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

最新評論

西贡区| 准格尔旗| 北安市| 如东县| 崇仁县| 云阳县| 齐齐哈尔市| 西丰县| 漳浦县| 合作市| 家居| 贞丰县| 腾冲县| 林州市| 疏附县| 龙川县| 大名县| 荆门市| 叶城县| 晋城| 阿合奇县| 保康县| 清流县| 贡山| 娄烦县| 南丹县| 武邑县| 浦县| 疏附县| 和政县| 夏河县| 嘉义县| 襄汾县| 盘锦市| 门头沟区| 呼伦贝尔市| 伊川县| 苍山县| 新田县| 海安县| 通城县|