Watch, Follow, &
Connect with Us

Embarcadero Blogs

Latest Posts


VCL and FireMonkey UI Styling - Join me at CodeRage next week

I am doing 4 sessions next week at CodeRage 9. Two on Bluetooth and BaaS (Backend-as-a-Service) and two on multi-device development using FireUI and our new MultiView component.

As part of my multi-device session, I am also going to cover application styling across both VCL and FireMonkey apps. For example, you can apply custom styles such as our premium styles that are part of our bonus pack offering to both your existing VCL apps and companion mobile apps (like in the tethered app example below). This allows you to give your VCL apps and mobile apps a matching custom look.

Style shown: Emerald Dark for VCL and FireMonkey

CodeRage 9


posted @ Thu, 23 Oct 2014 20:38:54 +0000 by sarinadupont


Bjarne Stroustrup "Make Simple Tasks Simple!" at CodeRage 9 - Wednesday, Oct. 29: 9-11am PDT

It is again my pleasure, once again, to announce that Bjarne Stroustrup will take part in the upcoming CodeRage 9 free online virtual developer conference next week. Bjarne last took part our CodeRage 7 C++ conference, "A Conversation with the C++ language designer and original implementer, Bjarne Stroustrup" back in November 2012.

This time we will be doing things a little bit differently. We will watch a replay of Bjarne’s wonderful CppCon 2014 Keynote, "Make Simple Tasks Simple!", and then have a live Q&A with Bjarne to complete the 2 hour session.

Bjarne’s session, "Make Simple Things Simple!" will take place on Wednesday, October 29 from 9am to 11am Pacific Time (12noon to 2pm Eastern Time) on the C++ track live stream.

Description from the CppCon 2014 site: "C++ faces two challenges: Helping programmers address the most demanding tasks in terms of performance, scale, and dependability. It must also help programmers be productive writing ordinary maintainable code. There is much more "ordinary code" than there is performance-critical code. Thus, C++ must make simple tasks simple while not getting in the way of tuning software for the last byte and last cycle where that’s necessary. This talk focuses on what C++11 and C++14 offers to simplify programming: auto, range-for loops, move semantics, futures, concepts, and more. However, the focus is not primarily on language features: the key is programming: how can we write better, more readable, efficient, and more maintainable code? If you think that the essence of C++ is clever pointer manipulation and huge class hierarchies you may be in for a few surprises."

Register for CodeRage 9 at http://forms.embarcadero.com/CodeRage9Registration.

You can submit questions live during the session or you can email questions in advance by sending them to davidi at embarcadero dot com using the subject line "Ask Bjarne during CodeRage 9".

REGISTER NOW FOR CODERAGE 9


posted @ Wed, 22 Oct 2014 16:36:09 +0000 by David Intersimone


Customizing VCL Styles with RAD Studio XE7

Delphi, C++Builder and RAD Studio include various VCL styles out of the box. These can be used for your Windows applications and customized via the included Bitmap Style Designer (Tools->Bitmap Style Designer). You can also create a new style from scratch. The easiest way to get started with a brand new style is to use the VCL style template in the Bitmap Style Designer as a guide. Below is a general outline of the steps required.

  • a) File->’New style for VCL or FireMonkey’ to start with a template
  • b) File->Open to select an existing .vsf style (i.e. Carbon.vsf or Auric.vsf) for editing
  • Expand the Images node and click on ’style.png’
  • Click ‘Export’ to export the png to a folder on your hard drive
  • Open the png with the graphics program of your choice. In my case, I used Photoshop
  • After you are done editing the style/creating a new style, select the style.png in the Style Designer, click update and select the updated png to replace the existing png
  • Select each style element, and create a selection outline for each bitmap associated with a specific Bitmap property (hot, pressed etc.) in the Inspector
  • Save the vsf style and apply it to your VCL application

In my case, I wanted to customize the CharcoalDarkSlate.vsf VCL style that can be found in C:\Users\Public\Documents\RAD Studio\15.0\Styles

I opened the png in Photoshop. You can design several states for each graphic via the Bitmap property in the Inspector, i.e. Bitmap, BitmapHot, BitmapPressed, BitmapFocused etc.. In my example, I decided to change the style of the system close button from a dark circle to a blue square.

