DOU Проектор: Android приложение для чтения Ленты DOU

В рубрике DOU Проектор все желающие могут презентовать свой продукт (как стартап, так и ламповый pet-проект). Если вам есть о чем рассказать — приглашаем поучаствовать. Если нет — возможно, серия вдохновит на создание собственного made in Ukraine продукта. Вопросы и заявки на участие присылайте на editors@dou.ua.

Идея

Всем привет. Меня зовут Богдан Коломиец, хочу поделиться историей создания приложения для сайта DOU.ua, с помощью которого можно просматривать список статей, читать тексты и комментарии к ним, а также сохранять материалы и читать их оффлайн, например, в метро.

Чуть более полгода назад я купил себе первое Android устройство и стал пробовать программировать под эту платформу. Вскоре после этого мне на почту пришло оповещения с DOU. Я нажал на ссылку и попал на мобильную версию сайта. Подумав о том, что мне не очень нравиться читать статью в браузере, я полез в PlayMarket за поиском клиента, который, как я был уверен, есть. Но я ошибался... Так и возникла идея написать это приложение самому.

Реализация

Итак, первым делом я начал искать какое-то API. Найдя на форуме топик на эту тему, понял, что API мне не светит. Я решил не сдаваться и парсить сайт. О том, плохо это или хорошо, будем судить потом. Выбрал библиотеку Jsoup, она легка в использовании и неплохо работает. С архитектурой я на тот момент не особо заморачивался, так как до этого в основном писал приложения типа калькулятора.

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

Код я приводить не буду, в конце статьи дам ссылку на исходники.

Итак, я использовал Material Design и несколько строк кода на Java для библиотеки Jsoup, и в итоге получилось вот что:

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

Для начала нужно было решить вопрос с последовательностью. Как мы проходим по странице при парсинге, в такой же последовательности мы должны и отображать это в приложение. Тогда я придумал следующее решение. При открытии страницы новостей создается список. Если при парсинге выбранный элемент равен картинке, то мы создаем объект, у которого идентификатором выступает картинка, если таблица — то идентификатор таблица и т. д. Соответственно, потом при отображении мы проходим по элементам и сверяем их идентификаторы.

Так была написана и вторая страница, вроде как-то работало. Но потом я перестал заниматься этой разработкой, а спустя 3 месяца решил всё переписать с нуля.

Перерождение. Новая версия была построена на MVP архитектуре. Это дало возможность сделать код более абстрактным, компактным и нечувствительным к изменениям. Также использовал Dagger 2 для Dependency Injection. Это тоже дало много своих преимуществ: к примеру, возможность следить за жизненным циклом объекта, что бывает в Android болезненно.

Также использовал Реактивное программирование (RxJava), что сейчас очень модно, стильно и молодёжно:). На самом деле один из главных плюсов при работе с сетью — это легкость в управлении потоками. Пару слов о сети: здесь также использовалась библиотека Jsoup, но завернутая в конвертер, который был написан для Retrofit2, куда я с легкостью поместил кэширование.

Дизайн главного экрана был полностью изменен:



Кроме того, я добавил такие элементы:
— Иконку количества просмотров;
— Иконку комментариев с их количеством, по которой можно перейти для просмотра;
— Кнопку «Поделиться», которая на момент написания статьи еще не реализована.

Экран со статьей также был переделан, включая алгоритм, по которому данные добавляются и отображаются на экране. Список я инкапсулировал в отдельном классе, добавил методы, которые работают с этим объектом. Создал на каждый тип элемента отдельный класс, который благодаря наследованию и полиморфизму будет точно знать, как ему отобразиться на экране.

Результаты

В итоге, спустя 8 дней, я запустил первую бета-версию приложения на PlayMarket. Хочу заметить, всё бы сильно затянулось, если бы не помощь моей коллеги-тестировщицы Алины Берестенко.

Итак, что уже есть:
— Показ списка статей;
— Просмотр статьи;
— Просмотр комментариев;
— Сохранение информации и доступ к ней без интернета;
— Возможность делиться статьей;
— Возможность предложить статью из приложения.

Что планируется:
— Оповещения о новых статьях;
— Просмотр статей по категориям;
— Отображение ссылок в статьях.

Исходники: 1-я версия, 2-я версия.

Уважаемые читатели, надеюсь, мое приложение будет полезно для вас. Я буду активно его совершенствовать и добавлять новые возможности. Жду ваши отзывы.

38 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

Гарна робота. Не знаю, чи писали до мене. Щодо вихідних кодів: почитайте про налаштування .gitignore, це може підняти вам карму :)

А нельзя такое вот типа сделать wrapapi.com/...IzS5EZy6kCxB6bK8U71md7TBv , только более толково, это как бы например, может заморочитесь для общественности ?

это круто. Вот только я не совсем понял кому адресован этот комментарий. Мне или редакции ДОУ?

Вот приблизительно такое сделаем:
i.imgur.com/hgbbyPU.png

По внешнему виду версия 1 больше понравилась.

