Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Разработка мобильных приложений в среде Android Studio. Учебное пособие
.pdf
5.3. Геолокация
81
Объект Location не содержит в себе названий стран, городов или адресов в какой-либо форме, он хранит только координаты – долготу и широту,
и может совершать с ними различные действия, например, вычислять расстояние между ними. Для получения по этим координатам более подробной информации используется класс Geocoder, для инициализации которого необходимо Activity и указание желаемой локализации. В представленном примере приведен способ нахождения названия города по координатам.
Далее переходим к функции getLocation() [42].
private String getLocation (double lat, double lon){
String countryName ="";
Geocoder geocoder =new Geocoder(this,Locale.getDefault());
List<Address> addresses;
try{
addresses=geocoder.getFromLocation(lat,lon,10);
if(addresses.size()>0){
for(Address adr:addresses){
if(adr.getCountryName()!=null&&adr.getCountryName().length()>0){
countryName=adr.getCountryName();
break;
}
}
}
}catch (IOException e){
e.printStackTrace();
}
return countryName;
}
Имеется возможность задать любую локализацию, например, Locale.ENGLISH либо взять локализацию устройства с использованием
Locale.getDefault(). Более подробная информация о местоположении хра-

5. Работа с сетью
82
нится в классе Address, объект которого можно получить используя координаты из класса Location и класса Geocoder с помощью функции
getFromLocation(). Первые два аргумента – долгота и широта, третий –
сколько вариантов локации для заданных координат вернуть. Обычно достаточно одного. Данная функция возвращает список адресов, найденных
для заданных координат. В этом классе хранится информация о стране, городе, почтовом индексе и так далее.
Рассмотрим самые основные методы класса Address:
getCountryCode() – возвращает код страны для адреса, например
«США», или ноль, если он неизвестен;
getCountryName() – возвращает локализованное название страны по
адресу, например «Исландия», или ноль, если оно неизвестно;
getExtras() – возвращает дополнительную специфичную для по-
ставщика информацию об адресе в виде Bundle;
getPostalCode() – возвращает почтовый индекс адреса, например
«94110», или ноль, если он неизвестен;
getPremises() – возвращает адрес помещения или ноль, если он не-
известен;
getSubAdminArea() – возвращает имя административной области
для адреса, например «округ Санта-Клара», или ноль, если оно неизвестно.
Контрольные вопросы
1. Особенности реализации сетевого функционала в мобильных прило-
жения в Android.
2. Что такое HttpURLConnection?
3. Шаги реализации получения данных с сайта.
4. JSON-файлы. Структура.
5. Классы работы с JSON-файлом.
6. Шаги разбора JSON-файла.
7. Что такое GSON?
8. Что такое аннотация в тексте программы?
9. Какие аннотации используются при представлении JSON-структуры
в java-коде.
10. Последовательность работы с Gson.
11. Последовательность реализации геолокации.

83
6. СПИСКИ В МОБИЛЬНЫХ ПРИЛОЖЕНИЯХ
Одним из важнейших элементов пользовательского интерфейса в мобильных приложениях является список. В операционной системе Android
его можно реализовать несколькими способами:
1) ScrollView;
2) ListView;
3) RecyclerView.
Первый из представленных выше элементов имеет существенное отличие от оставшихся двух – позволяет «скроллировать» свои дочерние
элементы и более никаких дополнительных функций не предоставляет.
Второй и третий элементы имеют более широкий спектр возможностей, но
между ними есть существенные различия:
производительность RecyclerView намного выше, чем у ListView за
счет встроенного паттерна ViewHolder;
Listview обеспечивает возможность располагать элементы только в
вертикальном линейном порядке без предоставления каких-либо изменений. В отличие от Listview RecyclerView имеет RecyclerView.Layoutmanager, который позволяет реализовать любое размещение
элементов, включая горизонтальные списки или сетки в шахматном порядке;
Listview не содержит никаких специальных механизмов, посредством которых можно анимировать добавление или удаление элементов. В
свою очередь RecyclerView имеет RecyclerView.ItemAnimator, позволяющий управлять анимацией;
ListView имеет встроенный источник данных для разных типов,
RecyclerView такого источника не имеет и требует обязательной реализа-
ции данного механизма;
ListView имеет встроенный «слушатель» нажатия на элемент, в то
время как RecyclerView поддерживает только «слушатель» касания, который управляет отдельным событием нажатия, но не имеет встроенного
управления им.
На основании перечисленных выше возможностей рекомендуется использовать RecyclerView [43].

