Главная страница
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
qrcode

Программирование под Android. Для профессионалов


Скачать 19.35 Mb.
НазваниеПрограммирование под Android. Для профессионалов
АнкорBrayn Khardi Bill Fillips - Programmirovanie po.
Дата23.05.2017
Размер19.35 Mb.
Формат файлаpdf
Имя файлаBrayn_Khardi_Bill_Fillips_-_Programmirovanie_po.pdf
оригинальный pdf просмотр
ТипДокументы
#21061
страница55 из 55
КаталогОбразовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей
1   ...   47   48   49   50   51   52   53   54   55
Глава 36. Карты
Используя этот метод в
RunManager
, можно создать удобный фасад (façade) для
RunMapFragment
Листинг 36.8. Запрос позиций серии, часть II (RunManager.java)
public LocationCursor queryLocationsForRun(long runId) {
return mHelper.queryLocationsForRun(runId);
}
RunMapFragment может использовать этот новый метод для загрузки позиций. Есте- ственно, запрос к базе данных следует вынести из главного потока при помощи
Loader
. Создайте новый класс
LocationListCursorLoader для решения этой задачи.
Листинг 36.9. Загрузчик позиций (LocationListCursorLoader.java)
public class LocationListCursorLoader extends SQLiteCursorLoader {
private long mRunId;
public LocationListCursorLoader(Context c, long runId) {
super(c);
mRunId = runId;
}
@Override
protected Cursor loadCursor() {
return RunManager.get(getContext()).queryLocationsForRun(mRunId);
}
}
Используйте новый загрузчик в
RunMapFragment для загрузки позиций.
Листинг 36.10. Загрузка позиций в RunMapFragment (RunMapFragment.java)
public class RunMapFragment extends SupportMapFragment
implements LoaderCallbacks {
private static final String ARG_RUN_ID = "RUN_ID";
private static final int LOAD_LOCATIONS = 0;
private GoogleMap mGoogleMap;
private LocationCursor mLocationCursor;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Проверка идентификатора серии в аргументе и поиск серии
Bundle args = getArguments();
if (args != null) {
long runId = args.getLong(ARG_RUN_ID, -1);
if (runId != -1) {
LoaderManager lm = getLoaderManager();
lm.initLoader(LOAD_LOCATIONS, args, this);
}
}
}