After creating the new shapes in Photoshop, I pasted them into the style.png. You can just place them over the existing circular buttons and cover them, or remove those from the graphic beforehand. We are going to select an outline for each button later on, so either approach works. Key is to keep the transparency of the style.png file.

I also update the style of the trackbar to a brown/wooden theme.

After completing the style changes, I saved my new style.png file, went back to the style in the Style Designer and clicked on Update. I then browsed to the location of my new style, selected it and clicked OK.

To make sure the new close buttons are properly mapped, expand the Objects-Form node until you have the sysButtons-btnClose node selected:

In the Inspector, select the … next to Bitmap. The Bitmap Property Editor appears. This editor allows you to select the outline of your clickable button. Click to select the left top corner of the button via a simple mouse click. Then, to select the bottom right corner (to create the entire outline), control-click onto the bottom right of the square button. Repeat this process for each of the Bitmap options in the Object Inspector for the selected style element.

When you are done, click ‘Save’ and preview your style in the VCL Style Viewer by clicking F9 in the Bitmap Style Designer.

Below is an example of what the Trackbar styling looks like.

To be able to utilize this style in your VCL applications, place the .vsf file into C:\Users\Public\Documents\RAD Studio\12.0\Styles

As my final step, I created a new VCL application in the IDE and placed the Trackbar component onto my form. Via Project->Options->Application->Appearance, I selected my custom style from the list, and also made sure it was selected as the ‘Default Style’ in the drop-down menu and clicked OK to select the style.

In order to see the style, you will need to run your application since VCL styles are shown at runtime.


posted @ Wed, 22 Oct 2014 17:34:43 +0000 by sarinadupont


Displaying Cloud Based Data with A to Z ListView Headers

With TListView and LiveBindings, it is easy to display cloud based data in a sorted manner using listview headers.

Working with sorted data

If the data is already sorted, i.e. we have two columns, one for recipe title and one for the food category, you can just bind ‘Category’ into ItemHeader.Text to display food category headers for each of the recipes. This displays each recipe under its category header.

In the Structure pane, under ListView1-LiveBindings-LinkListControlToField1, you can further customize the style of your header.

Select your ItemHeader.Text to Category binding in the LiveBindingsDesigner, and then in the Object Inspector, toggle between the three FillHeaderCustomFormat options.

The application consists of the following components:
User Interface
  • TListView, aligned to the client
  • TToolbar, aligned to the toolbar
  • TLabel, aligned to Contents and parented to TToolbar
  • TStyleBook (displaying premium EmeraldDark style)
BaaS
  • TBackendQuery (for querying existing data that lives in the cloud and was added via the BaaS web interface)
  • TKinveyProvider (AppKey, AppSecret and MasterSecret have been set; you can also use TApp42Provider and TParseProvider)
  • TRestResponseDataSetAdapter
  • TFDMemTable
If you wanted to alphabetically sort the recipes in the list without displaying them in a grouped fashion under category headers, you could bind both Item.Text and ItemHeader.Text into FDMemTable1 - RecipeTitle. Then set FillHeaderCustomFormat to SubString(%s, 0, 1).

posted @ Tue, 21 Oct 2014 18:33:25 +0000 by sarinadupont


Creating a Bluetooth LE cloud enabled luggage scale application

Every time I travel somewhere, I am concerned that my luggage might exceed the weight limit. With RAD Studio XE7 and the Wahoo Bluetooth Scale, I built a luggage scale application that allows me to weigh my luggage and store data about my luggage contents in the cloud.

The app UI consists of a TTabControl with 3 tabs:

  • WeightScale - for weighing my luggage and saving the weight and associated notes
  • Logged Data - for retrieving existing luggage data and displaying it in a list
  • Settings - for displaying my bluetooth data

In addition to the various UI components, the app also contains a TBluetoothLE component, a TStyleBook component (for loading and assigning my custom Jet style) and the following BaaS components:

  • TKinveyProvider (AppKey, AppSecret and MasterSecret match my Kinvey.com credentials)
  • TBackendQuery (connected to TKinveyProvider)
  • TBackendStorage (connected to TKinveyProvider)
  • TRestResponseDataSetAdapter
  • TFDMemTable

The scale I am working with is the Wahoo Balance scale.

Here is the Object Pascal code for my application:

