当前位置:   article > 正文

Kotlin Compose 计算器程序_kotlin计算器

kotlin计算器

效果

 

  1. val MediumGray = Color(0xFF2e2e2e)
  2. val LightGray = Color(0xFF818181)
  3. val Orange = Color(0xFFff9800)

新增了三个颜色。

开始开始教程开始

新建最基础的 button

  1. package com.example.caclulator
  2. import androidx.compose.foundation.clickable
  3. import androidx.compose.foundation.layout.Box
  4. import androidx.compose.foundation.shape.CircleShape
  5. import androidx.compose.material.Text
  6. import androidx.compose.runtime.Composable
  7. import androidx.compose.ui.Alignment
  8. import androidx.compose.ui.Modifier
  9. import androidx.compose.ui.draw.clip
  10. import androidx.compose.ui.graphics.Color
  11. import androidx.compose.ui.unit.sp
  12. @Composable
  13. fun CalculatorButton(
  14. symbol: String, modifier: Modifier, onClick: () -> Unit
  15. ) {
  16. Box(contentAlignment = Alignment.Center,
  17. modifier = Modifier
  18. .clip(CircleShape)
  19. .clickable { onClick() }
  20. .then(modifier)) {
  21. Text(text = symbol, fontSize = 36.sp, color = Color.White)
  22. }
  23. }

 抽取共同的要素。然后。所有按钮都用到了这个。

