0
  • 最佳答案

    import androidx.compose.ui.unit.dp

    import androidx.activity.compose.setContent

    import android.os.Bundle

    import androidx.activity.ComponentActivity

    import androidx.compose.material.Surface

    import androidx.compose.material.Text

    import androidx.compose.runtime.Composable

    import androidx.compose.ui.Modifier

    import androidx.compose.foundation.Canvas

    import androidx.compose.foundation.layout.Box

    import androidx.compose.foundation.layout.fillMaxSize

    import androidx.compose.foundation.layout.size

    import androidx.compose.material.*

    import androidx.compose.runtime.*

    import androidx.compose.ui.Alignment

    import androidx.compose.ui.geometry.Offset

    import androidx.compose.ui.geometry.Size

    import androidx.compose.ui.graphics.Color

    import androidx.compose.ui.graphics.PointMode

    import androidx.compose.ui.graphics.StrokeCap

    import androidx.compose.ui.graphics.drawscope.Stroke

    import androidx.compose.ui.layout.onSizeChanged

    import androidx.compose.ui.text.font.FontWeight

    import androidx.compose.ui.unit.Dp

    import androidx.compose.ui.unit.IntSize

    import androidx.compose.ui.unit.sp

    import kotlinx.coroutines.delay

    import kotlin.math.PI

    import kotlin.math.cos

    import kotlin.math.sin

    class MainActivity : ComponentActivity() {

     override fun onCreate(savedInstanceState: Bundle?) {

     super.onCreate(savedInstanceState)

     setContent {

      Surface(

      color = Color(0xFF101010),

      modifier = Modifier.fillMaxSize()

      ) {

      Box(

       contentAlignment = Alignment.Center

      ) {

       // call the function Timer

       // and pass the values

       // it is defined below.

       Timer(

       totalTime = 100L * 1000L,

       handleColor = Color.Green,

       inactiveBarColor = Color.DarkGray,

       activeBarColor = Color(0xFF37B900),

       modifier = Modifier.size(200.dp)

       )

      }

      }

     }

     }

    }

    // create a composable to

    // Draw arc and handle

    @Composable

    fun Timer(

     // total time of the timer

     totalTime: Long,

     // circular handle color

     handleColor: Color,

     // color of inactive bar / progress bar

     inactiveBarColor: Color,

     // color of active bar

     activeBarColor: Color,

     modifier: Modifier = Modifier,

     // set initial value to 1

     initialValue: Float = 1f,

     strokeWidth: Dp = 5.dp

    ) {

     // create variable for

     // size of the composable

     var size by remember {

     mutableStateOf(IntSize.Zero)

     }

     // create variable for value

     var value by remember {

     mutableStateOf(initialValue)

     }

     // create variable for current time

     var currentTime by remember {

     mutableStateOf(totalTime)

     }

     // create variable for isTimerRunning

     var isTimerRunning by remember {

     mutableStateOf(false)

     }

     LaunchedEffect(key1 = currentTime, key2 = isTimerRunning) {

     if(currentTime > 0 && isTimerRunning) {

      delay(100L)

      currentTime -= 100L

      value = currentTime / totalTime.toFloat()

     }

     }

     Box(

     contentAlignment = Alignment.Center,

     modifier = modifier

      .onSizeChanged {

      size = it

      }

     ) {

     // draw the timer

     Canvas(modifier = modifier) {

      // draw the inactive arc with following parameters

      drawArc(

      color = inactiveBarColor, // assign the color

      startAngle = -215f, // assign the start angle

      sweepAngle = 250f, // arc angles

      useCenter = false, // prevents our arc to connect at te ends

      size = Size(size.width.toFloat(), size.height.toFloat()),

      // to make ends of arc round

      style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round)

      )

      // draw the active arc with following parameters

      drawArc(

      color = activeBarColor, // assign the color

      startAngle = -215f, // assign the start angle

      sweepAngle = 250f * value, // reduce the sweep angle

          // with the current value

      useCenter = false, // prevents our arc to connect at te ends

      size = Size(size.width.toFloat(), size.height.toFloat()),

      // to make ends of arc round

      style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round)

      )

      // calculate the value from arc pointer position

      val center = Offset(size.width / 2f, size.height / 2f)

      val beta = (250f * value + 145f) * (PI / 180f).toFloat()

      val r = size.width / 2f

      val a = cos(beta) * r

      val b = sin(beta) * r

      // draw the circular pointer/ cap

      drawPoints(

      listOf(Offset(center.x + a, center.y + b)),

      pointMode = PointMode.Points,

      color = handleColor,

      strokeWidth = (strokeWidth * 3f).toPx(),

      cap = StrokeCap.Round // make the pointer round

      )

     }

     // add value of the timer

     Text(

      text = (currentTime / 1000L).toString(),

      fontSize = 44.sp,

      fontWeight = FontWeight.Bold,

      color = Color.White

     )

     // create button to start or stop the timer

     Button(

      onClick = {

      if(currentTime <= 0L) {

       currentTime = totalTime

       isTimerRunning = true

      } else {

       isTimerRunning = !isTimerRunning

      }

      },

      modifier = Modifier.align(Alignment.BottomCenter),

      // change button color

      colors = ButtonDefaults.buttonColors(

      backgroundColor = if (!isTimerRunning || currentTime <= 0L) {

       Color.Green

      } else {

       Color.Red

      }

      )

     ) {

      Text(

      // change the text of button based on values

      text = if (isTimerRunning && currentTime >= 0L) "Stop"

      else if (!isTimerRunning && currentTime >= 0L) "Start"

      else "Restart"

      )

     }

     }

    }


    1302969105866940416  评论     打赏       波鲁萨利诺.黄猿
    • Cstri  回复 @波鲁萨利诺.黄猿
      可能是我问题描述的不太好,把你们带沟里去了(不好意思),我只是想实现一个需求:在一段时间后执行一次composable函数,后来根据自己的想法问了大佬,给了我多种方案...在viewmodel里很简单的就完成了这个
      Cstri 2022-08-31 15:56   回复 1342082010843308032
  • 最近怎么热恋compose了,这个目前情况,做简单的还好,复杂起来了可能卡壳,产品的需求可不会跟着你掌握的来。

    1139423796017500160  评论     打赏       断点
    • 断点  回复 @断点
      来,推荐你学习一个开源的,倒计时https://juejin.cn/post/6936918974399512612
      断点 2022-08-31 11:03   回复 1139423796017500160
    • Cstri  回复 @断点
      哈哈哈,因为我正在用compose写项目,这个项目也算是比较简单的,view我估计忘得七七八八了,好的好的,我先看看
      Cstri 2022-08-31 11:16   回复 1342082010843308032
  • 那你把这个task写进一个coposeable的函数不就行了
    1302969105866940416  评论     打赏       波鲁萨利诺.黄猿
    • Cstri  回复 @波鲁萨利诺.黄猿
      外面套一个composable也是不行的
      Cstri 2022-08-31 14:24   回复 1342082010843308032
    • 波鲁萨利诺.黄猿  回复 @Cstri
      我刚刚写了一个,你看看是不是想要的
      波鲁萨利诺.黄猿 2022-08-31 15:04   回复 1302969105866940416
  • compose 要运行在一个有@Composable 注解的函数中,你这个直接Text 肯定不行,

    你把这个Text 这部分代码封装成一个用Composabe注释的函数中,然后再使用试试

    1302969105866940416  评论     打赏       波鲁萨利诺.黄猿
相关问题
幻影~ · 提问
2024-04-13 20:13 7 2
幻影~ · 找工作
2024-04-07 10:44 12 2
幻影~ · 问题
2024-03-31 17:20 7 2
TONYGFX · AOSP
2024-03-28 17:11 4 2