unit WeightScaleForm1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Ani, FMX.StdCtrls, System.Bluetooth, FMX.Layouts,
  FMX.Memo, FMX.Controls.Presentation, FMX.Edit, FMX.Objects, IPPeerClient, IPPeerServer,
  System.Tether.Manager, System.Bluetooth.Components, FMX.TabControl,
  REST.Backend.ServiceTypes, REST.Backend.MetaTypes, System.JSON,
  REST.Backend.KinveyServices, REST.OpenSSL, REST.Backend.KinveyProvider,
  REST.Backend.Providers, REST.Backend.ServiceComponents, FMX.ListView.Types,
  Data.Bind.Components, Data.Bind.ObjectScope, REST.Backend.BindSource,
  FMX.ListView, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  REST.Response.Adapter, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client,
  System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.EngExt,
  Fmx.Bind.DBEngExt, Data.Bind.DBScope;

type

  TSensorContactStatus = (NonSupported, NonDetected, Detected);

  THRMFlags = record
    HRValue16bits: boolean;
    SensorContactStatus: TSensorContactStatus;
    EnergyExpended: boolean;
    RRInterval: boolean;
  end;

  TfrmWeightMonitor = class(TForm)
    BluetoothLE1: TBluetoothLE;
    TabControl1: TTabControl;
    WeightScale: TTabItem;
    History: TTabItem;
    Panel1: TPanel;
    Memo1: TMemo;
    Panel2: TPanel;
    btnConnect: TButton;
    lblDevice: TLabel;
    lblWeight: TLabel;
    btnDisconnect: TButton;
    Settings: TTabItem;
    ToolBar1: TToolBar;
    Label1: TLabel;
    ToolBar2: TToolBar;
    ToolBar3: TToolBar;
    Label3: TLabel;
    btnSave: TButton;
    KinveyProvider1: TKinveyProvider;
    BackendStorage1: TBackendStorage;
    AppTitle: TLabel;
    title: TLabel;
    lbs: TLabel;
    ListView1: TListView;
    BackendQuery1: TBackendQuery;
    FDMemTable1: TFDMemTable;
    RESTResponseDataSetAdapter1: TRESTResponseDataSetAdapter;
    FDMemTable1_id: TWideStringField;
    FDMemTable1Weight: TWideStringField;
    FDMemTable1_acl: TWideStringField;
    FDMemTable1_kmd: TWideStringField;
    BindSourceDB1: TBindSourceDB;
    BindingsList1: TBindingsList;
    LinkListControlToField1: TLinkListControlToField;
    FDMemTable1LuggageDetails: TWideStringField;
    ImageControl1: TImageControl;
    StyleBook1: TStyleBook;
    Image1: TImage;
    procedure btnConnectClick(Sender: TObject);
    procedure BluetoothLE1EndDiscoverDevices(const Sender: TObject; const ADeviceList: TBluetoothLEDeviceList);
    procedure BluetoothLE1CharacteristicRead(const Sender: TObject; const ACharacteristic: TBluetoothGattCharacteristic;
      AGattStatus: TBluetoothGattStatus);
    procedure btnDisconnectClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure LinkListControlToField1FilledListItem(Sender: TObject;
      const AEditor: IBindListEditorItem);
    procedure FormCreate(Sender: TObject);
    procedure HistoryClick(Sender: TObject);
  private
    { Private declarations }
    FBLEDevice: TBluetoothLEDevice;
    FWeightGattService: TBluetoothGattService;
    FWeightMeasurementGattCharacteristic: TBluetoothGattCharacteristic;
    procedure GetServiceAndCharacteristics;
  public
    { Public declarations }
  end;

const
  ScaleDeviceName = 'Wahoo Scale';
  ServiceUUID = '';
  CharactUUID = '';

  // 0x1901 is the weight service
  // 0x2B01 is the live weight characteristic readings    0x84ae0000 0001      - 38 lbs   17kg
  // 0b 10000100101011100000000000000000

  Weight_Device: TBluetoothUUID = '{00001901-0000-1000-8000-00805F9B34FB}';
  Weight_Service: TBluetoothUUID = '{00001901-0000-1000-8000-00805F9B34FB}';
  Weight_Characteristic: TBluetoothUUID  = '{00002B01-0000-1000-8000-00805F9B34FB}';