主要布局编写

  1. package com.example.caclulator
  2. import androidx.compose.foundation.background
  3. import androidx.compose.foundation.layout.Arrangement
  4. import androidx.compose.foundation.layout.Box
  5. import androidx.compose.foundation.layout.Column
  6. import androidx.compose.foundation.layout.Row
  7. import androidx.compose.foundation.layout.aspectRatio
  8. import androidx.compose.foundation.layout.fillMaxWidth
  9. import androidx.compose.foundation.layout.padding
  10. import androidx.compose.material.Text
  11. import androidx.compose.runtime.Composable
  12. import androidx.compose.ui.Alignment
  13. import androidx.compose.ui.Modifier
  14. import androidx.compose.ui.graphics.Color
  15. import androidx.compose.ui.text.font.FontWeight
  16. import androidx.compose.ui.text.style.TextAlign
  17. import androidx.compose.ui.unit.Dp
  18. import androidx.compose.ui.unit.dp
  19. import androidx.compose.ui.unit.sp
  20. import com.example.caclulator.ui.theme.Orange
  21. @Composable
  22. fun Calculator(
  23. state: CalculatorState,
  24. buttonSpace: Dp = 8.dp,
  25. modifier: Modifier = Modifier,
  26. onAction: (CalculatorAction) -> Unit
  27. ) {
  28. Box(modifier = modifier) {
  29. Column(
  30. Modifier
  31. .fillMaxWidth()
  32. .align(Alignment.BottomCenter),
  33. verticalArrangement = Arrangement.spacedBy(buttonSpace)
  34. ) {
  35. Text(
  36. text = state.number1 + (state.operation?.symbol ?: "") + state.number2,
  37. textAlign = TextAlign.End,
  38. modifier = Modifier
  39. .fillMaxWidth()
  40. .padding(32.dp),
  41. fontWeight = FontWeight.Light,
  42. fontSize = 80.sp,
  43. color = Color.White,
  44. maxLines = 2
  45. )
  46. Row(
  47. modifier = Modifier.fillMaxWidth(),
  48. horizontalArrangement = Arrangement.spacedBy(buttonSpace)
  49. ) {
  50. CalculatorButton(symbol = "AC",
  51. modifier = Modifier
  52. .background(Color.LightGray)
  53. .aspectRatio(2f)
  54. .weight(2f),
  55. onClick = {
  56. onAction(CalculatorAction.Clear)
  57. })
  58. CalculatorButton(symbol = "Del",
  59. modifier = Modifier
  60. .background(Orange)
  61. .aspectRatio(1f)
  62. .weight(1f),
  63. onClick = {
  64. onAction(CalculatorAction.Delete)
  65. })
  66. CalculatorButton(symbol = "/",
  67. modifier = Modifier
  68. .background(Orange)
  69. .aspectRatio(1f)
  70. .weight(1f),
  71. onClick = {
  72. onAction(CalculatorAction.Operation(CalculatorOperation.Divide))
  73. })
  74. }
  75. // 7 8 9
  76. Row(
  77. modifier = Modifier.fillMaxWidth(),
  78. horizontalArrangement = Arrangement.spacedBy(buttonSpace)
  79. ) {
  80. CalculatorButton(symbol = "7",
  81. modifier = Modifier
  82. .background(Color.LightGray)
  83. .aspectRatio(1f)
  84. .weight(1f),
  85. onClick = {
  86. onAction(CalculatorAction.Number(7))
  87. })
  88. CalculatorButton(symbol = "8",
  89. modifier = Modifier
  90. .background(Color.LightGray)
  91. .aspectRatio(1f)
  92. .weight(1f),
  93. onClick = {
  94. onAction(CalculatorAction.Number(8))
  95. })
  96. CalculatorButton(symbol = "9",
  97. modifier = Modifier
  98. .background(Color.LightGray)
  99. .aspectRatio(1f)
  100. .weight(1f),
  101. onClick = {
  102. onAction(CalculatorAction.Number(9))
  103. })
  104. CalculatorButton(symbol = "-",
  105. modifier = Modifier
  106. .background(Orange)
  107. .aspectRatio(1f)
  108. .weight(1f),
  109. onClick = {
  110. onAction(CalculatorAction.Operation(CalculatorOperation.Subtract))
  111. })
  112. }
  113. // 4 5 6
  114. Row(
  115. modifier = Modifier.fillMaxWidth(),
  116. horizontalArrangement = Arrangement.spacedBy(buttonSpace)
  117. ) {
  118. CalculatorButton(symbol = "4",
  119. modifier = Modifier
  120. .background(Color.LightGray)
  121. .aspectRatio(1f)
  122. .weight(1f),
  123. onClick = {
  124. onAction(CalculatorAction.Number(4))
  125. })
  126. CalculatorButton(symbol = "5",
  127. modifier = Modifier
  128. .background(Color.LightGray)
  129. .aspectRatio(1f)
  130. .weight(1f),
  131. onClick = {
  132. onAction(CalculatorAction.Number(5))
  133. })
  134. CalculatorButton(symbol = "6",
  135. modifier = Modifier
  136. .background(Color.LightGray)
  137. .aspectRatio(1f)
  138. .weight(1f),
  139. onClick = {
  140. onAction(CalculatorAction.Number(6))
  141. })
  142. CalculatorButton(symbol = "+",
  143. modifier = Modifier
  144. .background(Orange)
  145. .aspectRatio(1f)
  146. .weight(1f),
  147. onClick = {
  148. onAction(CalculatorAction.Operation(CalculatorOperation.Add))
  149. })
  150. }
  151. // 12 3
  152. Row(
  153. modifier = Modifier.fillMaxWidth(),
  154. horizontalArrangement = Arrangement.spacedBy(buttonSpace)
  155. ) {
  156. CalculatorButton(symbol = "1",
  157. modifier = Modifier
  158. .background(Color.LightGray)
  159. .aspectRatio(1f)
  160. .weight(1f),
  161. onClick = {
  162. onAction(CalculatorAction.Number(1))
  163. })
  164. CalculatorButton(symbol = "2",
  165. modifier = Modifier
  166. .background(Color.LightGray)
  167. .aspectRatio(1f)
  168. .weight(1f),
  169. onClick = {
  170. onAction(CalculatorAction.Number(2))
  171. })
  172. CalculatorButton(symbol = "3",
  173. modifier = Modifier
  174. .background(Color.LightGray)
  175. .aspectRatio(1f)
  176. .weight(1f),
  177. onClick = {
  178. onAction(CalculatorAction.Number(3))
  179. })
  180. CalculatorButton(symbol = "*",
  181. modifier = Modifier
  182. .background(Orange)
  183. .aspectRatio(1f)
  184. .weight(1f),
  185. onClick = {
  186. onAction(CalculatorAction.Operation(CalculatorOperation.Multiply))
  187. })
  188. }
  189. Row(
  190. modifier = Modifier.fillMaxWidth(),
  191. horizontalArrangement = Arrangement.spacedBy(buttonSpace)
  192. ) {
  193. CalculatorButton(symbol = "0",
  194. modifier = Modifier
  195. .background(Color.LightGray)
  196. .aspectRatio(2f)
  197. .weight(2f),
  198. onClick = {
  199. onAction(CalculatorAction.Number(0))
  200. })
  201. CalculatorButton(symbol = ".",
  202. modifier = Modifier
  203. .background(Color.LightGray)
  204. .aspectRatio(1f)
  205. .weight(1f),
  206. onClick = {
  207. onAction(CalculatorAction.Decimal)
  208. })
  209. CalculatorButton(symbol = "=",
  210. modifier = Modifier
  211. .background(Orange)
  212. .aspectRatio(1f)
  213. .weight(1f),
  214. onClick = {
  215. onAction(CalculatorAction.Calculate)
  216. })
  217. }
  218. }
  219. }
  220. }

这里用到了status

这个是啥

data class

  1. package com.example.caclulator
  2. data class CalculatorState(
  3. val number1: String = "", val number2: String = "", val operation: CalculatorOperation? = null
  4. )

根据他们三个的变化。来进行对数据的刷新

还用到了密封类:

CalculatorAction

这个是啥?枚举的升级版本!

一下子就列举出来所有情况。枚举只能列举相同的状态。而他不一样可以扩展。

  1. package com.example.caclulator
  2. sealed class CalculatorAction{
  3. data class Number(val number:Int):CalculatorAction()
  4. object Clear:CalculatorAction()
  5. object Delete:CalculatorAction()
  6. object Decimal:CalculatorAction()
  7. object Calculate:CalculatorAction()
  8. data class Operation(val operation: CalculatorOperation):CalculatorAction()
  9. }

