ALLOY WIDGETSImproving code re-use through a library of bespoke UI                    components.                     TiCo...
WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.
WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.•   Create a re-usa...
WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.•   Create a re-usa...
WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.•   Create a re-usa...
WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.•   Create a re-usa...
WHAT IS A WIDGET?App                         Widget             Multiple widgets in the same window...
WHAT IS A WIDGET?App                          Widget             ... or multiple instances of the same             widget
A CUSTOM TABLE VIEW WIDGETAn example of building a cross-platform widget that encapsulates commonfunctionality but utilise...
CREATING A WIDGETTo create a new widget, right click the project name in the Titanium Studioproject view... and select New...
CREATING A WIDGETTo create a new widget, right click the project name in the Titanium Studioproject view... and select New...
WIDGET FILE STRUCTUREA widgets folder is created with Controllers, Styles and Views sub-directories.Note the absence of Mo...
USING A WIDGETIn the main app, we will call the newly created widget using the “Require” tag.          App – index.xml    ...
USING A WIDGETIn the main app, we will call the newly created widget using the “Require” tag.          App – index.xml    ...
USING A WIDGETIn the main app, we will call the newly created widget using the “Require” tag.          App – index.xml    ...
STYLING          App – index.tss                Widget – widget.tss".container": {   backgroundColor:"white"},"#table1": {...
STYLING           App – index.tss                  Widget – widget.tss ".container": {    backgroundColor:"white" }, "#tab...
CONTROLLERS - INITIALISE           App – index.tss                   Widget – widget.js                                   ...
CONTROLLERS - INITIALISE           App – index.tss                   Widget – widget.js                                   ...
CONTROLLERS - INITIALISE           App – index.tss                     Widget – widget.js                                 ...
CONTROLLERS - INITIALISE           App – index.tss                     Widget – widget.js                                 ...
CONTROLLERS – CALLING FUNCTIONS           App – index.js                                Widget – widget.js$.index.open(); ...
CONTROLLERS – CALLING FUNCTIONS           App – index.js                                Widget – widget.js$.index.open(); ...
CONTROLLERS – CALLING FUNCTIONS           App – index.js                                Widget – widget.js$.index.open(); ...
CONTROLLERS – CALLING FUNCTIONS           App – index.js                                Widget – widget.js$.index.open(); ...
CONTROLLERS – HANDLING EVENTS             App – index.js                                 Widget – widget.js  $.table1.addE...
CONTROLLERS – HANDLING EVENTS             App – index.js                                 Widget – widget.js  $.table1.addE...
CONTROLLERS – HANDLING EVENTS             App – index.js                                 Widget – widget.js  $.table1.addE...
THANK YOU Source code: http://bit.ly/alloy-customTableViewSlideshare: http://bit.ly/alloy-customTableViewSlides           ...
Prochain SlideShare
Chargement dans…5
×

Creating Alloy Widgets

10 459 vues

Publié le

Create Alloy widgets using Titanium Appcelerator.

0 commentaire
16 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
10 459
Sur SlideShare
0
Issues des intégrations
0
Intégrations
280
Actions
Partages
0
Téléchargements
147
Commentaires
0
J’aime
16
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Creating Alloy Widgets

  1. 1. ALLOY WIDGETSImproving code re-use through a library of bespoke UI components. TiConf.eu Martin Hudson, Jonti Hudson February 2013
  2. 2. WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.
  3. 3. WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.• Create a re-usable library across multiple projects
  4. 4. WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.• Create a re-usable library across multiple projects• Create components that manage cross- platform differences (e.g. a table edit / delete component)
  5. 5. WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.• Create a re-usable library across multiple projects• Create components that manage cross- platform differences (e.g. a table edit / delete component)• Improve readability of code
  6. 6. WHAT IS A WIDGET?A self-contained bespoke UI component thatholds all the logic associated with its use.• Create a re-usable library across multiple projects• Create components that manage cross- platform differences (e.g. a table edit / delete component)• Improve readability of code• Improve reliability due to re-use of tested components.
  7. 7. WHAT IS A WIDGET?App Widget Multiple widgets in the same window...
  8. 8. WHAT IS A WIDGET?App Widget ... or multiple instances of the same widget
  9. 9. A CUSTOM TABLE VIEW WIDGETAn example of building a cross-platform widget that encapsulates commonfunctionality but utilises platform specific behaviour.
  10. 10. CREATING A WIDGETTo create a new widget, right click the project name in the Titanium Studioproject view... and select New → Alloy Widget.
  11. 11. CREATING A WIDGETTo create a new widget, right click the project name in the Titanium Studioproject view... and select New → Alloy Widget.Use a “Reverse domain” naming convention to ensure widget names are notreplicated when you share widgets with others.
  12. 12. WIDGET FILE STRUCTUREA widgets folder is created with Controllers, Styles and Views sub-directories.Note the absence of Models – this is because the main app should handledata storage
  13. 13. USING A WIDGETIn the main app, we will call the newly created widget using the “Require” tag. App – index.xml Widget – widget.xml <Alloy> <Alloy> <Window class="container"> <TableView id="table"></TableView> <Require type="widget" </Alloy> src="co.mobiledatasystems.customEditableTable" id="table1"> </Require> <Button id="btnEdit" title="Allow Editing" onClick="btnEdit_click_Event"> </Button> </Window> </Alloy>
  14. 14. USING A WIDGETIn the main app, we will call the newly created widget using the “Require” tag. App – index.xml Widget – widget.xml <Alloy> <Alloy> <Window class="container"> <TableView id="table"></TableView> <Require type="widget" </Alloy> src="co.mobiledatasystems.customEditableTable" id="table1"> </Require> <Button id="btnEdit" title="Allow Editing" onClick="btnEdit_click_Event"> </Button> </Window> </Alloy>Note we specify that we want a widget and reference the name of our newwidget. Alloy knows where to find it.
  15. 15. USING A WIDGETIn the main app, we will call the newly created widget using the “Require” tag. App – index.xml Widget – widget.xml <Alloy> <Alloy> <Window class="container"> <TableView id="table"></TableView> <Require type="widget" </Alloy> src="co.mobiledatasystems.customEditableTable" id="table1"> </Require> <Button id="btnEdit" title="Allow Editing" onClick="btnEdit_click_Event"> </Button> </Window> </Alloy> In the widget, we specify the UI components we want to expose. In our case it is only a TableView.
  16. 16. STYLING App – index.tss Widget – widget.tss".container": { backgroundColor:"white"},"#table1": { left: 10dp, right: 10dp, top: 20dp, bottom:80dp},"#btnEdit": { bottom:10dp, left:20dp, right:20dp, height:45dp}We have referenced our instance of thewidget “table1” in index.xml
  17. 17. STYLING App – index.tss Widget – widget.tss ".container": { backgroundColor:"white" }, "#table1": { left: 10dp, right: 10dp, top: 40dp, bottom:80dp }, "#btnEdit": { bottom:10dp, left:20dp, right:20dp, height:45dp }Note, where possible, do all the styling ofwidget components in the main app. Thisensures maximum re-usability across projects.
  18. 18. CONTROLLERS - INITIALISE App – index.tss Widget – widget.js //copy the arguments passed in to the widget via. ".container": { the xml and tss parameters backgroundColor:"white" }, var _args = arguments[0] || {}; "#table1": { var editable = null; left: 10dp, right: 10dp, if(OS_ANDROID){ top: 40dp, editable = false; bottom:80dp }; }, //get each element set in the widgets xml or tss "#btnEdit": { parameters bottom:10dp, left:20dp, Ti.API.info(JSON.stringify(_args)); right:20dp, height:45dp //iterate round all the parameters we have passed } in for (var key in _args) { if (_args.hasOwnProperty(key)) {In the widgets controller we can //checks key is a direct property of _args, notaccess all the parameters passed in somewhere down the object treeusing the arguments[] array. if(OS_ANDROID){ switch (key){
  19. 19. CONTROLLERS - INITIALISE App – index.tss Widget – widget.js //copy the arguments passed in to the widget via. ".container": { the xml and tss parameters backgroundColor:"white" }, var _args = arguments[0] || {}; "#table1": { var editable = null; left: 10dp, right: 10dp, if(OS_ANDROID){ top: 40dp, editable = false; bottom:80dp }; }, //get each element set in the widgets xml or tss "#btnEdit": { parameters bottom:10dp, left:20dp, Ti.API.info(JSON.stringify(_args)); right:20dp, height:45dp //iterate round all the parameters we have passed } in for (var key in _args) { if (_args.hasOwnProperty(key)) {In the widgets controller we can //checks key is a direct property of _args, notaccess all the parameters passed in somewhere down the object treeusing the arguments[] array. if(OS_ANDROID){ switch (key){
  20. 20. CONTROLLERS - INITIALISE App – index.tss Widget – widget.js //iterate round all the parameters we have passed ".container": { in backgroundColor:"white" }, for (var key in _args) { "#table1": { if (_args.hasOwnProperty(key)) { left: 10dp, right: 10dp, //checks key is a direct property of _args, not top: 40dp, somewhere down the object tree bottom:80dp }, if(OS_ANDROID){ "#btnEdit": { switch (key){ bottom:10dp, case editing: left:20dp, editable = _args[key]; right:20dp, break; height:45dp case moving: break; //android } doesnt recognise this property default:We can read each parameter passed in } $.table[key] = _args[key];and process them appropriately. In our } else { $.table[key] = _args[key];example “editable” and “moving” are }; };iOS specific. We will set a local };variable in the case of Android.
  21. 21. CONTROLLERS - INITIALISE App – index.tss Widget – widget.js //iterate round all the parameters we have passed ".container": { in backgroundColor:"white" }, for (var key in _args) { "#table1": { if (_args.hasOwnProperty(key)) { left: 10dp, right: 10dp, //checks key is a direct property of _args, not top: 40dp, somewhere down the object tree bottom:80dp }, if(OS_ANDROID){ "#btnEdit": { switch (key){ bottom:10dp, case editing: left:20dp, editable = _args[key]; right:20dp, break; height:45dp case moving: break; //android } doesnt recognise this property default:We can read each parameter passed in } $.table[key] = _args[key];and process them appropriately. In our } else { $.table[key] = _args[key];example “editable” and “moving” are }; };iOS specific. We will set a local };variable in the case of Android.
  22. 22. CONTROLLERS – CALLING FUNCTIONS App – index.js Widget – widget.js$.index.open(); //custom method we expose to set the tables datavar editMode = false; exports.setData = function(rows /*Ti.UI.Row*/){ $.table.setData(rows);//create some data to put in the table };var rows = [];for(var i=0;i<10;i++){ //custom method we expose to allow the table torows.push(Ti.UI.createTableViewRow({title:Row be editablenumber + i})); exports.editing = function(edit /*bool*/){}; if(OS_IOS){$.table1.setData(rows); //call the "setData" $.table.editing = edit; //allow rowmethod we created in the widget editing on iPhone & iPad } else {//toggle the "editable" mode of the table editable = edit;function btnEdit_click_Event(){ }; if(editMode){ }; $.btnEdit.title = "Allow Editing"; editMode = false; } else { Using the commonJS framework, we $.btnEdit.title = "Cancel Editing"; editMode = true; can expose functions in the widget. In }; $.table1.editing(editMode); //call the our example we expose “setData” so"editing" method we created in the widget}; we can populate the table after the widget has created it.
  23. 23. CONTROLLERS – CALLING FUNCTIONS App – index.js Widget – widget.js$.index.open(); //custom method we expose to set the tables datavar editMode = false; exports.setData = function(rows /*Ti.UI.Row*/){ $.table.setData(rows);//create some data to put in the table };var rows = [];for(var i=0;i<10;i++){ //custom method we expose to allow the table torows.push(Ti.UI.createTableViewRow({title:Row be editablenumber + i})); exports.editing = function(edit /*bool*/){}; if(OS_IOS){$.table1.setData(rows); //call the "setData" $.table.editing = edit; //allow rowmethod we created in the widget editing on iPhone & iPad } else {//toggle the "editable" mode of the table editable = edit;function btnEdit_click_Event(){ }; if(editMode){ }; $.btnEdit.title = "Allow Editing"; editMode = false; } else { Using the commonJS framework, we $.btnEdit.title = "Cancel Editing"; editMode = true; can expose functions in the widget. In }; $.table1.editing(editMode); //call the our example we expose “setData” so"editing" method we created in the widget}; we can populate the table after the widget has created it.
  24. 24. CONTROLLERS – CALLING FUNCTIONS App – index.js Widget – widget.js$.index.open(); //custom method we expose to set the tables datavar editMode = false; exports.setData = function(rows /*Ti.UI.Row*/){ $.table.setData(rows);//create some data to put in the table };var rows = [];for(var i=0;i<10;i++){ //custom method we expose to allow the table torows.push(Ti.UI.createTableViewRow({title:Row be editablenumber + i})); exports.editing = function(edit /*bool*/){}; if(OS_IOS){$.table1.setData(rows); //call the "setData" $.table.editing = edit; //allow rowmethod we created in the widget editing on iPhone & iPad } else {//toggle the "editable" mode of the table editable = edit;function btnEdit_click_Event(){ }; if(editMode){ }; $.btnEdit.title = "Allow Editing"; editMode = false; } else { $.btnEdit.title = "Cancel Editing"; editMode = true; Here, the main app is responding to a }; $.table1.editing(editMode); //call the button click event and changing the"editing" method we created in the widget}; editable state in the widget.
  25. 25. CONTROLLERS – CALLING FUNCTIONS App – index.js Widget – widget.js$.index.open(); //custom method we expose to set the tables datavar editMode = false; exports.setData = function(rows /*Ti.UI.Row*/){ $.table.setData(rows);//create some data to put in the table };var rows = [];for(var i=0;i<10;i++){ //custom method we expose to allow the table torows.push(Ti.UI.createTableViewRow({title:Row be editablenumber + i})); exports.editing = function(edit /*bool*/){}; if(OS_IOS){$.table1.setData(rows); //call the "setData" $.table.editing = edit; //allow rowmethod we created in the widget editing on iPhone & iPad } else {//toggle the "editable" mode of the table editable = edit;function btnEdit_click_Event(){ }; if(editMode){ }; $.btnEdit.title = "Allow Editing"; editMode = false; } else { $.btnEdit.title = "Cancel Editing"; editMode = true; Here, the main app is responding to a }; $.table1.editing(editMode); //call the button click event and changing the"editing" method we created in the widget}; editable state in the widget.
  26. 26. CONTROLLERS – HANDLING EVENTS App – index.js Widget – widget.js $.table1.addEventListener(delete, function(r){ //create a handlers object that will contain Ti.API.info(row deleted: + JSON.stringify(r)); references to functions var dialog = Ti.UI.createAlertDialog({ var handlers = {}; message: r.row.title, title: Deleted //assign some functions that do nothing. }); handlers.click = function(r){}; dialog.show(); handlers.deleteRow = function(r){}; }); //expose a function that can pass in a reference to an external function and assign the referenceIn the widget we create an to the appropriate handler.“addEventListener” function that has exports.addEventListener = function(listenerName, listenerFunction){two parameters, the name of the event switch (listenerName){ case click :and a reference to the function it will handlers.click = listenerFunction; break;call in the main app. case delete : handlers.deleteRow = listenerFunction; break;We assign the reference to a }; };“handlers” object we created in the if(OS_IOS){widget. $.table.addEventListener(delete, function(r){
  27. 27. CONTROLLERS – HANDLING EVENTS App – index.js Widget – widget.js $.table1.addEventListener(delete, function(r){ //create a handlers object that will contain Ti.API.info(row deleted: + JSON.stringify(r)); references to functions var dialog = Ti.UI.createAlertDialog({ var handlers = {}; message: r.row.title, title: Deleted //assign some functions that do nothing. }); handlers.click = function(r){}; dialog.show(); handlers.deleteRow = function(r){}; }); //expose a function that can pass in a reference to an external function and assign the reference to the appropriate handler. exports.addEventListener = function(listenerName, listenerFunction){ switch (listenerName){In the main app we call the case click :“addEventListener” function, passing in handlers.click = listenerFunction; break;the name of the listener and defining case delete : handlers.deleteRow = listenerFunction;the function we want to execute when break; };the even is fired. }; if(OS_IOS){ $.table.addEventListener(delete, function(r){
  28. 28. CONTROLLERS – HANDLING EVENTS App – index.js Widget – widget.js $.table1.addEventListener(delete, function(r){ //assign some functions that do nothing. Ti.API.info(row deleted: + JSON.stringify(r)); handlers.click = function(r){}; var dialog = Ti.UI.createAlertDialog({ handlers.deleteRow = function(r){}; message: r.row.title, title: Deleted //expose a function that can pass in a reference }); to an external function and assign the reference dialog.show(); to the appropriate handler. }); exports.addEventListener = function(listenerName, listenerFunction){ switch (listenerName){ case click : handlers.click = listenerFunction; break; case delete : handlers.deleteRow = listenerFunction;In the widget we listen for the tables break; };“delete” event and call the appropriate };handler object. if(OS_IOS){ $.table.addEventListener(delete, function(r){ handlers.deleteRow(r); }); };
  29. 29. THANK YOU Source code: http://bit.ly/alloy-customTableViewSlideshare: http://bit.ly/alloy-customTableViewSlides Mobile Data Systems Ltd. Turnkey mobile consultancy www.mobiledatasystems.co martin.hudson@mobiledatasystems.co

×