var
  frmWeightMonitor: TfrmWeightMonitor;

implementation

{$R *.fmx}
{$R *.iPhone4in.fmx IOS}

procedure TfrmWeightMonitor.btnConnectClick(Sender: TObject);
begin
  lblWeight.Text := '0';
  lblDevice.Text := '';
  Memo1.Lines.Clear;
  BluetoothLE1.DiscoverDevices(3500, [Weight_Device]);
end;

procedure TfrmWeightMonitor.btnDisconnectClick(Sender: TObject);
begin
If FBLEDevice <> nil then
  BluetoothLE1.UnSubscribeToCharacteristic(FBLEDevice, FWeightMeasurementGattCharacteristic);
  btnDisconnect.Enabled := false;  // disable disconnect from subscribe scale button
  btnConnect.Enabled := true;  // enable connect to scale button
end;

//store luggage notes in the cloud
procedure TfrmWeightMonitor.btnSaveClick(Sender: TObject);
var
  LJSON : TJSONObject;
  ACreatedObject: TBackendEntityValue;
  luggagedetails	: string;
begin
    LJSON := TJSONObject.Create;
if InputQuery('Luggage BaaS Cloud Store', 'Enter Notes about your Luggage', luggagedetails)
 then
     LJSON.AddPair('Weight', lblWeight.Text);
     LJSON.AddPair('LuggageDetails', luggagedetails);
     BackendStorage1.Storage.CreateObject('luggagecloud', LJSON, ACreatedObject);
     ShowMessage('Luggage weight and notes stored');
end;

procedure TfrmWeightMonitor.FormCreate(Sender: TObject);
begin
  BackendQuery1.Execute;
end;

procedure TfrmWeightMonitor.BluetoothLE1EndDiscoverDevices(const Sender: TObject;
  const ADeviceList: TBluetoothLEDeviceList);
var
  I: Integer;
begin
  // log
  Memo1.Lines.Add(ADeviceList.Count.ToString +  ' devices discovered:');
  for I := 0 to ADeviceList.Count - 1 do Memo1.Lines.Add(ADeviceList[I].DeviceName);

  if BluetoothLE1.DiscoveredDevices.Count > 0 then
  begin
    FBLEDevice := BluetoothLE1.DiscoveredDevices.First;
    ShowMessage('Connected to Wahoo Scale');
    if BluetoothLE1.GetServices(FBLEDevice).Count = 0 then
    begin
      Memo1.Lines.Add('No Weight services found!');
      lblWeight.Text := 'No Weight services found!';
    end
    else begin
      Memo1.Lines.Add('Wahoo Services Found: '+ IntToStr(BluetoothLE1.GetServices(FBLEDevice).Count));
      btnDisconnect.Enabled := true;  // enable disconnect from subscribe scale button
      btnConnect.Enabled := false;  //disable connect to scale button
      // get Weight Service and Characteristic
      GetServiceAndCharacteristics;
    end;
  end
  else
    lblDevice.Text := 'Weight Device not found';
end;

procedure TfrmWeightMonitor.GetServiceAndCharacteristics;
begin
  FWeightGattService := nil;
  FWeightMeasurementGattCharacteristic := nil;
  // get Weight Service by UUID
  FWeightGattService := BluetoothLE1.GetService(FBLEDevice, Weight_SERVICE);

  if FWeightGattService <> nil then begin
    memo1.Lines.Add('Service: '+FWeightGattService.UUID.ToString);
    // get Weight Characteristic
    Memo1.Lines.Add('Looking Char: '+Weight_CHARACTERISTIC.ToString);
    BluetoothLE1.GetCharacteristics(FWeightGattService);
    FWeightMeasurementGattCharacteristic := BluetoothLE1.GetCharacteristic(FWeightGattService,Weight_CHARACTERISTIC);

    if FWeightMeasurementGattCharacteristic <> nil then begin
      Memo1.Lines.Add('Char: '+FWeightMeasurementGattCharacteristic.UUID.ToString);
      // subscribe to the weight service
      BluetoothLE1.SubscribeToCharacteristic(FBLEDevice, FWeightMeasurementGattCharacteristic);
      Memo1.Lines.Add('Subscribed to Weight Measurement Characteristic');
    end
    else begin
      Memo1.Lines.Add('Weight Char not found');
      lblWeight.Text := 'Weight Char not found';
    end
  end
  else begin
    Memo1.Lines.Add('Weight Service not found');
    lblWeight.Text := 'Weight Service not found';
  end;
