Освой Android играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Конвертер «38 попугаев»

Пора опять написать какое-нибудь полезное приложение (напоминаю, что до этого мы написали хорошую программу Счётчик ворон). На этот раз напишем конвертер, который позволит нам узнать длину длиннокота не только в метрах, но и в попугаях. Если вы не знаете, кто такой длиннокот, то вам прямая дорога на мой блог Субкота-5. Надеюсь, что такое субкота, вы знаете?

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

Подготовка

Создаём новый проект Converter и добавляем строковые ресурсы в файл res/values/strings.xml.


<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">38 попугаев</string>
    <string name="radiobutton_meters">В метрах</string>
    <string name="radiobutton_parrots">В попугаях</string>
    <string name="button_convert_text">Конвертировать</string>
    <color name="activity_color">#3399cc</color>

</resources>

Открываем файл activity_main.xml в папке res/layout/ и настраиваем внешний вид экрана приложения. Удаляем глупую надпись Hello World!. Далее с панели инструментов перетаскиваем компоненты Plain Text, RadioGroup, RadioButton, Button.

Мы подготовили каркас приложения. Теперь сделаем небольшой тюнинг. Назначим необходимые свойства добавленным элементам. Свойства можно менять через отдельную панель Properties.

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

Далее присвоим текст переключателям RadioButton. Мы заранее уже заготовили строковые ресурсы для переключателей. Поэтому нам нужно просто назначить нужные ресурсы в свойствах Text: radiobutton_meters и radiobutton_parrots. Убедитесь, что у первого переключателя у свойства Checked установлено значение true.

У кнопки для свойства Text мы используем строковый ресурс button_convert_text, а для свойства onClick - onClick (Java-вариант).

Чтобы приложение не выглядело стандартным, присвоим свойству background у корневого элемента значение activity_color (цвет морской волны).

Изменим также идентификаторы по умолчанию на более понятные: editText, radio_button_meter, radio_button_parrot, button_converter.

Побудьте дизайнером, придумайте свои варианты. У меня получилось следующее.

Код разметки выглядит следующим образом:


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/activity_color"
    android:orientation="vertical"
    android:paddingLeft="20dp"
    android:paddingRight="20dp">

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText">

        <RadioButton
            android:id="@+id/radio_button_meter"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="@string/radiobutton_meters" />

        <RadioButton
            android:id="@+id/radio_button_parrot"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/radiobutton_parrots" />
    </RadioGroup>

    <EditText
        android:id="@+id/editText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="numberSigned|numberDecimal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="Autofill,LabelFor,SpeakableTextPresentCheck" />

    <Button
        android:id="@+id/button_converter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_convert_text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/radioGroup" />
</androidx.constraintlayout.widget.ConstraintLayout>

Шкодим

Давайте писать код. Открываем файл активности MainActivity. Нам понадобятся два метода для конвертации величин и обработчик щелчка кнопки. При пустом значении текстового поля будем выводить Toast-сообщение. Начнём с двух методов.

Методы просты. Указываем количество попугаев и делим на магическое число 7.6 - получаем метры. И наоборот, указываем число метров и получим количество попугаев. Откуда взялось число 7.6 вы узнаете позже.

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


// Kotlin
// Если этот код работает, его написал Александр Климов,
// а если нет, то не знаю, кто его писал.
// http://developer.alexanderklimov.ru/android/

package ru.alexanderklimov.converter

import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.RadioButton
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val meterRadioButton: RadioButton = findViewById(R.id.radio_button_meter)
        val inputEditText: EditText = findViewById(R.id.editText)

        val button: Button = findViewById(R.id.button_converter)
        button.setOnClickListener {
            if (inputEditText.text.isEmpty()) {
                Toast.makeText(
                    applicationContext, "Введите длину кота",
                    Toast.LENGTH_LONG).show()
            }
            else {
                val inputValue = inputEditText.text.toString().toFloat()
                if (meterRadioButton.isChecked) {
                    inputEditText.setText(convertParrotToMeter(inputValue).toString())
                } else {
                    inputEditText.setText(convertMeterToParrot(inputValue).toString())
                }
            }
        }
    }

    // Конвертируем в метры
    private fun convertParrotToMeter(parrot: Float): Float = (parrot / 7.6).toFloat()

    // Конвертируем в попугаи
    private fun convertMeterToParrot(meter: Float): Float = (meter * 7.6).toFloat()
}

// Java package ru.alexanderklimov.converter; import ... public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // Конвертируем в метры private float convertParrotToMeter(float parrot) { return (float) (parrot / 7.6); } // Конвертируем в попугаи private float convertMeterToParrot(float meter) { return (float) (meter * 7.6); } public void onClick(View view) { RadioButton meterRadioButton = findViewById(R.id.radioButtonMeter); EditText inputEditText = findViewById(R.id.editText); if (inputEditText.getText().length() == 0) { Toast.makeText(getApplicationContext(), "Введите длину кота", Toast.LENGTH_LONG).show(); return; } float inputValue = Float.parseFloat(inputEditText.getText().toString()); if (meterRadioButton.isChecked()) { inputEditText.setText(String .valueOf(convertParrotToMeter(inputValue))); } else { inputEditText.setText(String .valueOf(convertMeterToParrot(inputValue))); } } }

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

Запускаем проект и любуемся новым приложением.

Готовое приложение

Заключение

Чтобы быть уверенным, что мы применяли научные методы при написании программы, обратимся к Google с поисковым запросом метры в попугаях

Метры в попугаях

Правда, с момента написания статьи прошло много лет и Гугл уже не даёт такой результат, как на скриншоте.

Тем не менее, вам осталось поймать длиннокота и измерить его. Результаты необходимо показать коту и, тогда вас ждёт сюрприз! Кот от удивления произнесёт знаменитую фразу: А в попугаях я гораздо длиннее!

Дополнительное чтение

Обсуждение статьи на форуме.

Реклама