扩展的另外一个密封类

  1. package com.example.caclulator
  2. sealed class CalculatorOperation(val symbol: String) {
  3. object Add : CalculatorOperation("+")
  4. object Subtract : CalculatorOperation("-")
  5. object Multiply : CalculatorOperation("*")
  6. object Divide : CalculatorOperation("/")
  7. }

然后计算逻辑在viewModel当中

  1. package com.example.caclulator
  2. import androidx.compose.runtime.getValue
  3. import androidx.compose.runtime.mutableStateOf
  4. import androidx.compose.runtime.setValue
  5. import androidx.lifecycle.ViewModel
  6. class CalculatorViewModel : ViewModel() {
  7. var state by mutableStateOf(CalculatorState())
  8. fun onAction(action: CalculatorAction) {
  9. when (action) {
  10. is CalculatorAction.Number -> enterNumber(action.number)
  11. is CalculatorAction.Decimal -> enterDecimal()
  12. is CalculatorAction.Clear -> state = CalculatorState()
  13. is CalculatorAction.Operation -> enterOperation(action.operation)
  14. is CalculatorAction.Calculate -> performCalculation()
  15. is CalculatorAction.Delete -> performDelete()
  16. }
  17. }
  18. private fun performDelete() {
  19. when {
  20. state.number2.isNotBlank() -> state = state.copy(number2 = state.number2.dropLast(1))
  21. state.operation != null -> state = state.copy(operation = null)
  22. state.number1.isNotBlank() -> state = state.copy(number1 = state.number1.dropLast(1))
  23. }
  24. }
  25. private fun performCalculation() {
  26. val number1 = state.number1.toDoubleOrNull()
  27. val number2 = state.number2.toDoubleOrNull()
  28. if (number1 != null && number2 != null) {
  29. val result = when (state.operation) {
  30. is CalculatorOperation.Add -> number1 + number2
  31. is CalculatorOperation.Subtract -> number1 - number2
  32. is CalculatorOperation.Multiply -> number1 * number2
  33. is CalculatorOperation.Divide -> number1 / number2
  34. null -> return
  35. }
  36. state = state.copy(number1 = result.toString().take(15), number2 = "", operation = null)
  37. }
  38. }
  39. private fun enterOperation(operation: CalculatorOperation) {
  40. if (state.number1.isNotBlank()) {
  41. state = state.copy(operation = operation)
  42. }
  43. }
  44. private fun enterDecimal() {
  45. if (state.operation == null && !state.number1.contains(".") && state.number1.isNotBlank()) {
  46. state = state.copy(state.number1 + ".")
  47. return
  48. }
  49. if (!state.number2.contains(".") && state.number2.isNotBlank()) {
  50. state = state.copy(state.number2 + ".")
  51. }
  52. }
  53. private fun enterNumber(number: Int) {
  54. if (state.operation == null) {
  55. if (state.number1.length >= MAX_NUM_LENGTH) {
  56. return
  57. }
  58. state = state.copy(number1 = state.number1 + number)
  59. return
  60. }
  61. if (state.number2.length >= MAX_NUM_LENGTH) {
  62. return
  63. }
  64. state = state.copy(number2 = state.number2 + number)
  65. }
  66. companion object {
  67. private const val MAX_NUM_LENGTH = 8
  68. }
  69. }

MainActivity

  1. package com.example.caclulator
  2. import android.os.Bundle
  3. import androidx.activity.ComponentActivity
  4. import androidx.activity.compose.setContent
  5. import androidx.activity.viewModels
  6. import androidx.compose.foundation.background
  7. import androidx.compose.foundation.layout.fillMaxSize
  8. import androidx.compose.foundation.layout.fillMaxWidth
  9. import androidx.compose.foundation.layout.padding
  10. import androidx.compose.material.MaterialTheme
  11. import androidx.compose.material.Surface
  12. import androidx.compose.material.Text
  13. import androidx.compose.runtime.Composable
  14. import androidx.compose.ui.Modifier
  15. import androidx.compose.ui.tooling.preview.Preview
  16. import androidx.compose.ui.unit.dp
  17. import androidx.lifecycle.viewmodel.compose.viewModel
  18. import com.example.caclulator.ui.theme.Android_compose_caclulatorTheme
  19. import com.example.caclulator.ui.theme.MediumGray
  20. class MainActivity : ComponentActivity() {
  21. override fun onCreate(savedInstanceState: Bundle?) {
  22. super.onCreate(savedInstanceState)
  23. setContent {
  24. Android_compose_caclulatorTheme {
  25. val viewModel = viewModel<CalculatorViewModel>()
  26. val state = viewModel.state
  27. val buttonSpacing = 8.dp
  28. Calculator(
  29. state = state,
  30. buttonSpace = buttonSpacing,
  31. onAction = viewModel::onAction,
  32. modifier = Modifier
  33. .fillMaxSize()
  34. .background(MediumGray)
  35. .padding(16.dp)
  36. )
  37. }
  38. }
  39. }
  40. }

这就完成了。。

项目地址:https://gitee.com/liuande/android_compose_learn_calculator

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/999923
推荐阅读
相关标签
  

闽ICP备14008679号