end;

//query BaaS provider for existing luggage data
procedure TfrmWeightMonitor.HistoryClick(Sender: TObject);
begin
  BackendQuery1.Execute;
end;

//display weight icon next to each row in TListview
procedure TfrmWeightMonitor.LinkListControlToField1FilledListItem(
  Sender: TObject; const AEditor: IBindListEditorItem);
var
  LItem: TListViewItem;
begin
  LItem := AEditor.CurrentObject As TListViewItem;
  LItem.BitmapRef := ImageControl1.Bitmap;
end;

procedure TfrmWeightMonitor.BluetoothLE1CharacteristicRead(const Sender: TObject;
  const ACharacteristic: TBluetoothGattCharacteristic; AGattStatus: TBluetoothGattStatus);
var
  LSValue: string;
  HexValue: string;
  WeightPounds : double;
begin
  if AGattStatus <> TBluetoothGattStatus.Success then
    Memo1.Lines.Add('Error reading Characteristic ' + ACharacteristic.UUIDName + ': ' + Ord(AGattStatus).ToString)
  else
  begin
    LSValue := IntToStr(ACharacteristic.GetValueAsInteger);
    Memo1.Lines.Add(ACharacteristic.UUID.ToString + ' String: ' + LSValue);
    // calculate weight - characteristic is in hectograms
    WeightPounds := (ACharacteristic.GetValueAsInteger shr 8) * 0.2205;
    Memo1.Lines.Add('Weight (pounds): '+Format('%8.2f',[WeightPounds]));
    lblWeight.Text := Format('%8.2f',[WeightPounds]);
  end;
end;

end.


posted @ Mon, 20 Oct 2014 23:49:14 +0000 by sarinadupont


Reserve your space: CodeRage 9 - the Delphi developer event of the year

CodeRage 9 - The totally technical online conference for Delphi, C++Builder and RAD Studio dedvelopers is just around the corner. The free online conference will be taking place October 28-30.


Join us for CodeRage® 9, the totally free, totally technical online conference for software developers. This year's conference brings you top industry speakers and technologists presenting on a wide variety of topics, all geared toward maximizing your software development productivity. 
The theme for this year's CodeRage conference is "You are the Developers of Things, Everything!" The conference will cover development topics for the Object Pascal and C++ programming languages with Delphi, C++Builder, RAD Studio and Appmethod. The conference will have two live stream tracks – one for Object Pascal and one for C++.


posted @ Fri, 17 Oct 2014 16:50:00 +0000 by Tim Del Chiaro


Mac OS X Yosemite Style Pack for RAD Studio XE7

Yesterday, Apple released Mac OS X Yosemite.

We have a new Yosemite style pack available for RAD Studio XE7 users that includes both a blue and a dark style. The blue style is the default Yosemite style, and the dark style is designed for Yosemite’s dark (graphite) mode.

You can get both styles and the sample project by going to: http://cc.embarcadero.com/item/30025

Here are the steps to add Yosemite styling support to your project:

1. Place TStyleBook onto the Master view
2. Set TStyleBook.Name = "YosemiteStyleBook"
3. Load Yosemite.fsf or YosemiteDark.fsf to YosemiteStyleBook
4. Use the TForm.OnCreate event and add this code:

procedure TForm1.FormCreate(Sender: TObject);
begin
  {$IFDEF MACOS}
  if (TOSVersion.Major = 10) and (TOSVersion.Minor = 10) then
     Form1.StyleBook := YosemiteStyleBook;
  {$ENDIF}
end;


posted @ Fri, 17 Oct 2014 19:50:26 +0000 by sarinadupont


iOS 8 App Store Hotfix

Hi,

A couple of days ago we released a hotfix for submitting iOS 8 applications to the Apple App Store.

This RAD Studio hotfix enables deployment of Delphi and C++ iOS applications to the Apple App Store.

It applies to RAD Studio XE5, XE6 and XE7.

You can get the hofix by going to: http://cc.embarcadero.com/item/30022

