2

What would be the most lightweight way to observe current time from viewModel from a composable.

In my composable's view I would expect to see current time formatted as HH:mm and be always updated according to current time.

F.Mysir
  • 2,838
  • 28
  • 39
  • [`java.time.LocalTime.now()`](https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html#now--) is an option – deHaar Aug 12 '22 at 10:55
  • Should I use a flow on a viewModel and then collect it from composable? And what would be the best method in order to trigger less recompositions from a composable? Those are the things I also have in my mind... – F.Mysir Aug 12 '22 at 11:21
  • I'd prefer the `ViewModel`… – deHaar Aug 12 '22 at 12:44

1 Answers1

10

You can use LaunchedEffect as in example below. I added seconds to show that it updates, you can change delay and formatting according to your needs.

@Composable
private fun Timer() {
    var time by remember { mutableStateOf("") }
    val sdf = remember { SimpleDateFormat("HH:mm:ss", java.util.Locale.ROOT)}
    LaunchedEffect(key1 = Unit){
        while(isActive){
           time = sdf.format(Date())
            delay(1000)
        }
    }
    Column(modifier=Modifier.fillMaxSize()) {
        Text(time, fontSize = 40.sp)

    }
}

In ViewModel with MutableStateFlow

class TimerModel(private val dateFormat: SimpleDateFormat) : ViewModel() {
    private val _timer = MutableStateFlow<String>(dateFormat.format(Date()))
    val timer: StateFlow<String> = _timer

    init {
        viewModelScope.launch {
            while (isActive) {
                _timer.value = dateFormat.format(Date())
                delay(1000)
            }
        }
    }
}

Usage

val currentTime = timeViewModel.timer.collectAsState()
Text(currentTime.value)

enter image description here

Thracian
  • 43,021
  • 16
  • 133
  • 222
  • Hi this answer is nice but I would prefer a solution from viewModel because I would like to observe it in other parts of code also and make other calculations also. – F.Mysir Aug 12 '22 at 11:50
  • @F.Mysir added another sample with ViewModel – Thracian Aug 12 '22 at 12:13
  • 3
    The answer is very good except for the use of an outdated library (`java.util.Date` & `java.text.SimpleDateFormat` are not recommended anymore). Use `java.time` instead, if you can… – deHaar Aug 12 '22 at 12:43