6. Списки в мобильных приложениях
84
6.1. Создание RecyclerView
Создание RecyclerView реализуется на основе четырех шагов.
Первым шагом создания RecyclerView является подключение биб-
лиотеки. В файле gradle (Module:App) в части dependencies необходимо дописать строку, с помощью которой среда подгрузит необходимые файлы:
implementation 'com.android.support:recyclerview-v7:28.0.0'
Второй шаг – добавление RecyclerView на макет. Данный элемент
доступен для редактирования в графическом режиме, таким образом можно
просто «перетащить» его на форму. После чего макет примет вид, представленный на рис. 25.
Рис. 25. Макет, содержащий RecyclerView
Внешний вид данного элемента можно изменить. Если выделить Re-
cyclerView, то появится кнопка (рис. 26). При нажатии на нее появится меню (рис. 27), где первая строка отвечает за визуальное отображение списка

6.1. Создание RecyclerView
85
на макете. Данная настройка никак не влияет ни на внешний вид списка
при работе приложения, ни на его функционал, лишь на его отображение в
графическом режиме при разработке. Но стоит отметить, что среда разработки сразу создает xml-файл с названием «recycler_view_item» и выбранным содержимым.
Рис. 26. Кнопка настроек отображения RecyclerView
Представленный на рис. 25 макет соответствует следующему xml-
файлу:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
tools:context=".MainActivity">

6. Списки в мобильных приложениях
86
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
Рис. 27. Настройка отображения списка в графическом режиме
Третий шаг – связать view-элемент в макете и Activity, как показано
в представленном ниже коде класса главного Activity:
public class MainActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
@Override

6.1. Создание RecyclerView
87
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
}
}
В представленном выше примере строка
mRecyclerView.setHasFixedSize(true)
означает, что изменение содержимого списка не будут изменять размеры
элемента RecyclerView. Данный параметр оптимизирует работу списка за
счет исключения проверок содержимого на занимаемый ими размер.
Как уже упоминалось выше, RecyclerView может располагать элементы списка не только линейно, но и в виде сетки. За этот параметр отвечает LayoutManager. В строке RecyclerView.LayoutManager
mLayoutManager = new LinearLayoutManager(this) представлен
LinearLayoutManager – линейное расположение элементов. Если необходи-
мо расположить элементы сеткой, то следует использовать
GridLayoutManager. Рассматриваемая строка создает экземпляр класса
LayoutManager необходимого типа.
Строка mRecyclerView.setLayoutManager(mLayoutManager) устанавливает необходимый тип расположения элементов.
Четвертый шаг – добавление адаптера. Адаптер – это класс, создающий views для элементов списка и замещающий содержимое невидимых
элементов новыми данными. Адаптер создается путем создания нового
java-файла.
Представленный ниже код класса адаптера включает минимально необходимый набор методов.
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {
private List<String> mDataset;

6. Списки в мобильных приложениях
88
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public MyViewHolder(View v) {
super(v);
mTextView = v.findViewById(R.id.my_text_view);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i("Click", "on item click");
}
});
}
}
public MyRecyclerViewAdapter(List<String> myDataset) {
mDataset = myDataset;
}
@Override
public MyRecyclerViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_view_item, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.mTextView.setText(mDataset.get(position));
}
@Override

6.1. Создание RecyclerView
89
public int getItemCount() {
return mDataset.size();
}
}
Ниже представлен макет элемента списка.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:padding="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/my_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@tools:sample/lorem" />
</LinearLayout>
Рассмотрим подробно представленный выше код класса адаптера:
1. public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder>
Название класса – MyRecyclerViewAdapter. Он расширяет (extends)
класс RecyclerView.Adapter, содержащий в себе внутренний класс
MyViewHolder.
2. private List<String> mDataset;
Класс содержит данные, которые впоследствии выводятся на экран и
которыми заполняются элементы View (элементы списка). В примере этими данными является список строк. В качестве этих данных может высту-

6. Списки в мобильных приложениях
90
пать также массив и любой класс, данными которого будет заполняться
элементы RecyclerView.
3. public static class MyViewHolder extends RecyclerView.ViewHolder
{
public TextView mTextView;
public MyViewHolder(View v) {
super(v);
mTextView = v.findViewById(R.id.my_text_view);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i("Click", "on item click");
}
});
}
}
MyViewHolder – внутренний класс, предназначенный для хранения
информации о View-элементах списка. В примере каждый элемент содержит текстовое поле. Связь текстового поля с макетом происходит в конструкторе класса. Данный класс также содержит неявный элемент
itemView, который является общим View для всего элемента списка. В
примере показано добавление обработчика клика на элемент. RecyclerView
не содержит встроенного обработчика нажатий на свои элементы.
4. public MyRecyclerViewAdapter(List<String> myDataset) {
mDataset = myDataset;
}
Конструктор адаптера, который принимает список строк для отобра-
жения в списке.
5. public MyRecyclerViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