Regards,

Sarina


posted @ Fri, 17 Oct 2014 17:40:36 +0000 by sarinadupont


Mobile User Interface Design: Home Screen Navigation

Written by Sarina D.

When it comes to mobile UI design, there are several key design paradigms. I covered the different mobile UI design patterns in my recent C++ Mobile Day session.

App Home Screen Navigation Key Features
• Images arranged in a grid like layout
• Images can be annotated with text
• May span over multiple screens (you can use a TTabControl for that)
To create the user interface shown in the screenshot above, you will first need to create a new mobile application. Add a TToolbar, align it to the Top, and parent a TLabel to it. Next, drop a TGridPanelLayout component onto your form and align it to the client. By default, two columns (0,1) and two rows (0,1) are set up.
Note: Since you are going to set up event handlers for each graphic on the home screen, I would recommend adding a TTabControl (aligned to Client) with 11 invisible tabs (TabPosition = tpNone). Then add the Toolbar and GridPanelLayout components to Tab1, and link to each of the tabs when the user taps on one of the 10 home screen graphics by setting up on-click events for each graphic.

Define the width of each column, i.e. 50% to have even spacing across both columns.
For this sample application, we want to have a total of two columns with five rows. To add a row, right click on ‘RowCollection’ and add an item.
Each of the five rows should have a value of 20% to ensure even spacing across our grid.
Next, drop a total of 10 TImageControls onto your form. You could also use TImage if you want to load different images for different device resolutions (i.e. 1x resolution image, 2x resolution image etc.).Multi-select (shift select) all TImageControls in the Structure pane and change the width and height to 75 px. This ensures spacing between each of the graphics.
Select each TImageControl and select the row and column you want it to be displayed.

Last step is to add the images you want to display and setup on-click events for each graphic to navigate the user to the related content.


posted @ Mon, 13 Oct 2014 23:43:04 +0000 by J T


Creating a Navigation Drawer for your Mobile Application

Written by Sarina D.

Recently, I covered key menu styles that are used in mobile applications today. Drawer menus are very popular, as they allow you to take advantage of more screen real estate when building your app. The main application menu is hidden by default, and invoked by tapping on a menu item or swiping left/right. This type of UI can be seen in many popular mobile applications, including Facebook, Youtube and Gmail.

In this tutorial, I will cover the steps needed to create a navigation drawer for your Appmethod mobile apps.

Many thanks to Malcolm Groves who created the drawer sample that I am using and expanding for this blog post. You can download the project source from his Github repository.

This application consists of 2 layouts. One layout containing the drawer content, and one containing the main application content.

In this case, my left menu, the drawer menu, includes a top aligned toolbar with a parented label, and a client aligned Listbox with several menu items in it. The idea here is that the drawer menu contains all the main application navigation, including quick links to my account profile, app settings etc.

For demo purposes, I dropped a TListView component onto my form, parented it to lytMain and set its alignment property to alClient. I also placed a TPrototypeBindsource component onto my form to fill my TListview with some sample data. Right-clicking on the PrototypeBindSource component provides you with sample data that you can then easily bind into your Listview using the LiveBindings Designer. I also parented a TLine to lytMain to make the division between the main layout and navigation drawer more visible. You could also apply a style or use a separate background color.

If you double click on the Actionlist component on the form, you can see that we setup a custom action. We are leveraging that action for opening/closing the drawer when the user clicks on the drawer menu (three line) button or when they swipe across the main menu layout.

procedure TfrmMain.actOpenDrawerExecute(Sender: TObject);
begin
  DrawerVisible := not DrawerVisible;
end;

procedure TfrmMain.actOpenDrawerUpdate(Sender: TObject);
begin
  actOpenDrawer.Visible := not (IsPad and IsLandscape);
end;

On the form, we also placed the Gesture Manager component since we want the user to be able to swipe across the screen to show/hide the navigation drawer. In the project source, you will see that the touch gestures are setup for the toolbar parented to lytMain. In my demo, I removed the gesture that was setup on the toolbar and instead assigned the touch gesture to lytMain.

You can find the source code for this project in Malcolm Groves’ Github repository. Below is a quick video that shows my running application.


posted @ Mon, 13 Oct 2014 23:42:32 +0000 by J T


Server Response from: BLOGS1