В общем случае располагаете три контейнера (тип - на ваше усмотрение, что больше нравится, например ListView или ScrollBox с вложенными кнопками) с Align := TAlignLayout.Left
- самый левый это зона с флагами
- средний элементы супы/напитки/т.д., устанавливаете начальную ширину 0 и добавляете анимацию для ширины
- правый это элементы рассольник/еще суп/т.д., устанавливаете начальную ширину 0 и добавляете анимацию для ширины
Далее, при нажатии на флаг в левом контейнере запускаете анимацию увеличения ширины среднего контейнера (перед этим заполняете средний контейнер нужными элементами меню). Получаете эффект раскрытия. При повторном нажатии на флаг инвертируете анимацию и запускаете, получаете эффект скрытия
Аналогично для правого контейнера.
Понятно, что нужно будет реализовать аналогичную логику динамического формирования элементов, а также скрытия правого контейнера при скрытии среднего, но думаю, что общая идея реализации вашей задачи понятна.
Обе версии и 32 и 64 бит должны быть в одном пакете apk или aab. Если версия делфи 10.4.2, то можно попробовать попробовать бангл создать, но сам я не проверял, работает ли он сейчас. В версиях раньше, это работало плохо (версия 32 бит, все равно не запускалась на некоторых устройствах). Можно еще вручную добавить 32 битный so файл в 64 apk. Подробнее об этом написано здесь:
И ниже пост, чуть попроще но суть та же самая.
Я делаю так:
1.Создаю файл базы (БД) например для Виндовс Acces (пример моего в приложении).
2.Создаю файл TreeView.dat.
3.Подключаюсь к БД.
4.Создаю нове ветки так:
//Ввести ветку
procedure TForm_Glavn.SpeedButton_vvod_vetkiClick(Sender: TObject);
begin
//проверка наличия текста в Едите
if Edit_Mame_Vetok.Text = '' then
begin
MessageDl.MessageDlg('Вы не ввели название ветки!', mtInformation,[mbYes],0);
Abort;
end;
TreeView1.Items. Add (TreeView1. Selected, Edit_Mame_Vetok.Text) ;
//база
Query_Glav.Insert;
Query_Glav.FieldByName('Dat').AsString:=DateToStr(Now);
Query_Glav.FieldByName('Imya_vetok').AsString:=Edit_Mame_Vetok.Text;
Query_Glav.FieldByName('Opisanie').AsString:=Memo_opisanie.Text;
Query_Glav.Post;
//сохраняем дерево
F := TFileStream.Create(Base+'\Data\TreeView.dat', fmCreate or fmShareCompat);
try
F.WriteComponent(TreeView1);
finally
F.Free;
end;
Edit_Mame_Vetok.Text:='';
end;
5.Создаю подветки так:
//Ввести подветку
procedure TForm_Glavn.SpeedButton_vvod_podvetkiClick(Sender: TObject);
begin
if TreeView1.Selected = nil then
begin
MessageDl.MessageDlg('Вы не выбрали в какой ветке делаем подветку!', mtInformation,[mbYes],0);
Exit; //если не выбрана ветка выходим
end;
//проверка наличия текста в Едите
if Edit_Mame_Vetok.Text = '' then
begin
MessageDl.MessageDlg('Вы не ввели название ветки!', mtInformation,[mbYes],0);
Abort;
end;
TreeView1.Items.AddChild (TreeView1. Selected, Edit_Mame_Vetok.Text);
//база
Query_Glav.Insert;
Query_Glav.FieldByName('Dat').AsString:=DateToStr(Now);
Query_Glav.FieldByName('Imya_vetok').AsString:=Edit_Mame_Vetok.Text;
Query_Glav.FieldByName('Opisanie').AsString:=Memo_opisanie.Text;
Query_Glav.Post;
//сохраняем дерево
F := TFileStream.Create(Base+'\Data\TreeView.dat', fmCreate or fmShareCompat);
try
F.WriteComponent(TreeView1);
finally
F.Free;
end;
Edit_Mame_Vetok.Text:='';
end;
6.Прикрепляю файл так:
// Прикрепить файл
procedure TForm_Glavn.SpeedButton_FileClick(Sender: TObject);
var
IconStream:TMemoryStream;
begin
if TreeView1.Selected = nil then
begin
MessageDl.MessageDlg('Вы не выбрали в какой ветке делаем подветку!', mtInformation,[mbYes],0);
Exit; //если не выбрана ветка выходим
end;
OpenDialog1.InitialDir:=Base;
if Opendialog1.Execute then
begin
//заносим файл в потоке
SpeedButton_File.Caption:='Подождите......';
Application.ProcessMessages;
IconStream:=TMemoryStream.Create;
IconStream.LoadFromFile(OpenDialog1.FileName);
//становимся в невидимой таблице на указанной модели
Query_Glav.Locate('Imya_vetok',Edit_Mame_Vetok.Text,[loPartialKey, loCaseInsensitive]);
Query_Glav.Edit;
if (ExtractFileExt(Opendialog1.FileName) = '.pdf')then Query_Glav.FieldByName('RashirenieFile').AsInteger:=3;
if (ExtractFileExt(Opendialog1.FileName) = '.docx')then Query_Glav.FieldByName('RashirenieFile').AsInteger:=2;
if (ExtractFileExt(Opendialog1.FileName) = '.jpg')then Query_Glav.FieldByName('RashirenieFile').AsInteger:=0;
if (ExtractFileExt(Opendialog1.FileName) = '.rar')then Query_Glav.FieldByName('RashirenieFile').AsInteger:=1;
(Query_Glav.FieldByName('File') as TBlobField).LoadFromStream(IconStream);
IconStream.Free;
Application.ProcessMessages;
MessageDl.MessageDlg('Файл добавлен в базу!', mtInformation,[mbYes],0);
SpeedButton_File.Caption:=' Прикрепить файл';
end else MessageDl.MessageDlg('Ошибка ввода!', mtInformation,[mbYes],0);
end;
7. Удаляю ветку или подветку так:
//Удалить ветку/ подветку
procedure TForm_Glavn.SpeedButton_DeleteClick(Sender: TObject);
begin
if TreeView1.Items.Count = 0 then //проверка наличия веток вообще
begin
MessageDl.MessageDlg('Так нет же веток!', mtInformation,[mbYes],0);
Abort;
end;
if TreeView1.Selected.HasChildren=True then //проверка наличия подветки
begin
MessageDl.MessageDlg('Сначала удалите подветку!', mtInformation,[mbYes],0);
Image1.Refresh;
Abort;
end;
if TreeView1.Selected.HasChildren=False then //проверка наличия подветки
begin
SpeedButton_Delete.Caption:='Подождите.....';
Application.ProcessMessages;
//становимся в невидимой таблице на указанной ветке
Query_Glav.Locate('Imya_vetok',TreeView1.Selected.Text,[loPartialKey, loCaseInsensitive]);
if Query_Glav.FieldByName('Imya_vetok').AsString <> '' then Query_Glav.Delete;//удаляем в базе
Application.ProcessMessages;
TreeView1.Items.Delete(TreeView1.Selected); //удаляем в дереве
Application.ProcessMessages;
Image1.Refresh;
Application.ProcessMessages;
SpeedButton_Delete.Caption:=' Удалить ветку/ подветку';
end;
//сохраняем дерево
F := TFileStream.Create(Base+'\Data\TreeView.dat', fmCreate or fmShareCompat);
try
F.WriteComponent(TreeView1);
finally
F.Free;
end;
Edit_Mame_Vetok.Text:='';
end;
8. Переименовываю ветки так:
//Переименовать ветку/ подветку
procedure TForm_Glavn.SpeedButton3Click(Sender: TObject);
begin
//проверка наличия текста в Едите
if Edit_Mame_Vetok.Text = '' then
begin
MessageDl.MessageDlg('Вы не ввели название ветки!', mtInformation,[mbYes],0);
Abort;
end;
//становимся в невидимой таблице на указанной модели
Query_Glav.Locate('Imya_vetok',TreeView1.Selected.Text,[loPartialKey, loCaseInsensitive]);
TreeView1.Selected.Text:=Edit_Mame_Vetok.Text;
//база
Query_Glav.Edit;
Query_Glav.FieldByName('Dat').AsString:=DateToStr(Now);
Query_Glav.FieldByName('Imya_vetok').AsString:=Edit_Mame_Vetok.Text;
Query_Glav.FieldByName('Opisanie').AsString:=Memo_opisanie.Text;
Query_Glav.Post;
//сохраняем дерево
F := TFileStream.Create(Base+'\Data\TreeView.dat', fmCreate or fmShareCompat);
try
F.WriteComponent(TreeView1);
finally
F.Free;
end;
Edit_Mame_Vetok.Text:='';
end;
9.Открываю прикреплённый файл так:
// Открыть прикреплённый файл отдельно
procedure TForm_Glavn.SpeedButton4Click(Sender: TObject);
var
ImageData:TMemoryStream;
begin
if TreeView1.Selected = nil then
begin
MessageDl.MessageDlg('Вы не выбрали в какой ветке делаем подветку!', mtInformation,[mbYes],0);
Exit; //если не выбрана ветка выходим
end;
//становимся в невидимой таблице на указанной модели
Query_Glav.Locate('Imya_vetok',Edit_Mame_Vetok.Text,[loPartialKey, loCaseInsensitive]);
ImageData:=TMemoryStream.Create;
(Query_Glav.FieldByName('File') as TBlobField).SaveToStream(ImageData);
ImageData.Position:=0;
if ImageData.Size<>0 then
begin
if Query_Glav.FieldByName('RashirenieFile').AsInteger=3 then Path:=Base+'\Temp\Dokument.pdf';
if Query_Glav.FieldByName('RashirenieFile').AsInteger=2 then Path:=Base+'\Temp\Dokument.docx';
if Query_Glav.FieldByName('RashirenieFile').AsInteger=0 then Path:=Base+'\Temp\Dokument.jpg';
if Query_Glav.FieldByName('RashirenieFile').AsInteger=1 then Path:=Base+'\Temp\Dokument.rar';
ImageData.SaveToFile(Path);
ImageData.Free;
ImageData:=nil;
if FileExists(Path) then
begin
ShellExecute (0, 'open', pChar(Path), nil, nil, SW_SHOW);
end else
MessageDl.MessageDlg('Файл'+Path+' в папке Data не найден.', mtInformation,[mbYes],0);
end else
MessageDl.MessageDlg('В этой ветке документа нет.', mtInformation,[mbYes],0);
end;