Мобильные приложения это уникальный вид приложений. Их особенность в том, что
- они должны работать как на маленьких, так и на относительно больших экранах
- мобильные ОС однозадачны, т.е. когда мы из приложения переключаемся, оно "засыпает"
- у пользователя все время один контекст, т.е. он может работать одновременно только с одним окном (что не мешает нам эмулировать несколько окон на экране, но "неполноценных")
Как вы помните из прошлого урока, мы выбрали шаблон приложения с заголовком, подвалом и навигацией. Мы немного дополним и изменим интерфейс. В верхней части формы у нас есть ```TopToolBar```. В его центр добавим компонент ```TcomboBox``` и назовем его ```ThemeBox```. В нем мы будем выбирать какой тип ленты данных нам будет показываться. Тут же есть 2 кнопки навигации, которые достались нам в наследство от шаблона. Не думаю, что мы их будем использовать, так как навигации осоой у нас не предвидится, но выбрасывать пока что тоже не будем.
Большую часть формы занимает компонент ```TTabControl```. Именно он будет основой нашего приложения. Так как корешков его закладок не видно, а самих их может быть довольно много, то переключение между закладками будет восприниматься пользователем как открытие нового экрана приложения. Кроме того, мы всегда можем создать новую закладку динамически и вывести на нее информацию, а после показать пользователю, что будет для него эквивалентно открытию нового экрана.
На первую закладку поместим компонент ```TListView```. В нем мы будем отображать ленту сообщений. Он конфигурируется не очень очевидным образом. Во-первых он имеет ряд свойств как потомок ```TControl```, а во-вторых мы можем сконфигурировать внешний вид отдельной строки - ```TListViewItem```. И не забудем прикрепить к нему компонент ```TImageList```, который отвечает за хранение и отображение картинок для каждой заметки. Пока что мы загрузим в него всего пару картинок в тестовых целях. Это будет логотип GOLOS. И выставим в `true` свойство ```SearchVisible```, оно позволит нам искать по заголовкам ленты.
Для самой строки выставим следующие параметры:
А именно, укажем что мы будем выводить в строке картинку, а помимо заголовка еще и подробную информацию. И зададим размеры картинки для поста:
Для начала нам этого хватит. Теперь пришла пора задуматься о том как вывести данные.
Здесь я сделаю небольшое лирическое отступление о процессе программирования. Часто, при работе над большими проектами применяют принципы декомпозиции, пилят все по частям и делают окончательную сборку в конце. А потом еще раз обрабатывают все напильником. Я же человек иного склада характера и придерживаюсь более понятной и близкой мне идеологии, которая гласит, что нужно сделать сначала минимально работающее приложение и уже потом итерациями доводить его до ума. Зато сразу видно, что у нас будет получаться.
Итак, нам нужно получить данные блокчейна голос, чтобы вывести их в нашем ```ListView```. Данные можно получить по технологии WebSocket с сервера голоса. Но есть и еще один путь, на который меня натолкнуло одно из обсуждений, что при плохом интернете GOLOS плохо работает, так как требователен к трафику. Не могу не согласится. Блокчейн самодостаточен, но для некоторых применений избыточен. Поэтому у нас есть еще один путь, получить нужные данные блокчейна запросом из БД Sql Server, любезно предоставленной сообществу @arcange. Мы планируем сделать некоторое дублирование в дальнейшем, чтобы можно было обращаться как к серверу БД, так и к WebSocket, скорее всего, на выбор. Но пока изберем более простой путь работы с БД. Он потребует наличия компонентов UniDAC, они кроссплатформенные и умеют работать с MS SQL Server.
Кладем на форму ```UniConnection```, ```SQLServerUniProvider``` и ```UniQuery```. Они сами друг друга найдут. Для ```UniConnection``` устанавливаем параметры доступа к серверу sql.golos.cloud. Теперь, на событие ```OnCreate``` формы пишем вот такой код:
```procedure THeaderFooterwithNavigation.FormCreate(Sender: TObject);
var
Item: TListViewItem;
I: integer;
Details: string;
begin
{ This defines the default active tab at runtime }
TabControl1.First(TTabTransition.None);
UniConnection.Connect;
if UniConnection.Connected then
begin
UniQuery.SQL.Clear;
UniQuery.SQL.Add('select top(30) * from TxComments where title <> '''' and parent_author = '''' order by id desc');
UniQuery.Open;
if UniQuery.RecordCount > 0 then
begin
UniQuery.First;
for I := 0 to UniQuery.RecordCount - 1 do
begin
Item := ListView.Items.Add;
Item.ImageIndex := 0;
Item.Text := UniQuery.FieldByName('title').AsString;
Details := ClearMarkdown(ConvertHTML(UniQuery.FieldByName('body').AsString));
Item.Detail := Copy(Details, 1, 40) + sLineBreak + '@' + UniQuery.FieldByName('author').AsString;
UniQuery.Next;
end;
end;
end;
end;<CR>```
Здесь есть 2 функции, которых нет в Joomla. Они помогают нам вывести "очищенный" текст начала поста. Это
```ConvertHTML``` - удаляет HTML разметку
```ClearMarkdown``` - удаляет markdown разметку.
Мы вынесли их в отдельный модуль ```GolosUtils```.
Ну что же, ставим целевой платформой Windows (так проще отлаживаться и быстрее компилироваться) и запускаем приложение. УРА! Первые данные уже появились! Они еще корявые, налезают друг на друга, не все выводится красиво, но оно уже работает.
Вот тут продолжение
Привет!
Этот пост был выбран Академией Голоса и попал в список программы поддержки качественных образовательных постов.
Ссылка на твой пост будет опубликована в отчете Академии.
Спасибо за полезный контент (ノ◕ヮ◕)ノ*:・゚✧
Саша, а эти промежуточные шаги просто образовательные? Их не стоит ли постить в #открытый-код от @golosapp? Как там условиях "открытого кода" прописано?
Туда надо коммиты постить, а здесь пока что на полноценный коммит еще не набралось на мой взгляд.
Используйте тройной обратные кавычки:
``` + <CR> + your code + <CR> + ```
<CR>
означает "возврат каретки" (Carriage Return)Да, протупил. Но вот сейчас вроде все сделал как надо, а не работает.
test
а так получаетсяА вот с Markdown разметкой что-то не задалось. Кто знает, можно переделать это "как надо"?