Как создать свое первое приложение для Android. Часть 2

В предыдущей части мы только знакомились с инструментами разработки и создавали простые кнопки в Android-приложении. Сегодня мы сделаем более сложное приложение на «модном» языке программирования Kotlin и немного углубимся в особенности использования Android Studio. Используемая версия Android Studio – 3.3 для Windows.

Наше новое приложение на Android поможет решить незамысловатую задачу – куда поехать в отпуск. Нажимаем кнопку... и смартфон за нас определяет, в какую страну стоить полететь.

Почему на Kotlin? Потому что простой и современный.

В целом Kotlin решает целый ряд проблем, которые были в Java. Это сравнительно молодой язык программирования – он был представлен в 2011 г. Подробнее о его преимуществах и недостатках можно почитать здесь. Kotlin совместим с Java и является его развитием в каком-то смысле.

 

Новый проект

Для начала создаем новый проект. Если у вас уже открыт Android Studio – выбираем File – New – New Project.

Выбираем Basic Activity. Жмем Next. Название приложения – Traveling. Не забываем выбрать Language – Kotlin. Минимальный API – 14. Жмем Finish. Готово, у вас открылся новый проект. В нем уже есть одно окно.

Слева вверху есть возможность переключения режима отображения файлов проекта. По умолчанию Android Studio показывает файлы, которые относятся к Android.

Если нажать на выпадающее меню сверху слева, можно увидеть различные настройки отображения. Основными для работы являются Project и Android. Project покажет все модули приложения. По умолчанию используется Android, которые структурирует все файлы на 4 категории:

  • Manifests
  • Java
  • Res
  • Gradle scripts

Несмотря на то, что мы будем использовать Kotlin для создания приложения – папка называется java. Это не должно вас запутать.

 

Первые настройки

Как мы помним, все базовые требования нашего приложения находятся в файле AndroidManifest.xml В AndroidManifest.xml можно поменять иконку приложения, выставить тему, права необходимые приложению и многое другое.

Пока что наше приложение пустое, тем не менее, мы применим первую настройку для него. Добавим в AndroidManifest.xml такую строку:

android:screenOrientation="portrait"

Если она уже есть – отлично. Когда вы добавили эту настройку – соберите приложение и запустите его (на эмуляторе либо смартфоне). Попробуйте повернуть телефон – экран не будет поворачиваться, потому что используется настройка из файла AndroidManifest.xml

 

Gradle

Gradle – это инструмент для автоматической сборки вашего проекта. По сути, это отдельный инструмент, который помогает разработчику автоматически «строить» приложения из мелких «кусков» – исходного кода, скриптов, файлов конфигурации. Альтернативой Gradle являются широко известные Ant и Maven. В нашем конкретном случае Gradle создает (компилирует) файл .apk, который можно потом загрузить в смартфон.

Открываем слева раздел Gradle scripts и выбираем build.gradle (Module:app). Здесь мы можем увидеть стандартный набор для компиляции и другую дополнительную информацию:

Apply plugin. Эта команда применяет plugin-ы. В нашем случае добавляет поддержку kotlin (apply plugin: 'kotlin-android').

Android {…} – здесь устанавливаются настройки на какой версии API будет работать приложение. (targetSdkVersion 28)

Dependencies {…} – зависимости. Здесь можно добавить внешние библиотеки. В нашем случае строка 'com.android.support:appcompat-v7:28.0.0' означает совместимость приложения с более старыми API.


Устанавливаем внешние библиотеки

Как дополнение к существующим библиотекам есть возможность подключить внешние для расширения возможностей приложения.

В нашем случае мы добавим анимацию картинки с помощью сторонней библиотеки. Для этого находим раздел dependencies в build.gradle (Module:app). Добавляем туда такой код:

implementation 'com.daimajia.easing:library:2.0@aar'
implementation 'com.daimajia.androidanimations:library:2.2@aar'

Должно получиться так:

Android Studio автоматически поймет, что вы подключаете сторонние библиотеки и предложит их скачать и установить. Появится кнопка Sync Now. Нажмите ее. Библиотеки установлены. 

 

Добавляем изображение

Загружать картинку в наше приложение мы будем немного другим способом, нежели в прошлой статье.