Вывод маршрута
587
...
@Override
public Loader onCreateLoader(int id, Bundle args) {
long runId = args.getLong(ARG_RUN_ID, -1);
return new LocationListCursorLoader(getActivity(), runId);
}
@Override
public void onLoadFinished(Loader loader, Cursor cursor) {
mLocationCursor = (LocationCursor)cursor;
}
@Override
public void onLoaderReset(Loader loader) {
// Завершение работы с данными
mLocationCursor.close();
mLocationCursor = null;
}
}
Класс
RunMapFragment сохраняет объект
LocationCursor для списка позиций. Этот список будет использоваться при построении карты с маршрутом.
Реализация onLoaderReset(Loader)
закрывает и обнуляет ссылку на курсор, когда тот становится недоступным. В обычных обстоятельствах этот метод будет вызываться при закрытии загрузчика объектом
LoaderManager при выходе поль- зователя с фрагмента, содержащего карту. Вдобавок такое решение не закрывает курсор при выполнении поворота, а это именно то, что нам нужно.
Мы подошли к самой интересной части этой главы: выводу информации на
GoogleMap
. Добавьте метод updateUI()
с заполнением данных отображаемой серии, и вызовите этот метод в onLoadFinished(…)
Листинг 36.11. Нанесение данных серии на карту (RunMapFragment.java)
private void updateUI() {
if (mGoogleMap == null || mLocationCursor == null)
return;
// Создание накладки с позициями серии.
// Создаем ломаную со всеми точками.
PolylineOptions line = new PolylineOptions();
// Также создается объект LatLngBounds для масштабирования по размерам.
LatLngBounds.Builder latLngBuilder = new LatLngBounds.Builder();
// Перебор позиций
mLocationCursor.moveToFirst();
while (!mLocationCursor.isAfterLast()) {
Location loc = mLocationCursor.getLocation();
LatLng latLng = new LatLng(loc.getLatitude(), loc.getLongitude());
line.add(latLng);
latLngBuilder.include(latLng);
mLocationCursor.moveToNext();
}
// Добавление маршрута на карту
mGoogleMap.addPolyline(line);
// Масштабирование карты по маршруту с дополнительными отступами
продолжение


588
Глава 36. Карты
Листинг 36.11 (продолжение)
// В качестве ограничивающего прямоугольника выбирается
// размер текущего экрана.
Display display = getActivity().getWindowManager().getDefaultDisplay();
// Построение инструкции перемещения для камеры карты.
LatLngBounds latLngBounds = latLngBuilder.build();
CameraUpdate movement = CameraUpdateFactory.newLatLngBounds(latLngBounds,
display.getWidth(), display.getHeight(), 15);
mGoogleMap.moveCamera(movement);
}
@Override public Loader onCreateLoader(int id, Bundle args) {
long runId = args.getLong(ARG_RUN_ID, -1);
return new LocationListCursorLoader(getActivity(), runId);
}
@Override public void onLoadFinished(Loader loader, Cursor cursor) {
mLocationCursor = (LocationCursor)cursor;
updateUI();
}
Новый метод использует Maps API в нескольких местах. Сначала он создает экзем- пляр
PolylineOptions
, который будет использоваться для построения маршрута, выводимого на экран, и экземпляр
LatLngBounds.Builder для создания ограничи- вающего прямоугольника для масштабирования карты.
Затем он перебирает данные
LocationCursor и для каждого объекта
Location создает объект
LatLng с его координатами. Объект
LatLng включается в
PolylineOptions
, а последний включается в
LatLngBounds перед переходом к следующей строке в курсоре.
После перебора всех позиций метод вызывает addPolyline(PolylineOptions)
для
GoogleMap
, добавляя маршрут на карту.
На следующем шаге следует масштабировать карту так, чтобы на ней помещалась вся линия. Перемещение по карте относится к ответственности «камеры», а для на- стройки камеры используются команды, упакованные в экземплярах
CameraUpdate и передаваемые moveCamera(CameraUpdate)
. Создание экземпляра для перемеще- ния камеры по границам только что добавленной линии выполняется методом newLatLngBounds(LatLngBounds,
int,
int,
int)
класса
CameraUpdateFactory
Мы передаем размеры текущего экрана как приближенное значение размера карты в пикселах, с добавлением нескольких пикселов на отступы, чтобы маршрут лучше смо- трелся. Существует упрощенная версия этого метода newLatLngBounds(LatLngBounds,
int)
, но она выдает исключение
IllegalStateException
, если метод будет вызван до того, как
MapView завершит определение своих размеров в процессе построения макета. Так как мы не можем гарантировать, что это произойдет к моменту вызова updateUI()
, приходится использовать приблизительную оценку.
Внесите изменения и снова запустите RunTracker — на карте появляется черная линия, обозначающая маршрут. Пожалуй, сейчас стоит поближе познакомиться с классом
PolylineOptions и попытаться немного украсить результат.

