Как сделать калькулятор в Андроид Студио

Создание собственного калькулятора — это обряд посвящения для каждого начинающего Android-разработчика. В этом руководстве вы узнаете, как сделать калькулятор в андроид студио, используя современный Kotlin и два популярных подхода к построению интерфейса: классический XML на основе LinearLayout и декларативный Jetpack Compose. Мы не только напишем работающее приложение, но и разберем архитектурные решения, которые позволят вам расширять его функциональность без боли.


Инструментарий и подготовка проекта

Для работы потребуется актуальная версия Android Studio. Создайте новый проект с пустой активностью (Empty Views Activity или Empty Compose Activity). Второй вариант предпочтительнее для Jetpack Compose, но если вы выбираете XML, достаточно шаблона с Empty Views. Обязательно выберите Kotlin в качестве основного языка и убедитесь, что минимальный SDK не ниже 24, чтобы использовать все современные API.

Для вычислений мы воспользуемся библиотекой exp4j, которая умеет разбирать математические выражения в строковом виде и соблюдает порядок операций. Это избавляет от написания собственного парсера. Добавьте зависимость в build.gradle.kts модуля app:

dependencies {
    implementation("net.objecthunter:exp4j:0.4.8")
}

Дизайн интерфейса: XML против Jetpack Compose

Прежде чем погружаться в код, стоит сравнить оба подхода, поскольку вопрос как сделать калькулятор в андроид студио часто подразумевает выбор между классической версткой и современным тулкитом. В таблице ниже приведены ключевые отличия.

Критерий XML (LinearLayout) Jetpack Compose
Язык разметки Отдельные XML-файлы в res/layout Код на Kotlin внутри @Composable функций
Сложность освоения Низкая, много готовых примеров Средняя, требует понимания реактивности
Производительность Может страдать при глубокой вложенности Оптимальна за счет перекомпоновки только изменившихся элементов
Обновление UI Ручное через findViewById или ViewBinding Автоматическое через состояние (mutableStateOf)

Вариант 1: Верстка на LinearLayout

Макет калькулятора состоит из двух частей: дисплей для ввода выражения и результата, а также панель кнопок. Корневым контейнером выступает вертикальный LinearLayout с черным фоном. Верхняя половина экрана отводится под два TextView: operation (выражение) и result (ответ). Нижняя половина — пять горизонтальных LinearLayout, каждый из которых содержит по пять кнопок с равным весом.

Кнопки стилизуются через themes.xml, чтобы избежать дублирования кода. Создайте три стиля: Numbers (белый текст на сером фоне для цифр), Operations (оранжевый текст для базовых операций) и Operations_Sci (светло-серый текст для дополнительных функций). Каждая кнопка получает уникальный id, например, b_1, b_2, b_add, b_eq.

Пример фрагмента разметки для первого ряда кнопок:

<LinearLayout
    android:orientation="horizontal"
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="0dp">
    <TextView android:text="C" android:id="@+id/b_clear" style="@style/Operations" />
    <TextView android:text="(" android:id="@+id/b_leftb" style="@style/Operations_Sci" />
    <TextView android:text=")" android:id="@+id/b_rightb" style="@style/Operations_Sci" />
    <TextView android:text="/" android:id="@+id/b_div" style="@style/Operations" />
    <TextView android:text="*" android:id="@+id/b_mul" style="@style/Operations" />
</LinearLayout>

Логика калькулятора на Kotlin с exp4j

Вся магия происходит в MainActivity.kt. После привязки элементов интерфейса через ViewBinding или findViewById, для каждой кнопки-цифры и операции устанавливается слушатель, который добавляет соответствующий символ в TextView operation. Кнопка back удаляет последний символ, а clear очищает оба поля.

Сердце вычислений — обработчик кнопки «равно». Он извлекает строку выражения, передает её в ExpressionBuilder из библиотеки exp4j, а затем вызывает evaluate(). Если выражение составлено корректно, ответ форматируется: целые числа отображаются без десятичной точки, дробные — с сохранением знаков после запятой. В случае ошибки в поле result выводится "Error". Вот основной фрагмент кода:

b_eq.setOnClickListener {
    val optext = operation.text.toString()
    if (optext.isNotEmpty()) {
        try {
            val expr = ExpressionBuilder(optext).build()
            val res = expr.evaluate()
            val longres = res.toLong()
            result.text = if (longres.toDouble() == res) longres.toString() else res.toString()
        } catch (e: Exception) {
            result.text = "Error"
        }
    }
}

Такой подход позволяет обрабатывать сложные выражения со скобками и приоритетами операций, не реализуя алгоритм сортировочной станции вручную.


Вариант 2: Реализация на Jetpack Compose

Если вы предпочитаете декларативный UI, как сделать калькулятор в андроид студио с помощью Compose — задача, решаемая еще лаконичнее. Вся верстка описывается непосредственно в Kotlin-функциях, а состояние управляется через remember и mutableStateOf. Кнопки размещаются в Column и Row с равным весом, что достигается модификатором Modifier.weight(1f).

Преимущества Compose проявляются в реактивности: при изменении строки выражения интерфейс обновляется автоматически, без вызова invalidate. Пример компонента кнопки:

@Composable
fun CalculatorButton(symbol: String, onClick: () -> Unit) {
    Button(
        onClick = onClick,
        modifier = Modifier.weight(1f).padding(2.dp)
    ) {
        Text(symbol, fontSize = 20.sp)
    }
}

Логика вычислений остается той же — вызов exp4j через ExpressionBuilder, но теперь строка выражения хранится в состоянии var expression by remember { mutableStateOf("") }, а результат — в var result by remember { mutableStateOf("") }.


Тестирование и сборка APK

Когда приложение готово, запустите его на эмуляторе или реальном устройстве. Проверьте базовые операции: сложение, вычитание, умножение, деление, а также сценарии с ошибками (деление на ноль, несбалансированные скобки). Убедитесь, что кнопка back корректно удаляет последний символ, а результат можно перенести в поле выражения для продолжения расчетов.

Для распространения приложения создайте APK через пункт меню Build → Build Bundle(s) / APK(s) → Build APK(s). Готовый файл будет находиться в папке app/build/outputs/apk/debug/.


Типичные ошибки и их решение

  • Приложение крашится при нажатии на кнопку. Проверьте, что все id в findViewById или ViewBinding совпадают с указанными в XML. Если используется Compose, убедитесь, что onClick-обработчики переданы корректно.
  • Выражение "2+2*2" дает 8 вместо 6. Это означает, что вы не используете библиотеку вроде exp4j, а пытаетесь вычислять операции линейно. Подключите ExpressionBuilder, который учитывает математический приоритет.
  • Кнопки растянуты неравномерно. При использовании LinearLayout задайте ширину каждой кнопки 0dp и вес 1. В Compose примените Modifier.weight(1f) внутри Row или Column.
  • Ошибка компиляции "cannot resolve symbol exp4j". Убедитесь, что зависимость добавлена в build.gradle.kts модуля app и выполнен Gradle Sync.

Итоги

Вы узнали, как сделать калькулятор в андроид студио двумя способами: через классический XML с LinearLayout и через современный Jetpack Compose. Оба подхода опираются на библиотеку exp4j для безопасного вычисления выражений. Этот проект закрывает базовые потребности начинающего разработчика: верстка интерфейса, обработка пользовательского ввода, подключение сторонних библиотек и сборка APK. Дальнейшие улучшения — добавление памяти, истории операций или научных функций — станут отличной практикой для закрепления навыков. Сохраните этот урок в закладки и используйте как шпаргалку при создании собственных приложений.