На Android-устройствах может применяться различное разрешение экрана. Чтобы картинки не растягивались и не сжимались, в зависимости от разрешения их можно загружать в нескольких версиях (mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi). Самая распространенная сейчас xxhdpi. Эту версию картинки мы и загрузим в наше приложение.

Переключаемся в режим отображения Project и идем в appsrcmain res. Правой кнопкой мыши нажимаем на папке res и выбираем New - Android resource directory. В открывшем окне вверху выбираем drawable. Слева выбираем density и жмем >>. Далее из выпадающего меню выбираем XX-High Density и жмем OK.

После этого скачайте картинку ниже и назовите ее img_earth.png

Уже на компьютере скопируйте ее в буфер обмена (CTRL + C). Затем щелкните на папке drawable-xxhdpi и нажмите CTRL + V.

Появится окно с предложением добавить картинку в ваш проект. Жмите ОК. Картинка успешно добавлена.

 

Устанавливаем значения

Как профессиональные программисты мы определим некоторые значения в отдельных файлах.

Для этого откроем файл strings.xml (находится в папке res - values). В него добавим такой код:

<string name="travel_description">В какую страну поехать в отпуск?</string>

Файл strings.xml обычно содержит в себе строки (текст), которые видит пользователь в своем приложении. Это упрощает перевод приложения на другие языки, так как вам остается только добавить соответствующий текст в этот файл.

Теперь откроем файл dimens.xml (находится в res - values) и добавим следующий код:

<dimen name="description_text_size">24sp</dimen>
<dimen name="travel_text_size">21sp</dimen>

Здесь мы устанавливаем размер текста. Все что касается размеров – лучше прописывать в отдельный файл.

 

Создаем интерфейс

Теперь откроем файл content_main.xml (папка res - layout) и полностью заменим его содержимое на следующий код:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:showIn="@layout/activity_main"
        tools:context=".MainActivity">

    <TextView
            android:id="@+id/descriptionText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_marginTop="8dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:text="@string/travel_description"
            android:textSize="@dimen/description_text_size"/>

    <ImageView
            android:id="@+id/earthImage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@+id/descriptionText"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginTop="10dp"
            android:src="@drawable/img_earth"/>

    <TextView
            android:id="@+id/travelText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:gravity="center"
            app:layout_constraintTop_toBottomOf="@+id/earthImage"
            android:textColor="@android:color/holo_blue_dark"
            android:textSize="@dimen/travel_text_size"
            android:textStyle="bold"/>

    <Button
            android:id="@+id/travelButton"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_below="@id/travelText"
            android:layout_centerHorizontal="true"
            app:layout_constraintTop_toBottomOf="@+id/travelText"
            android:layout_marginTop="10dp"
            android:text="Нажми, чтобы узнать"/>
</android.support.constraint.ConstraintLayout>

После этого переключитесь в режим Design. Вы увидите интерфейс нашего приложения. С помощью кода выше мы его построили. Общий блок ConstraintLayout вмещает в себя все элементы: 2 строки текста TextView, кнопка Button и картинка ImageView (с анимацией).

На этом этапе уже можно запустить приложение. Жмем Run app.

Вы увидите интерфейс, но кнопка все еще не работает. Пора сделать ее интерактивной!

 

Подключаем код

Писать код (на Kotlin) мы будем здесь app – java – com.example.traveling. Там откроем MainActivity.kt 

После строк import добавляем код:

class MainActivity : AppCompatActivity() {
    private var travelList = arrayOf(
        "Греция",
        "Турция",
        "Испания",
        "Албания",
        "Россия",
        "Индонезия",
        "Польша",
        "Украина",
        "Болгария",
        "Остаться в Беларуси",
        "Италия"
    )

    private lateinit var travelText: TextView
    private lateinit var generatetravelButton: Button
    private lateinit var travelimgImage: ImageView

В начале мы определяем массив (travelList), из которого будут загружаться названия стран. Затем мы определяем переменные для элементов интерфейса.

Дальше добавляем код, чтобы в итоге Mainactivity выглядел так:

package com.example.traveling

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import com.daimajia.androidanimations.library.Techniques
import com.daimajia.androidanimations.library.YoYo
import kotlinx.android.synthetic.main.content_main.*
import java.util.*

class MainActivity : AppCompatActivity() {
    private var travelList = arrayOf(
        "Греция",
        "Турция",
        "Испания",
        "Албания",
        "Индонезия",
        "Россия",
        "Польша",
        "Украина",
        "Болгария",
        "Остаться в Беларуси",
        "Италия"
    )