Добавление маркеров начала и конца маршрута
589
Добавление маркеров начала и конца маршрута
Теперь, когда мы подготовили все необходимое, добавить маркеры, обозначающие начальную и конечную позиции маршрута, относительно несложно. Мы также добавим текст, который будет выводиться в информационном окне при прикос- новении к маркеру.
Добавьте в метод updateUI()
код, выделенный жирным шрифтом.
Листинг 36.12. Маркеры начала и конца маршрута с информацией (RunMapFragment.java)
private void updateUI() {
if (mGoogleMap == null || mLocationCursor == null)
return;
// Создание накладки с позициями серии.
// Создаем ломаную со всеми точками.
PolylineOptions line = new PolylineOptions();
// Также создается объект LatLngBounds для масштабирования по размерам.
LatLngBounds.Builder latLngBuilder = new LatLngBounds.Builder();
// Перебор позиций mLocationCursor.moveToFirst();
while (!mLocationCursor.isAfterLast()) {
Location loc = mLocationCursor.getLocation();
LatLng latLng = new LatLng(loc.getLatitude(), loc.getLongitude());
Resources r = getResources();
// Если это первая позиция, добавить маркер
if (mLocationCursor.isFirst()) {
String startDate = new Date(loc.getTime()).toString();
MarkerOptions startMarkerOptions = new MarkerOptions()
.position(latLng)
.title(r.getString(R.string.run_start))
.snippet(r.getString(R.string.run_started_at_format, startDate));
mGoogleMap.addMarker(startMarkerOptions);
} else if (mLocationCursor.isLast()) {
// Если это последняя позиция, которая не является
// также первой, добавить маркер
String endDate = new Date(loc.getTime()).toString();
MarkerOptions finishMarkerOptions = new MarkerOptions()
.position(latLng)
.title(r.getString(R.string.run_finish))
.snippet(r.getString(R.string.run_finished_at_format, endDate));
mGoogleMap.addMarker(finishMarkerOptions);
}
line.add(latLng);
latLngBuilder.include(latLng);
mLocationCursor.moveToNext();
}
// Добавление маршрута на карту mGoogleMap.addPolyline(line);
Для первой и последней точки маршрута код создает экземпляр
MarkerOp- tions для хранения позиции, заголовка и дополнительного текста. Заголовок

590
Глава 36. Карты и дополнительный текст выводятся в простом информационном окне, когда поль- зователь прикасается к маркеру.
В этом коде используется маркер по умолчанию, но при желании можно создать маркер другого цвета (и даже содержащий заданное изображение) при помощи метода icon(BitmapDescriptor)
и
BitmapDescriptorFactory
. Существует много стандартных цветов, из которых вы можете выбрать нужный.
Запустите приложение RunTracker и протестируйте его во время своего следующего путешествия. Счастливого пути!
Упражнение. Оперативное обновление
В текущей версии
RunMapFragment может отображать карту с местоположениями серии, «замороженными» по времени на момент прибытия пользователя. Каче- ственное геопозиционное приложение должно выводить обновления в режиме
«живого» обновления. Используя субкласс
LocationReceiver в
RunMapFragment
, организуйте обработку поступления новых позиций с перерисовкой маршрута.
Не забудьте удалить предыдущую накладку (overlay) и маркеры, прежде чем до- бавлять новые.

Послесловие
Поздравляем! Вы добрались до последней страницы этого учебника. Не каждому хватило бы терпения сделать то, что вы сделали; узнать то, что вы узнали. Ваша самоотверженная работа не пропала даром; теперь вы стали разработчиком Android.
Последнее упражнение
У нас осталось еще одно, последнее упражнение для вас: станьте хорошим разработ- чиком Android. Каждый хороший разработчик хорош по-своему, поэтому с этого момента вы должны найти собственный путь.
С чего начать, спросите вы? Мы можем дать несколько советов.

Пишите код
. Начинайте прямо сейчас. Вы быстро забудете то, что узнали в книге, если не будете применять полученные знания. Примите участие в про- екте или напишите собственное простое приложение. Что бы вы ни выбрали, не тратьте времени: пишите код.

Учитесь
. В этой книге вы узнали много полезной информации. Что-то из этого пробудило ваше воображение? Поэкспериментируйте со своими любимыми возможностями. Найдите и почитайте дополнительную документацию по ним — или целую книгу, если она есть.

Встречайтесь с людьми
. Многие первоклассные разработчики Android посто- янно бывают на канале
#android-dev сервера irc.freenode.net
. Сайт Android
Developer Office Hours (https://plus.google.com/+AndroidDevelopers/posts) поможет вам оставаться на связи с группой разработки Android и другими заинтересованными разработчиками. Локальные встречи также помогут вам найти единомышленников.

Присоединяйтесь к сообществу разработки с открытым кодом
. Разработка
Android процветает на сайте https://www.github.com. Обнаружив полезную би- блиотеку, посмотрите, в каких еще проектах участвуют его авторы. Делитесь своим кодом — никогда не знаешь, кому он пригодится.
37

592
Глава 37. Послесловие
Бессовестная самореклама
Если вам понравилась книга, ознакомьтесь с другими учебниками Big Nerd Ranch по адресу https://www.bignerdranch.com/books. У нас также имеется широкий вы- бор недельных курсов для разработчиков, на которых вы всего за неделю сможете получить массу полезной информации. И конечно, если вам понадобятся услуги опытных разработчиков, мы также занимаемся контрактным программированием.
За подробностями обращайтесь на наш сайт по адресу https://www.bignerdranch.com.
Спасибо
Без таких читателей, как вы, наша работа была бы невозможной. Спасибо вам за то, что купили и прочитали нашу книгу.
1   ...   47   48   49   50   51   52   53   54   55

перейти в каталог файлов

Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей

Образовательный портал Как узнать результаты егэ Стихи про летний лагерь 3агадки для детей