赞
踩
效果
- val MediumGray = Color(0xFF2e2e2e)
- val LightGray = Color(0xFF818181)
- val Orange = Color(0xFFff9800)
新增了三个颜色。
开始开始教程开始
新建最基础的 button
- package com.example.caclulator
-
- import androidx.compose.foundation.clickable
- import androidx.compose.foundation.layout.Box
- import androidx.compose.foundation.shape.CircleShape
- import androidx.compose.material.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.draw.clip
- import androidx.compose.ui.graphics.Color
- import androidx.compose.ui.unit.sp
-
- @Composable
- fun CalculatorButton(
- symbol: String, modifier: Modifier, onClick: () -> Unit
- ) {
- Box(contentAlignment = Alignment.Center,
- modifier = Modifier
- .clip(CircleShape)
- .clickable { onClick() }
- .then(modifier)) {
- Text(text = symbol, fontSize = 36.sp, color = Color.White)
- }
- }
抽取共同的要素。然后。所有按钮都用到了这个。
主要布局编写
- package com.example.caclulator
-
- import androidx.compose.foundation.background
- import androidx.compose.foundation.layout.Arrangement
- import androidx.compose.foundation.layout.Box
- import androidx.compose.foundation.layout.Column
- import androidx.compose.foundation.layout.Row
- import androidx.compose.foundation.layout.aspectRatio
- import androidx.compose.foundation.layout.fillMaxWidth
- import androidx.compose.foundation.layout.padding
- import androidx.compose.material.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.ui.Alignment
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.graphics.Color
- import androidx.compose.ui.text.font.FontWeight
- import androidx.compose.ui.text.style.TextAlign
- import androidx.compose.ui.unit.Dp
- import androidx.compose.ui.unit.dp
- import androidx.compose.ui.unit.sp
- import com.example.caclulator.ui.theme.Orange
-
- @Composable
- fun Calculator(
- state: CalculatorState,
- buttonSpace: Dp = 8.dp,
- modifier: Modifier = Modifier,
- onAction: (CalculatorAction) -> Unit
- ) {
- Box(modifier = modifier) {
- Column(
- Modifier
- .fillMaxWidth()
- .align(Alignment.BottomCenter),
- verticalArrangement = Arrangement.spacedBy(buttonSpace)
- ) {
- Text(
- text = state.number1 + (state.operation?.symbol ?: "") + state.number2,
- textAlign = TextAlign.End,
- modifier = Modifier
- .fillMaxWidth()
- .padding(32.dp),
- fontWeight = FontWeight.Light,
- fontSize = 80.sp,
- color = Color.White,
- maxLines = 2
- )
-
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.spacedBy(buttonSpace)
- ) {
- CalculatorButton(symbol = "AC",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(2f)
- .weight(2f),
- onClick = {
- onAction(CalculatorAction.Clear)
- })
-
-
- CalculatorButton(symbol = "Del",
- modifier = Modifier
- .background(Orange)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Delete)
- })
-
- CalculatorButton(symbol = "/",
- modifier = Modifier
- .background(Orange)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Operation(CalculatorOperation.Divide))
- })
-
- }
-
- // 7 8 9
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.spacedBy(buttonSpace)
- ) {
- CalculatorButton(symbol = "7",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(7))
- })
-
- CalculatorButton(symbol = "8",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(8))
- })
-
- CalculatorButton(symbol = "9",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(9))
- })
- CalculatorButton(symbol = "-",
- modifier = Modifier
- .background(Orange)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Operation(CalculatorOperation.Subtract))
- })
-
-
- }
- // 4 5 6
-
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.spacedBy(buttonSpace)
- ) {
- CalculatorButton(symbol = "4",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(4))
- })
-
- CalculatorButton(symbol = "5",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(5))
- })
-
- CalculatorButton(symbol = "6",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(6))
- })
- CalculatorButton(symbol = "+",
- modifier = Modifier
- .background(Orange)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Operation(CalculatorOperation.Add))
- })
-
-
- }
-
- // 12 3
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.spacedBy(buttonSpace)
- ) {
- CalculatorButton(symbol = "1",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(1))
- })
-
- CalculatorButton(symbol = "2",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(2))
- })
-
- CalculatorButton(symbol = "3",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Number(3))
- })
- CalculatorButton(symbol = "*",
- modifier = Modifier
- .background(Orange)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Operation(CalculatorOperation.Multiply))
- })
-
-
- }
-
-
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.spacedBy(buttonSpace)
- ) {
- CalculatorButton(symbol = "0",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(2f)
- .weight(2f),
- onClick = {
- onAction(CalculatorAction.Number(0))
- })
-
- CalculatorButton(symbol = ".",
- modifier = Modifier
- .background(Color.LightGray)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Decimal)
- })
-
- CalculatorButton(symbol = "=",
- modifier = Modifier
- .background(Orange)
- .aspectRatio(1f)
- .weight(1f),
- onClick = {
- onAction(CalculatorAction.Calculate)
- })
-
-
- }
- }
-
-
- }
-
- }
这里用到了status
这个是啥
data class
- package com.example.caclulator
-
- data class CalculatorState(
- val number1: String = "", val number2: String = "", val operation: CalculatorOperation? = null
- )
根据他们三个的变化。来进行对数据的刷新
还用到了密封类:
CalculatorAction
这个是啥?枚举的升级版本!
一下子就列举出来所有情况。枚举只能列举相同的状态。而他不一样可以扩展。
- package com.example.caclulator
-
- sealed class CalculatorAction{
- data class Number(val number:Int):CalculatorAction()
-
- object Clear:CalculatorAction()
- object Delete:CalculatorAction()
- object Decimal:CalculatorAction()
- object Calculate:CalculatorAction()
-
- data class Operation(val operation: CalculatorOperation):CalculatorAction()
- }
扩展的另外一个密封类
- package com.example.caclulator
-
- sealed class CalculatorOperation(val symbol: String) {
- object Add : CalculatorOperation("+")
- object Subtract : CalculatorOperation("-")
- object Multiply : CalculatorOperation("*")
- object Divide : CalculatorOperation("/")
- }
然后计算逻辑在viewModel当中
- package com.example.caclulator
-
- import androidx.compose.runtime.getValue
- import androidx.compose.runtime.mutableStateOf
- import androidx.compose.runtime.setValue
- import androidx.lifecycle.ViewModel
-
- class CalculatorViewModel : ViewModel() {
- var state by mutableStateOf(CalculatorState())
-
- fun onAction(action: CalculatorAction) {
- when (action) {
- is CalculatorAction.Number -> enterNumber(action.number)
- is CalculatorAction.Decimal -> enterDecimal()
- is CalculatorAction.Clear -> state = CalculatorState()
- is CalculatorAction.Operation -> enterOperation(action.operation)
- is CalculatorAction.Calculate -> performCalculation()
- is CalculatorAction.Delete -> performDelete()
- }
- }
-
- private fun performDelete() {
- when {
- state.number2.isNotBlank() -> state = state.copy(number2 = state.number2.dropLast(1))
- state.operation != null -> state = state.copy(operation = null)
- state.number1.isNotBlank() -> state = state.copy(number1 = state.number1.dropLast(1))
-
-
- }
- }
-
- private fun performCalculation() {
- val number1 = state.number1.toDoubleOrNull()
- val number2 = state.number2.toDoubleOrNull()
- if (number1 != null && number2 != null) {
- val result = when (state.operation) {
- is CalculatorOperation.Add -> number1 + number2
- is CalculatorOperation.Subtract -> number1 - number2
- is CalculatorOperation.Multiply -> number1 * number2
- is CalculatorOperation.Divide -> number1 / number2
- null -> return
- }
-
- state = state.copy(number1 = result.toString().take(15), number2 = "", operation = null)
- }
- }
-
- private fun enterOperation(operation: CalculatorOperation) {
- if (state.number1.isNotBlank()) {
- state = state.copy(operation = operation)
- }
- }
-
- private fun enterDecimal() {
- if (state.operation == null && !state.number1.contains(".") && state.number1.isNotBlank()) {
- state = state.copy(state.number1 + ".")
- return
- }
-
- if (!state.number2.contains(".") && state.number2.isNotBlank()) {
- state = state.copy(state.number2 + ".")
- }
- }
-
- private fun enterNumber(number: Int) {
- if (state.operation == null) {
- if (state.number1.length >= MAX_NUM_LENGTH) {
-
- return
- }
- state = state.copy(number1 = state.number1 + number)
-
- return
- }
-
- if (state.number2.length >= MAX_NUM_LENGTH) {
- return
- }
- state = state.copy(number2 = state.number2 + number)
-
- }
-
- companion object {
- private const val MAX_NUM_LENGTH = 8
-
- }
-
- }
MainActivity
- package com.example.caclulator
-
- import android.os.Bundle
- import androidx.activity.ComponentActivity
- import androidx.activity.compose.setContent
- import androidx.activity.viewModels
- import androidx.compose.foundation.background
- import androidx.compose.foundation.layout.fillMaxSize
- import androidx.compose.foundation.layout.fillMaxWidth
- import androidx.compose.foundation.layout.padding
- import androidx.compose.material.MaterialTheme
- import androidx.compose.material.Surface
- import androidx.compose.material.Text
- import androidx.compose.runtime.Composable
- import androidx.compose.ui.Modifier
- import androidx.compose.ui.tooling.preview.Preview
- import androidx.compose.ui.unit.dp
- import androidx.lifecycle.viewmodel.compose.viewModel
- import com.example.caclulator.ui.theme.Android_compose_caclulatorTheme
- import com.example.caclulator.ui.theme.MediumGray
- class MainActivity : ComponentActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContent {
- Android_compose_caclulatorTheme {
- val viewModel = viewModel<CalculatorViewModel>()
- val state = viewModel.state
- val buttonSpacing = 8.dp
- Calculator(
- state = state,
- buttonSpace = buttonSpacing,
- onAction = viewModel::onAction,
- modifier = Modifier
- .fillMaxSize()
- .background(MediumGray)
- .padding(16.dp)
- )
- }
- }
- }
- }
这就完成了。。
项目地址:https://gitee.com/liuande/android_compose_learn_calculator
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。