Вы могли бы сделать парсинг и хранение данных на стороне сервера и отдавать в клиент более подходящий формат данных, например json. Это как минимум сохранит от головной боли, если вдруг у ДОУ появится API.

Материал дизайна что-то не заметил

С самого начала стоит подумать о кэшировании контента, особенно для такого редкоизменяемого контетна. Если я только что уже видел список постов, какие то из них грузил, то отключившись от интернета(например зашел в метро — частый кейс) я не хочу видеть пустое приложение. Особенно бъет по глазам повторная загрузка статьи, когда возвращаемся из коментариев.
Советую рассмотреть этот вопрос в первую очередь, т.к. он внесет свои коррективы в структуру приложения.

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

Кэш на уровне сети и локальный кэш сущностей — это разные штуки.
1) В данной ситуации такого быть не может, но в общем — если на одну и ту же статью(сущность) можно попасть по разным ссылкам — то сетевой кэш не спасет.
2) твой случай

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

3) Когда срок действия сетевого кэша истек, то ты все еще можешь показывать контетн из локального кэша с пометкой что данные не новые, а за такое то число — это лучше чем просто пустой экран

Да, не спорю с этим) Нужно заняться будет

Коротко покритикую по приложению, без рассмотрения кода.
Material design вы явно не использовали.
1. Уберите ужасные диалоги загрузки. Где вы такие видели? Их может использовали когда-то в версиях андроида 2.х, да и то не везде. Посмотрите как делают другие приложения, в частности те, что от Google.
2. Анимации переходов между экранами слишков медленные. В гайдлайнах есть рекомендуемые значения, в курсе о дизайне для разработчиков на Udacity более подробно описано.
3. FAB не нужен. Он используется для часто используемых действий на экране. Тут один раз нажал, посмотрел, что он на самом деле ничего и не делает и больше не нажимаешь. Можно убрать в тулбар.
4. Тулбар не по гайдлайнам, он на 8dp меньше и у него там что-то странное с иконками меню, они опущены.
5. Большое расстояние между соседними карточками. Между первой карточкой и тулбаром расстояние в два раза меньше, чем расстояние между двумя соседними карточками.
6. Назначение кнопки share внизу карточки остается непонятным.

Большое спасибо за замечания ))

FAB для главного действия на скрине, а не для часто используемого. Но то что он в данном случае не нужен — факт

Також нещодавно почав кодити під Android і виникла ідея із додатком для цього сайту, але такий вже знайшов на плеймаркеті (DOU BETA) і ідею тимчасово відкинув :)
Хочу подякувати Вам за виконану роботу!

this item cannot be installed in your device’s country

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

Да, категории добавлю в скором времени

Кто-то может меня глупого научить пользовать RxJava в случае «activity lifecycle» и «configuration change» ивентов? Данное приложение с первого раза стало неюзабильным, превратившись в вечный прогресс бар. Уже давно не пользовал, но насколько помню, именно subscribe() там является энергичной функцией, что не совсем подходит для Android:
imgur.com/a/iJc5d

Какое у вас устройство? Эту багу я пока ловил только на одном устройстве, и не успел исправить

Макс Іщенко свого часу писав, що готовий надати API для цікавих проектів. Думаю, цей більш, ніж підпадає під цю категорію. Можна попросити дати API для отримання статей/коментарів.
Ну, і для написання останніх теж.
dou.ua/...orums/topic/13493/#695518

У нас уже есть full text RSS feeds, по идее это что нужно.

Вроде бы тоже были, уточню у Сергея.

Зараз починається мода на відсутність коментарів:
ain.ua/2016/08/01/662126

gReader Pro умеет скачивать все страницы по RSS ленте и можно спокойно читать в офлайне

Сьогодні, до речі, почали робити API, поки що зробили тільки піддомен:
api.dou.ua
А якогось готового API, яке можна взяти і дати, ще немає і ніколи не було :(

Это все хорошо. Полезная приложуха будет с чтением вакансий и подписка на категорию вакансий. Когда новая вакансия появляется то приходит нотификашка :-)

Да, я тоже об этом думал, добавлю обязательно)

Будет желание развивать — пиши), время свободное иногда есть. Может помогу чем смогу).

Отличная идея, сам хотел такое написать но руки не дошли. А то что кнопка + пропадает если пролистать вниз и появляется если вверх — это фича? Еще может добавить разные цветовые стили? А то черный цвет заголовков статей хоть и подходит к логотипу, но кому то может показаться слишком мрачным.

Гайдлайновская фича. Мне тоже не очень нравиться такая её работа. Но переписать что бы она пропадала в при скролле в любую сторону как то руки не дошли

Как насчет еще добавить кнопку «Оставить отзыв о приложении» и «Поделиться в соц. сетях»? Или что бы оно само периодически предлагало оценить приложение на Play маркете.

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

Под «Поделиться в соц. сетях» я имел ввиду рассказать о приложении. Хотя можно это сделать нажав на кнопку «Поделиться ссылкой...» одной из соц. сетей в этой теме.

Можете дать ссылку на гайдлайн?

Подписаться на комментарии