Search code examples
androiddelphifiremonkey

Delphi android create action bar


SITUATION

I am creating an app for a customer and my boss told me to add an action bar with a button that displays some other things. This screenshot will clarify:

enter image description here

The dark green bar above with (and the white text) is a TLayout aligned at Top with a ColorBox. On the right you can see that I have a button and, when you click on it, you see a TListBox with some options. When the user clicks on them, an action is performed.


PROBLEM

The TListBox is not visible when the form creates. When you click on the button the box appears thanks to this code:

procedure TForm1.ButtonMenuClick(Sender: TObject);
begin

 //oflowmen is the TListBox
 oflowmen.Visible := not oflowmen.Visible;
 if oflowmen.Visible then
 begin
  oflowmen.ApplyStyleLookup;
  oflowmen.RealignContent;
 end;

end;

This code works fine because when you click on the button, the TListBox appears/disappears, but this is not enough. I want my box to disappear in 2 ways:

  1. When I click again on the button (solution that I have implemented above)
  2. When I click somewhere in the screen (excluding the button of course)

How can I implement the second case?

Note: I put a screenshot of a 32 bit exe instead of a screenshot from my android test device, but it's the same thing.


Solution

  • yep, behavior of FMX components are different on different platform, this is not a secret.

    Alternative solution: use TComboBox -- it's already has behavior you need (click somewhere in the screen). See screen sample:

    enter image description here

    Answer on your question: change HitTest property to False for TListBox and for all other controls on your form and do control of MouseDown. Not good idea (Halloween solution).

    Code sample:

    unit Unit1;
    
    interface
    
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts, FMX.ListBox, FMX.StdCtrls,
      FMX.Controls.Presentation, FMX.TabControl;
    
    type
      TForm1 = class(TForm)
        ToolBar1: TToolBar;
        ToolBar2: TToolBar;
        Button1: TButton;
        ComboBox1: TComboBox;
        ListBox1: TListBox;
        Button2: TButton;
        TabControl1: TTabControl;
        TabItem1: TTabItem;
        TabItem2: TTabItem;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
      private
        FLIstBoxVisible: Boolean;
        procedure SetListBoxVisible(const Value: Boolean);
      public
        property ListBoxVisible: Boolean read FLIstBoxVisible write SetListBoxVisible;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ComboBox1.DropDown;
    end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      ListBoxVisible := True;
    end;
    
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
    begin
      if ListBoxVisible then
        ListBoxVisible := False;
    end;
    
    procedure TForm1.SetListBoxVisible(const Value: Boolean);
    var
      I: Integer;
    begin
      for I := 1 to Form1.ComponentCount - 1 do
        begin
          if Form1.Components[I] = ListBox1 then
            Continue;
    
          (Form1.Components[I] as TControl).HitTest := not Value;
    
          if Value then
            (Form1.Components[I] as TControl).OnMouseDown := FormMouseDown
          else
            (Form1.Components[I] as TControl).OnMouseDown := nil;
        end;
    
      if Value then
        ListBox1.RealignContent;
      FLIstBoxVisible := Value;
      ListBox1.Visible := Value;
    end;
    
    end.
    

    And form:

    object Form1: TForm1
      Left = 0
      Top = 0
      Caption = 'Form1'
      ClientHeight = 480
      ClientWidth = 640
      FormFactor.Width = 320
      FormFactor.Height = 480
      FormFactor.Devices = [Desktop]
      OnMouseDown = FormMouseDown
      DesignerMasterStyle = 0
      object ToolBar1: TToolBar
        Size.Width = 640.000000000000000000
        Size.Height = 40.000000000000000000
        Size.PlatformDefault = False
        TabOrder = 0
        object ToolBar2: TToolBar
          Size.Width = 640.000000000000000000
          Size.Height = 40.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 0
          object Button1: TButton
            Align = Left
            Size.Width = 80.000000000000000000
            Size.Height = 40.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 1
            Text = 'ComboBox'
            OnClick = Button1Click
          end
          object Button2: TButton
            Align = Right
            Position.X = 560.000000000000000000
            Size.Width = 80.000000000000000000
            Size.Height = 40.000000000000000000
            Size.PlatformDefault = False
            TabOrder = 0
            Text = 'ListBox'
            OnClick = Button2Click
          end
        end
        object ComboBox1: TComboBox
          Align = Left
          Items.Strings = (
            'item 1'
            'item 2'
            'item 3'
            'item 4'
            'item 5')
          Position.Y = 40.000000000000000000
          Size.Width = 640.000000000000000000
          Size.PlatformDefault = False
          TabOrder = 1
        end
      end
      object ListBox1: TListBox
        HitTest = False
        Position.X = 224.000000000000000000
        Position.Y = 128.000000000000000000
        TabOrder = 1
        Visible = False
        DisableFocusEffect = True
        Items.Strings = (
          'Item 1'
          'Item 2'
          'Item 3'
          'Item 4')
        DefaultItemStyles.ItemStyle = ''
        DefaultItemStyles.GroupHeaderStyle = ''
        DefaultItemStyles.GroupFooterStyle = ''
        Viewport.Width = 196.000000000000000000
        Viewport.Height = 196.000000000000000000
      end
      object TabControl1: TTabControl
        Align = Client
        Size.Width = 640.000000000000000000
        Size.Height = 440.000000000000000000
        Size.PlatformDefault = False
        TabIndex = 0
        TabOrder = 2
        TabPosition = PlatformDefault
        object TabItem1: TTabItem
          CustomIcon = <
            item
            end>
          IsSelected = True
          Size.Width = 70.000000000000000000
          Size.Height = 26.000000000000000000
          Size.PlatformDefault = False
          StyleLookup = ''
          TabOrder = 0
          Text = 'TabItem1'
          OnMouseDown = FormMouseDown
        end
        object TabItem2: TTabItem
          CustomIcon = <
            item
            end>
          IsSelected = False
          Size.Width = 70.000000000000000000
          Size.Height = 26.000000000000000000
          Size.PlatformDefault = False
          StyleLookup = ''
          TabOrder = 0
          Text = 'TabItem2'
          OnMouseDown = FormMouseDown
        end
      end
    end
    

    Tested on DX10 (without Update 1) and Android 5.1.1