    private lateinit var travelText: TextView
    private lateinit var generatetravelButton: Button
    private lateinit var travelimgImage: ImageView


    override fun onCreate(savedInstanceState: Bundle?) {
        // 1:
        super.onCreate(savedInstanceState)
        // 2:
        setContentView(R.layout.activity_main)
        val toolbar = findViewById<View>(R.id.toolbar) as Toolbar
        setSupportActionBar(toolbar)
        // 3:
        travelText = findViewById<View>(R.id.travelText) as TextView
        travelimgImage = findViewById<View>(R.id.earthImage) as ImageView
        generatetravelButton = findViewById<View>(R.id.travelButton) as Button
        // 4:
        generatetravelButton.setOnClickListener {
            // 5:
            val index = Random().nextInt(travelList.size)
            travelText.setText(travelList[index])
            // 6:
            YoYo.with(Techniques.Wobble)
                .duration(500)
                .playOn(earthImage)
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.action_settings -> true
            else -> super.onOptionsItemSelected(item)
        }
    }
}

Что мы сделали по пунктам:

  1. Вызвали суперкласс.
  2. Определили, чтобы вызывался основной layout
  3. Определили значения 3 переменных, заданных ранее. Взяли id из ранее созданных файлов интерфейса.
  4. Повесили на кнопку (Button) простую функцию.
  5. Генерируем случайное выбор из массива стран – функция кнопки.
  6. Используем стороннюю библиотеку (мы ее подключили с помощью Gradle) для создания анимации картинки. Устанавливаем тип эффекта и длительность. Полный список эффектов есть тут. Можете выбрать свой.

Все почти готово! Жмем Build и Run App. У нас получается уже работающее приложение.

Кнопка работает и показывает, в какую страну мы едем.

Портит вид лишь розовый значок почты внизу справа. Он нам не нужен. Для того, чтобы его удалить, нужно зайти в reslayout и открыть activity_main.xml.

Вот этот блок нужно очистить:

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_dialog_email"/>

Все! Теперь ненужная кнопка удалена.

Вот как выглядит приложение уже на смартфоне.

 

Logcat

Это еще не все! Android Studio позволяет заглянуть «под капот» вашего приложения. Для этого существует Logcat. Выберите вкладку Logcat внизу проекта. Или нажмите ALT + 6. Вверху вкладки вы выбираете устройство для мониторинга. Logcat позволяет просмотреть системные сообщения и логи любых приложений и процессов. Это может быть удобно, если у вас есть какая-то проблема. Чтобы видеть сообщения только от вашего приложения выберите: Show only selected application.

 

Добавляем сообщения в Logcat

Для отладки Android-приложения можно добавить свое сообщения в Logcat. Это нужно, чтобы понять, выполнилось ли то или иное действие. Для этого добавим в MainActivity.kt такую строку:

Log.v("travel Tag", "После Create")

Должно получиться так:

 

Мы создали тэг и сообщение.

Чтобы его протестировать, необходимо сохранить и запустить приложение (SHIFT + F10). Затем открываем панель Logcat (там будет много сообщений) и в поиске указываем «После». Видим нашу строчку. Работает!

 

Узнаем почему приложение «падает»

Еще одна полезная функция Logcat – это возможность проанализировать сообщения, которые появляются, когда приложение аварийно завершается. Сначала добавим «баг» в наше приложение. Открываем MainActivity.kt и комментируем строку:

///  travelText = findViewById<View>(R.id.travelText) as TextView

Запускаем приложение на эмуляторе. Нажимаем на кнопку и приложение «падает». Что и требовалось получить. Теперь открываем вкладку Logcat и видим красный текст. Logcat показывает, что есть проблемы с переменной. Он даже показывает, на какой строчке есть проблема. Читая сообщения Logcat, можно понять, в чем проблема. 

Вот такой мощный инструмент отладки. Не забудьте все вернуть на место и раскомментировать строку. Теперь можно тестировать свое готовое приложение. Итоговый исходный код вы можете скачать здесь.

 

Версия для печатиВерсия для печати

Рубрики: 

  • 1
  • 2
  • 3
  • 4
  • 5
Всего голосов: 2
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!