tag:blogger.com,1999:blog-78882356104500587472024-03-27T22:57:17.873-07:00Apps, Games and Mobile DevPersonal repository for my own experiences with mobile apps, Xamarin, gaming and software development. All opinions and views are my own. Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-7888235610450058747.post-70855910539071539722016-06-02T15:27:00.005-07:002016-06-03T14:52:03.856-07:00Web Services made easy with HttpClient & JSON.NET<span style="font-family: inherit;">I have intended to write this for a while. As a Sales Engineer for Xamarin, and now Microsoft, I go through a lot of the same scenarios when working with companies to get up and running with Xamarin and mobile development. As one example, there is almost a 99% guarantee that the first apps these companies plan to build will communicate with an external data source in some way, almost always using web services.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Now, there is a high likelihood this is not a new topic to those who read this blog, but as a believer in the "<a href="http://xkcd.com/1053/">Lucky 10,000</a>" from xkcd, I figure this information is still worth sharing. To those of you who were unaware of today's content, congrats as you are one of the lucky 10,000 today! What I have to share should make your mobile journey all the easier.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Now it should be noted that I recognize web services are a broad topic, lots of solutions out there. One quick hop over to the Xamarin documentation alone lists a few:</span><br />
<br />
<a href="https://developer.xamarin.com/guides/cross-platform/application_fundamentals/web_services/">https://developer.xamarin.com/guides/cross-platform/application_fundamentals/web_services/</a><br />
<br />
<span style="font-family: inherit;">The main three built into the Xamarin tooling are on consuming RESTful, SOAP and WCF services. For the remainder of this post I will focus on REST as I find it to be the most straightforward to consume.</span><br />
<span style="font-family: inherit;"><span style="font-family: "times" , "times new roman" , serif;"><br /></span></span>
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-size: small;">Consuming REST services really falls down to two main parts. Consumption of the service itself, and then consumption of the data received. As you likely have guessed, there are two tools available to help make this process </span></span>much more straightforward. For the service, <a href="https://www.nuget.org/packages/Microsoft.Net.Http">Microsoft's HTTP Client</a> libraries and for the data, <a href="http://www.newtonsoft.com/json">JSON.NET</a>. When combined, it can be as simple as three lines of code to communicate with an external service and acquire data. Below is a sample of what that code would look like:</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="font-size: small;"><br /></span></span></span>
<span style="font-family: Times,"Times New Roman",serif;"><span style="font-family: inherit;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">var httpClient = new HttpClient ();<br />var json = await httpClient.GetStringAsync ($"http://mywebservice.com");<br />var result = JsonConvert.DeserializeObject<my_data_object><my_data_object> (json);</my_data_object></my_data_object></span></span></span></span></span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><my_data_object><span style="font-family: Times,"Times New Roman",serif;">What you see above is both parts. Line one creates the HttpClient followed by actually making a REST call to grab you data. The third line is part two, parsing the resulting json into something more C# readable. If you have not used JSON.NET before, it really is something of magic under the hood. Basically, all you need to do is provide it a valid json file, and then pass a constructed C# object for it to parse into. In the above example, it will try to parse your json into the class "MY_DATA_OBJECT". </span></my_data_object></span></span></span></span></span><br />
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><my_data_object><span style="font-family: Times,"Times New Roman",serif;"><br /></span></my_data_object></span></span></span></span></span>
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><my_data_object><span style="font-family: Times,"Times New Roman",serif;">To use a more "practical" example, I am a big fan of Blizzard games and recently wrote an app to play with some of the community API's available, found here <a href="https://dev.battle.net/">https://dev.battle.net/</a>. The main goal was to just do a bit of poking and write a simple Warcraft character display app. Nothing complex, make some calls to load character data, item sets, etc. In order to grab the basic character profile in my app, I have the following code:</span></my_data_object></span></span></span></span></span><br />
<span style="font-family: inherit;"><span style="font-family: inherit;"><br /></span></span>
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><my_data_object><span style="font-family: Times,"Times New Roman",serif;">var httpClient = new HttpClient (new NativeMessageHandler ());<br />var json = await httpClient.GetStringAsync ($"https://us.api.battle.net/wow/character/Muradin/Deaus?locale=en_US&apikey={</span></my_data_object></span></span></span><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><my_data_object><span style="font-family: Times,"Times New Roman",serif;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><span style="font-family: Times,"Times New Roman",serif;">Constants.APIKEY}</span></span></span></span>" );</span></my_data_object></span></span></span></span></span><br />
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><my_data_object><span style="font-family: Times,"Times New Roman",serif;">var res = JsonConvert.DeserializeObject<chardata> (json); </chardata></span></my_data_object></span></span></span></span></span><br />
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><my_data_object><span style="font-family: Times,"Times New Roman",serif;"><br /></span></my_data_object></span></span></span></span></span>
<span style="font-family: inherit;"><span style="font-family: inherit;"><span style="font-family: Georgia,"Times New Roman",serif;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><my_data_object><span style="font-family: Times,"Times New Roman",serif;">In this case, I am pulling the data for my Paladin, Deaus, from the Muradin server. The resulting JSON looked like this:</span></my_data_object></span></span></span></span></span><br />
<br />
{<br />
"lastModified": 1426370270000,<br />
"name": "Deaus",<br />
"realm": "Muradin",<br />
"battlegroup": "Vengeance",<br />
"class": 2,<br />
"race": 3,<br />
"gender": 0,<br />
"level": 100,<br />
"achievementPoints": 7620,<br />
"thumbnail": "muradin/10/119640842-avatar.jpg",<br />
"calcClass": "b",<br />
"faction": 0,<br />
"totalHonorableKills": 1961<br />
}<br />
<br />
<span style="font-family: inherit;">On the C# side, I would create a class called CharData which would look something like this:</span><br />
<br />
<span style="font-family: Times,"Times New Roman",serif;">public class CharData<br />{<br /> public long lastModified { get; set; }<br /> public string name { get; set; }<br /> public string realm { get; set; }<br /> public string battlegroup { get; set; }<br /> public int class { get; set; }<br /> public int race { get; set; }<br /> public int gender { get; set; }<br /> public int level { get; set; }<br /> public int achievementPoints { get; set; }<br /> public string thumbnail { get; set; }<br /> public string calcClass { get; set; }<br /> public int faction { get; set; }<br /> public int totalHonorableKills { get; set; }<br />}</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">JSON.NET does the rest of the work, taking advantage of the json tags and matching them to the appropriate C# properties, and instantiates/populates my data for me. The best part of all of this? All of this is PCL compliant so it is located 100% inside my shared code!</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">One useful tool to expedite the process even more is the website <a href="http://json2csharp.com/">json2csharp.com</a>. This website will take json data and auto generate the resulting C# class for you, at least at a base level.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">As a note, not all REST end points are so easily configured, but HttpClient is actually quite flexible. I was also recently poking around a community made Hearthstone API, <a href="https://market.mashape.com/omgvamp/hearthstone">https://market.mashape.com/omgvamp/hearthstone</a>, and their .NET API's are powered through unirest (<a href="http://unirest.io/net">http://unirest.io/net</a>). To get this to work I had to add a couple of DefaultRequestHeader paramters to match the documentation there. Still, rather straight forward to communicate with.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">That is about it. While this does put some requirement to set up good REST endpoints for your mobile applications, it tends to be worth the effort. Even if you have legacy WCF systems or complicated back ends, I have found that companies that have made exposed REST front ends to facilitate the communication can help streamline the entire process and, as you see above, can really make consumption on the mobile side quite easy. Until next time!</span>Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com2tag:blogger.com,1999:blog-7888235610450058747.post-28515557847436033892016-05-16T11:31:00.000-07:002016-05-16T11:31:36.773-07:00Complete Mobile Dev Ops with Visual Studio Team Services and Xamarin Test CloudWow it has been over six months. Sorry! As you can imagine, things have been busy in 2016. There has been an <a href="https://blogs.microsoft.com/blog/2016/02/24/microsoft-to-acquire-xamarin-and-empower-more-developers-to-build-apps-on-any-device/">acquisition</a>, Xamarin tools made <a href="https://blog.xamarin.com/xamarin-for-all/">available for free</a> in Visual Studio, and then <a href="https://evolve.xamarin.com/#videos">Xamarin Evolve</a>. Now that things have settled down, and integration into Microsoft underway, I wanted to take this as an opportunity to get back to making semi-regular posts once more.<br />
<br />
When I joined Xamarin in December of 2013, it was still largely a one product company. Xamarin enabled you to develop apps for Android, iOS, or Mac using C#. (OK, technically three products but to a degree you can look at them as different facets of the same tool).<br />
<br />
Since that point Xamarin has grown to help assist in the full mobile development lifecycle. This included the launch of Xamarin University for training, Xamarin Test Cloud for better testing and Xamarin Inisghts for crash reporting, messaging and analytics. With Xamarin now under the Microsoft umbrella, a few new tools are available to even further complete that picture. The focus of this entry will be on how to leverage Visual Studio Team Services with Xamarin, both development and Xamarin Test Cloud, to create a full Dev-Test-Publish lifecycle.<br />
<br />
<u>Getting setup with Visual Studio Team Services</u><br />
I won't spend a whole lot of time on this. The basic checklist can be found below. <br />
<br />
1. Create your VSTS account<br />
2. Create your Project<br />
3. Connect to Visual Studio<br />
4. Set up your repo and code<br />
<br />
The main setup guide hub can be found here: https://www.visualstudio.com/get-started/setup/set-up-vs<br />
<br />
For my scenario, I ended up using git as my repository, which would also be my recommendation if you don't have a previous requirement or preference. <br />
<br />
<span style="font-size: small;"><u>Integrating Xamarin Test Cloud</u></span><br />
<span style="font-size: small;">Now that you have your code integrated with VSTS, and uploaded, the next step is to create a build process that confirms your build and also calls to Xamarin Test Cloud for regression testing. </span>That way, any time a developer on your team submits their code, you can confirm everything is still working. Please note, this will require having created a UITest project and at least one step to run. If you have not ever done this, you can find more details here:<br />
https://developer.xamarin.com/guides/testcloud/uitest/intro-to-uitest/<br />
<br />
Now, the final piece of this puzzle is to integrate this as part of your VSTS build chain. Microsoft actually made this process quite straight forward, once I had my head wrapped around the tooling. A full general doc, found after I got it sorted myself, can be found here:<br />
<br />
https://msdn.microsoft.com/library/vs/alm/build/apps/xamarin<br />
<br />
This is what I wanted to break down and guide in more detail. First, select the Build tab in the VSTS portal and hit the green "+" button:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLSc5S_AZRi_yyGFf7lDQ3llnZeJlro2FqXz-lwYZj-dWOPj0kWMKnkAGEfg0Ft1sZ9AcXVXI1k5TAr70_UCbGTZlyRSkC6gprrTZLOheFbW7S_4H6CJmPLfckSvMSKCG1lE_FQGMkaho/s1600/Screenshot+2016-05-13+15.25.36.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLSc5S_AZRi_yyGFf7lDQ3llnZeJlro2FqXz-lwYZj-dWOPj0kWMKnkAGEfg0Ft1sZ9AcXVXI1k5TAr70_UCbGTZlyRSkC6gprrTZLOheFbW7S_4H6CJmPLfckSvMSKCG1lE_FQGMkaho/s320/Screenshot+2016-05-13+15.25.36.png" width="307" /></a></div>
This will create a new dialog window. This is where you will select your build type. For our example we will use Xamarin.Android template. If you need iOS, you would match this process with iOS.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZPb00dPlH5wpAPupQEIES4-uoFAb_VXYldW7eROL73oHl30gNe0sKCZJXr1tUvjsWeCypgZalkcAnPE7amHAfWeVf8w9D42uLtK6lz_AOHDtrvg_a6o5Yn3v2RlzhnOiJiarAZdsUwd4/s1600/Screenshot+2016-05-13+15.26.34.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZPb00dPlH5wpAPupQEIES4-uoFAb_VXYldW7eROL73oHl30gNe0sKCZJXr1tUvjsWeCypgZalkcAnPE7amHAfWeVf8w9D42uLtK6lz_AOHDtrvg_a6o5Yn3v2RlzhnOiJiarAZdsUwd4/s320/Screenshot+2016-05-13+15.26.34.png" width="288" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">So many options</td></tr>
</tbody></table>
From here you can use the default settings, you want to select your Repository in question so that it uses this code for the build. If you notice in my example, I have "Continuous integration" selected. I recommend this if possible as it will allow you to run these tests whenever code is submitted to the branch.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-mm-U82V0EmMlume6YSSX-eRxtNiR0S80deOHE5TlOZifJCCGbcr2CrAeg9JDv6Kl46tpfkJlvBYlOTBb5GvudhDAIev-mUiocvlZa12KU1SiRVuaIIfHnwcZ6bi-AosNfL32RsoGTyw/s1600/Screenshot+2016-05-16+11.11.46.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-mm-U82V0EmMlume6YSSX-eRxtNiR0S80deOHE5TlOZifJCCGbcr2CrAeg9JDv6Kl46tpfkJlvBYlOTBb5GvudhDAIev-mUiocvlZa12KU1SiRVuaIIfHnwcZ6bi-AosNfL32RsoGTyw/s320/Screenshot+2016-05-16+11.11.46.png" width="291" /></a></div>
Once you hit create, you are then resented with a dialog to configure the specific build settings. There are a three steps that require input:<br />
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFjFom3jG8tlXddrKxWO8mSVztNSbwo0iAIW4gQsnz69WP65Oyk52DhN1D_0ctTcrWfKff5HjxDnAS7oJfXQ557cAeZNpzdJaaeQTF_JcQ5Og9KfXoeKyEDfndJP0kyoHenWdJnwTFS1Y/s1600/Screenshot+2016-05-13+15.30.08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFjFom3jG8tlXddrKxWO8mSVztNSbwo0iAIW4gQsnz69WP65Oyk52DhN1D_0ctTcrWfKff5HjxDnAS7oJfXQ557cAeZNpzdJaaeQTF_JcQ5Og9KfXoeKyEDfndJP0kyoHenWdJnwTFS1Y/s320/Screenshot+2016-05-13+15.30.08.png" width="320" /></a></div>
<br />
But it can be boiled down to<br />
1. Your license login (user name and password) information to activate\deactivate your Xamarin credentials<br />
2. Xamarin Test Cloud API Key, Device ID, Test Cloud email<br />
<br />
As a pro-tip for the password, the password field defaults to a plain text entry. What I would recommend is select the variables tab, and add your password as a variable, with the lock icon selected to flag it as "Secret".<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6OKrJJG0uPsXniw7gPU-evt7fz2xj2tV5Q0cV8b9_IF6-Upz6HOHIqeDwqQrDnODxbibC6vDLhanJ152PGX0KbzrMXak9G61-xbkTZ62cyvtyjBta55nEMkY8fteFIvCz5Bqg1ls6aC4/s1600/Screenshot+2016-05-16+11.20.01.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6OKrJJG0uPsXniw7gPU-evt7fz2xj2tV5Q0cV8b9_IF6-Upz6HOHIqeDwqQrDnODxbibC6vDLhanJ152PGX0KbzrMXak9G61-xbkTZ62cyvtyjBta55nEMkY8fteFIvCz5Bqg1ls6aC4/s320/Screenshot+2016-05-16+11.20.01.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MyPassword is the variable I have created.</td></tr>
</tbody></table>
Then in the password field you just use that variable with the syntax $(_VARNAME_). Much more secure than plain text usage.<br />
<br />
For the "Test" step, you need to provide a few pieces of information.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF6loxgL6v5BI-nr4DHe-zsREp4AMJEKsi_4Uv1vZ-PjX018AlchAFvfAicIgFKy-Cov6lhN2dxFuUklRwij5Mlf1HMFAdu7NI9iuVOXGqlarZqVFy4krh1qulLIFU7qkwnAYsjCjrU0s/s1600/Screenshot+2016-05-16+11.23.44.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF6loxgL6v5BI-nr4DHe-zsREp4AMJEKsi_4Uv1vZ-PjX018AlchAFvfAicIgFKy-Cov6lhN2dxFuUklRwij5Mlf1HMFAdu7NI9iuVOXGqlarZqVFy4krh1qulLIFU7qkwnAYsjCjrU0s/s320/Screenshot+2016-05-16+11.23.44.png" width="320" /></a></div>
<br />
First is your Test Cloud API Key, which is found under Teams and Organizations on your Test Cloud account. You can find details on obtaining that here: https://developer.xamarin.com/guides/testcloud/organizations-and-teams/#Obtaining_the_Team_API_Key<br />
<br />
If you are not currently using Xamarin Test Cloud, fear not! We have a free trial that you can try out. More details can be found here: https://testcloud.xamarin.com/register<br />
<br />
Again, you need to provide an email, this time the email of registered/added to the Test Cloud account. This may or may not differ from your Xamarin license details.<br />
<br />
The devices ID you can acquire when you create an upload on Xamarin Test Cloud. The final step will give you a command line prompt that can be used for Windows or OSX and included is a --devices (#########) flag. This id is the final piece of information as it tells Test Cloud what devices the test needs to be run on, and can be reused from run to run. I would recommend recording these ID's as currently there is not another way to retrieve them to my knowledge.<br />
<br />
Once you have entered all this information you have everything you need. At this point I would recommend selecting "Queue build" to do a test run with what you have uploaded, troubleshoot issues as needed. Ideally you should see this:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqpd6X4gzvPbqKB_WOw9oKQ1P6yDLdi-5hdhsdPIiqWev5-rtSLDif-ACDL3Mfq_XVTvTq0Dpl2oAAjRz9thUc7Lj8DimJMn5FBSOB0uJw6w9nG40qlGH3HHG-FzkNa3hcUPt6f7ddN0Q/s1600/Screenshot+2016-05-13+15.47.39.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqpd6X4gzvPbqKB_WOw9oKQ1P6yDLdi-5hdhsdPIiqWev5-rtSLDif-ACDL3Mfq_XVTvTq0Dpl2oAAjRz9thUc7Lj8DimJMn5FBSOB0uJw6w9nG40qlGH3HHG-FzkNa3hcUPt6f7ddN0Q/s320/Screenshot+2016-05-13+15.47.39.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Green is good!</td></tr>
</tbody></table>
That's it! You have made your first step into a larger world of end to end mobile development and more efficient DevOps! Now, any time you submit code from git, this build step will be executed and you are on your way to writing higher quality code. Use this to make sure you are keeping your app at a high quality, and catch bugs and regressions before your users do!Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com3tag:blogger.com,1999:blog-7888235610450058747.post-3667266718882114112015-11-13T15:45:00.002-08:002015-11-13T15:45:36.950-08:00How to Preview your Xamarin.Forms XAML in Xamarin StudioIn my work as a Customer Success Engineer at Xamarin, I demo the tools we provide daily. One that has gained immense popularity since launch has been, without a doubt, Xamarin.Forms. For those of you new to Xamarin development, Xamarin.Forms is a framework that enables you to write your mobile UI for Android, iOS and Windows phone in a shared code layer using either C# or XAML. Many developers see this as a real asset as greater code share suggests shorter development times and getting your app faster to market. XAML based UI development is also something that WPF and C# developers are already familiar with so that means their experience will help them get up and running with mobile sooner.<br />
<br />
With that in mind, one thing that developers desire is rapid feedback and development. At the time of this writing Xamarin.Forms currently is a programmatic solution only. That means, no visual designer or previewer to view your UI in progress. That means that the only way to ensure your UI looks good is to build and deploy your app to either an emulator or physical device. While certainly a possibility, this is not the fastest process, especially if you are trying to make minute changes and get immediate feedback.<br />
<br />
<br />One solution to this that has been made available is a tool call the <a href="https://visualstudiogallery.msdn.microsoft.com/4ed9794a-2021-486a-9bca-4851c7ee7316">Xamarin.Forms Player</a>, written by Daniel Cazzulino, who also happens to be a developer at Xamarin. What this tool does is installs a plugin to Visual Studio that allows you to pair your Visual Studio instance to either an emulator or device. Then, while you are writing the XAML portion of your application, you can actually quickly preview the results live without doing a full build and deployment of the application. This serves as a great solution to many developers. While the Visual Studio add-in has been available for a while, I was recently made aware of this also being published as an Add-In for Xamarin Studio and wanted to write a quick guide on how to get it set up.<br />
<br />
From what I understand about the tool, the Forms
Player works as a pub/sub application where multiple devices will subscribe to an IDE through a paired code between your IDE and an configured application running on device. Then, as you are developing your XAML you can quickly do a compile and publish. When the IDE publishes an update, each subscriber running will update and display
the result. Really cool.<br />
<br />
There are two main parts to getting this set up<br />
<br />
I. Install the Add-In within Xamarin Studio (On Mac)<br />
<br />Select Xamarin Studio -> Add-In Manager -> Gallery Tab. From there search for Forms Player, it should appear under Mobile Development<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKmeIAo8mjmushXigjhGcHZTGR6ACJKzuvx0TmmLfSvZzirE18Vad1dXIyB8IlXCTaXH3eVh0wbi1ptD5Ivr4Q2tJwPLP0JV63Udqp3cG-lP45Aqc02MaGiVTvq_aycALLOtaGY3DdNgc/s1600/Forms+Add-In+Manager.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="271" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKmeIAo8mjmushXigjhGcHZTGR6ACJKzuvx0TmmLfSvZzirE18Vad1dXIyB8IlXCTaXH3eVh0wbi1ptD5Ivr4Q2tJwPLP0JV63Udqp3cG-lP45Aqc02MaGiVTvq_aycALLOtaGY3DdNgc/s400/Forms+Add-In+Manager.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
II. Create and Install a Forms Player application on device.<br />
<br />
Here is where we set up the subscriber side of things. There are a few ways you could do this, including compiling the code from GitHub and installing it, but this approach is pretty simple.<br />
<br />
1) Create a new cross platform Xamarin.Forms application. I would name it something like "Forms Player" or maybe equally memorable. PCL or Shared Project should be fine.<br />
<br />
2) Add the Xamarin.Forms Player NuGet to your Android and iOS Targets. Right click both Android and iOS Projects-> Add-> Add NuGet Packages. Make sure in the bottom right you check the "Show pre-release" box.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMo2YaVwy4d2_Bl5WfHGd0D5vuYWwpeZNzrAFRFTSu4ZWEgyOqvNBB6O39FwlVa7GpYdQf0FEYGleDrSF_5N0YFwrxuUvEl_CBhwi4EpvtZMglJrX7X0bqoTkDdLNLIISDyGA3dGm64c4/s1600/NuGet+Package+Forms+Player.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="263" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMo2YaVwy4d2_Bl5WfHGd0D5vuYWwpeZNzrAFRFTSu4ZWEgyOqvNBB6O39FwlVa7GpYdQf0FEYGleDrSF_5N0YFwrxuUvEl_CBhwi4EpvtZMglJrX7X0bqoTkDdLNLIISDyGA3dGm64c4/s400/NuGet+Package+Forms+Player.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
3) Update <span style="font-size: x-small;"><span style="font-family: Arial,Helvetica,sans-serif;">
<span style="color: #333333;"></span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">App</span><span style="color: #333333;"> </span><span style="color: #333333;">()</span>
</span></span>in MainActivity.cs and AppDelegate.cs to be
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-size: x-small;"><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">Xamarin.Forms.Player.App</span><span style="color: #333333;"> </span><span style="color: #333333;">()</span></span></span></span><br />
<br />
<br />
<br />
<br />
<br />
<br />
As a side note, you may need to modify some of the built references on the iOS project. When I set this up, it complained, initially, about duplicate references to System.Runtime, System.Threading and System.IO. Removing them from the References-> From Packages folder got it running fine.<br />
<br />4) Deploy this application to the devices/emulators you want to support. You will see a Home screen like this:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeJBkq6GJ1h5bZCMEsLKjIIMxqGD2yqx5Hv8m-Q_qFbcldZP7a2ePrSf_j21nFYu2zbPGdqa83hOaVc2W1uIGv1YeEKL00YLLIz8barU7Qc0DFvuwV2aWX4BudBjom6LwKfaPBUA6witI/s1600/PlayerHomeScreen.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="550" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeJBkq6GJ1h5bZCMEsLKjIIMxqGD2yqx5Hv8m-Q_qFbcldZP7a2ePrSf_j21nFYu2zbPGdqa83hOaVc2W1uIGv1YeEKL00YLLIz8barU7Qc0DFvuwV2aWX4BudBjom6LwKfaPBUA6witI/s640/PlayerHomeScreen.png" width="640" /> </a></td><td style="text-align: center;"> </td><td style="text-align: center;"><br /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">iOS on left, Android on Right</td></tr>
</tbody></table>
III) Start debugging your app<br />
<br />
Now that you have these installed, what you will do is pair them. You do this by selecting the Forms Player menu and select Connect. This will create a running Session ID, which you will input in the running application you have previously installed above.<br />
<br />
Open up the Forms application you want to work on. When you open the .xaml file, you will notice that the "Publish" option from the Forms Player menu will no longer be greyed out. Each time you select publish, or hit the hotkey, while you have a .xaml file loaded in your IDE, it will load that current XAML to any device with the app running and session paired, and then preview it.<br />
<br />
And there you go! Hopefully you found this useful and it will help you build and ship higher quality Xamarin.Forms apps faster.<br />
<br />Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com76tag:blogger.com,1999:blog-7888235610450058747.post-27554250802613296922015-10-06T15:42:00.000-07:002015-10-06T15:42:39.202-07:00Getting started with iOS Development- No more XML<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">Well, I finally am making the plunge. After weeks of postponing, delays, justification and just general laziness I pulled myself together and started the iOS side of development. For those that don't know me I have always had a preference to Android (or an irrational dislike of Apple and its products) so my desire to work on iOS definitely came with a bias against it.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">That being said, as a developer with a background in .NET, C#, WPF and Android moving to iOS can be TOUGH. It is a very different paradigm shift to move from xml based UI development, which I have really grown to love, to iOS Storyboards, which still confuse me. Storyboards are built with a visual flow to them, this gives you a nice ability to get a good overview of the app and how it navigates but the individual details are not as easy to manage. Additionally, coming from a world of Layout Controls, moving to the paradigm of Auto-Layout and Constraints can also be a unique challenge. Overall the shift for me hearkens back to a day of WinForms development. It is definitely something new for me.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">Much as before, this will likely see a few iterations as my knowledge grows. I decided to follow a similar pattern to how I built my Android UI, first loading the main character overview page, then start building it out from there. </span><span style="font-size: small;">So after setting up my initial UI I found myself with this general starting point:</span></span><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqdMqAmo_PICqENQpk-BoVdHaWRjeWMwqc2bshsxG8ZNxU94HR5Ok8VjgF00S0a8YGvy0C1L8TCyLotKo1epMmLkynuXiBRl90ay4ZNTkwe_TCffigKJdkVvp0m_Hb8aY45QXqyaYkV_g/s1600/iOS_overview+v1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqdMqAmo_PICqENQpk-BoVdHaWRjeWMwqc2bshsxG8ZNxU94HR5Ok8VjgF00S0a8YGvy0C1L8TCyLotKo1epMmLkynuXiBRl90ay4ZNTkwe_TCffigKJdkVvp0m_Hb8aY45QXqyaYkV_g/s320/iOS_overview+v1.png" width="181" /></a></span></span></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">I'll deal with layout later.</span></span></td></tr>
</tbody></table>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">The first challenge I ran into was a new paradigm for my drop down selection boxes. Where android has a <a href="http://developer.android.com/reference/android/widget/Spinner.html">spinner</a> control that provides a drop down list for you to interact with, that is not something available on iOS.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">They have a <a href="https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPickerView_Class/index.html">picker</a> control instead, which is described as using </span><span style="font-size: small;">"a spinning-wheel or slot-machine metaphor to show one or more sets of values". If you notice, I am using Text Field's for my data display since there was no "combo box". After some research I learned that iOS actaully has a pretty cool solution set up for something like this. What i needed to do was wire the Text Field input option to be a Picker control instead of the default keyboard input. iOS, in this regard, actually makes this quite simple to do. Text Fields, and many other controls, have a property called <a href="http://developer.xamarin.com/api/property/UIKit.UITextView.InputView/">InputView</a> which defines what control is the selected input. Keyboard is the default when nothing is set, so instead I set it to a created Picker Control, like so:</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">
<span style="color: #333333;"></span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">racePicker</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">UIPickerView</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">CGRect</span><span style="color: #333333;">.</span><span style="color: #333333;">Empty</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">
<span style="color: #333333;"></span><span style="color: #333333;">racePickerText</span><span style="color: #333333;">.</span><span style="color: #333333;">InputView</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">racePicker</span><span style="color: #333333;">;</span></span></span>
<br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">Then a picker control is displayed when we click the Text Field like so:</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"></span></span><br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbW7bVBJaG0G8SflrYX_6tvMjBSWPuOMAOImaCe9ywpun4RgoCczdZj4nWlCQMkr-FYPG9SqCJk-l89l471vOeFaY-9VJRXOs2ZVcKFWW0qFSCobVa6jqQQzS9_aGVd_QpbnUE2z4Y9kQ/s1600/overview_picker_v1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbW7bVBJaG0G8SflrYX_6tvMjBSWPuOMAOImaCe9ywpun4RgoCczdZj4nWlCQMkr-FYPG9SqCJk-l89l471vOeFaY-9VJRXOs2ZVcKFWW0qFSCobVa6jqQQzS9_aGVd_QpbnUE2z4Y9kQ/s320/overview_picker_v1.png" width="176" /></a></span></div>
<br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">Overall this is a good start. Different from what we had before, but it works. This does bring up a couple more questions however, populating our data, binding it to the Text Field itself, and then dismissing our Picker when we are done.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">1. Setting up the Data.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">This is an area that is actually not as documented in Xamarin, but is something that needs to be learned. In Objective-C/Swift world the UIPickerView has two main sources for data and interaction. The Delegate and DataSource. The DataSource is, as you can guess, the data that is tied to the control. You can think of Delegates kind of like the controller layer, defining interaction. </span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">In Xamarin, both of these properties are exposed, as well as a hybrid Object called the <a href="http://developer.xamarin.com/api/type/UIKit.UIPickerViewModel/">UIPickerViewModel</a>. This is something specific to Xamarin, but basically serves as a hybrid of the two previously mentioned properties and is more C# styled. I learned, over time, that this is a paradigm we do quite frequently but it is something we admittedly do not have as much documentation on. For the case of my application it served my needs. Knowing I had at least four different scenarios I wanted a data source for my object, I created a general PickerModel and overrode the defined methods to use my data, and then set my model in my picker control:</span></span><br />
<br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">model</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">MyPickerModel</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">RaceHelper</span><span style="color: #333333;">.</span><span style="color: #333333;">GetAllRaces</span><span style="color: #333333;"> </span><span style="color: #333333;">()</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;">info</span><span style="color: #333333;">.</span><span style="color: #333333;">Race</span><span style="color: #333333;">.</span><span style="color: #333333;">Name</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br /><span style="color: #333333;"></span><span style="color: #333333;">model</span><span style="color: #333333;">.</span><span style="color: #333333;">OnPropertySelected</span><span style="color: #333333;"> </span><span style="color: #333333;">+=</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">object</span><span style="color: #333333;"> </span><span style="color: #333333;">sender</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #3364a4;">EventArgs</span><span style="color: #333333;"> </span><span style="color: #333333;">args</span><span style="color: #333333;">)</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;"> </span></span></span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><span style="font-family: Menlo;"><span style="color: #333333;">{ </span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">racePickerText</span><span style="color: #333333;">.</span><span style="color: #333333;">Text</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">model</span><span style="color: #333333;">.</span><span style="color: #333333;">SelectedItem</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;">}</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;">racePicker</span><span style="color: #333333;">.</span><span style="color: #333333;">Model</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">model</span><span style="color: #333333;">;</span></span></span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">The constructor is how I set my initial conditions, and then if you notice I have a defined PropertySelected event so that I can feedback to my UI when items are updated. Then I was able to get my data populating within my UIPickerView:</span></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyNFOGLF465JrAbGtmHYhXn7kzyPpUmIWJh62tkR0MOb6ENtxbIme5JJ83ux00P3TcfAcK-I_1U1MkscvkMGbcsVlEYA3536dc1Ds4z9CZSqU5KOVavFu3SF1PWZv4ouZ4taISeqHKjE8/s1600/overview_picker_final.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyNFOGLF465JrAbGtmHYhXn7kzyPpUmIWJh62tkR0MOb6ENtxbIme5JJ83ux00P3TcfAcK-I_1U1MkscvkMGbcsVlEYA3536dc1Ds4z9CZSqU5KOVavFu3SF1PWZv4ouZ4taISeqHKjE8/s320/overview_picker_final.png" width="174" /></a></div>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">The final piece to the puzzle was dismissing the view. This took a bit of hunting and research and then I finally found the final piece. Along with an InputView, there is also an <a href="http://developer.xamarin.com/api/property/UIKit.UITextField.InputAccessoryView/">InputAccessoryView</a></span></span>.<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"> This gives you the ability to add a toolbar to your InputView, giving additional functionality and methods of interaction, including a "Done" button in my case. Setup was actually pretty simple:</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"></span><br />
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">toolbar</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">UIToolbar</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">RectangleF</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #f57d00;">0.0f</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0.0f</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #f57d00;">50.0f</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #f57d00;">44.0f</span><span style="color: #333333;">))</span><span style="color: #333333;">;</span><br />
<span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">myButton</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">UIBarButtonItem</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">UIBarButtonSystemItem</span><span style="color: #333333;">.</span><span style="color: #333333;">Done</span><span style="color: #333333;">,</span></span><br />
<span style="font-family: Menlo;"><span style="color: #333333;"> </span><span style="color: #009695;">delegate</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">this</span><span style="color: #333333;">.</span><span style="color: #333333;">racePickerText</span><span style="color: #333333;">.</span><span style="color: #333333;">ResignFirstResponder</span><span style="color: #333333;"> </span><span style="color: #333333;">()</span><span style="color: #333333;">;</span><span style="color: #333333;"> </span></span><br />
<span style="font-family: Menlo;"><span style="color: #333333;"> })</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;">toolbar</span><span style="color: #333333;">.</span><span style="color: #333333;">Items</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">UIBarButtonItem</span><span style="color: #333333;">[]</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span></span><br />
<span style="font-family: Menlo;"><span style="color: #009695;"> new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">UIBarButtonItem</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">UIBarButtonSystemItem</span><span style="color: #333333;">.</span><span style="color: #333333;">FlexibleSpace</span><span style="color: #333333;">)</span><span style="color: #333333;">,</span> <span style="color: #333333;">myButton</span><span style="color: #333333;"> }</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;">racePickerText</span><span style="color: #333333;">.</span><span style="color: #333333;">InputAccessoryView</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">toolbar</span><span style="color: #333333;">;</span></span><br />
<span style="font-family: Menlo;"><span style="color: #333333;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;">And what this gives us is the final product here:</span></span> </span></span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL1o6NqVztRSYyIveLPMHN9LWtx0InoxCuAsH548jceY59FTe6WPgI3dZ9S2hJREJ8Q4XOJ57DNLdKRBJRKFs472kKoVj0qDYq1Fmd8Bd9jL5VeZDXIN6t1mbg-oXJzpU9Nbv8zejdP0I/s1600/overview_picker_final.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL1o6NqVztRSYyIveLPMHN9LWtx0InoxCuAsH548jceY59FTe6WPgI3dZ9S2hJREJ8Q4XOJ57DNLdKRBJRKFs472kKoVj0qDYq1Fmd8Bd9jL5VeZDXIN6t1mbg-oXJzpU9Nbv8zejdP0I/s320/overview_picker_final.png" width="174" /></a></div>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;"><br />Next step will be to organize the code to be more clean/refactored but that will be for another time.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;">Again I apologize for lack of diligence in getting things posted, lots going on but hopefully I will get updates on a more regular pace once more as I dig into the world of iOS.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;"></span></span><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;"></span></span><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;"></span></span>
<br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"></span><span style="font-family: Menlo;"></span> <span style="font-family: Menlo;"><span style="color: #333333;"></span></span>
Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com1tag:blogger.com,1999:blog-7888235610450058747.post-42342848846313670272015-09-21T14:43:00.001-07:002015-09-21T14:45:09.651-07:00Android Code Review- BaseAdapters are your FriendWell, I am finally forcing myself to make the jump to iOS, but that is taking more time than I anticipated. More on that in the first iOS blog post. I did spend a little time doing some code review, bug fixing and refactoring. In that process I had a great conversation with one of the other Success Engineers at Xamarin, Colby Williams, who gave me some good feedback and reviewed some of my code. I learned one really great nuget that is worth sharing as it is not immediately apparent when getting started with Xamarin from Android.<br />
<br />
When using collection views, it is almost always best to subclass BaseAdapter rather than use any of the out of the box adapters provided by Android (ArrayAdapter comes to mind). I was using the default ArrayAdapter for all of my drop down spinner controls and what I learned is most of the default Adapters provided by Android will give a potential performance hit because for each object in the list, an equal java object has to be created and maintained. This is due to how Xamarin and Android communicate with each other. For an in depth review, this document covers it well:<br />
<br />
http://developer.xamarin.com/guides/android/under_the_hood/architecture<br />
<br />
So what was happening was for every spinner I created using an Array Adapter, a general C# and Java object were being created and maintained, creating overhead. Instead, creating a BaseAdapter, the under the hood creates a single Java object that has a C# implementation within. Much better performance wise, fewer objects to maintain in memory.<br />
<br />
My final code for the adapter is actually pretty simple:<br />
<br />
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">class</span><span style="color: #333333;"> </span><span style="color: #3364a4;">SpinnerAdapter</span><span style="color: #333333;"> </span><span style="color: #333333;">:</span><span style="color: #333333;"> </span><span style="color: #3364a4;">BaseAdapter</span><span style="color: #333333;"><</span><span style="color: #009695;">string</span><span style="color: #333333;">></span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #3364a4;">List</span><span style="color: #333333;"><</span><span style="color: #009695;">string</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">_items</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #3364a4;">Activity</span><span style="color: #333333;"> </span><span style="color: #333333;">_context</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #3364a4;">SpinnerAdapter</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Activity</span><span style="color: #333333;"> </span><span style="color: #333333;">context</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #3364a4;">List</span><span style="color: #333333;"><</span><span style="color: #009695;">string</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">items</span><span style="color: #333333;">)</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">_items</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">items</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">_context</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">context</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">override</span><span style="color: #333333;"> </span><span style="color: #009695;">long</span><span style="color: #333333;"> </span><span style="color: #333333;">GetItemId</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">int</span><span style="color: #333333;"> </span><span style="color: #333333;">position</span><span style="color: #333333;">)</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">return</span><span style="color: #333333;"> </span><span style="color: #333333;">position</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">int</span><span style="color: #333333;"> </span><span style="color: #333333;">GetPosition</span><span style="color: #333333;">(</span><span style="color: #009695;">string</span><span style="color: #333333;"> </span><span style="color: #333333;">selected</span><span style="color: #333333;">)</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">return</span><span style="color: #333333;"> </span><span style="color: #333333;">_items</span><span style="color: #333333;">.</span><span style="color: #333333;">IndexOf</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">selected</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">override</span><span style="color: #333333;"> </span><span style="color: #009695;">string</span><span style="color: #333333;"> </span><span style="color: #009695;">this</span><span style="color: #333333;">[</span><span style="color: #009695;">int</span><span style="color: #333333;"> </span><span style="color: #333333;">index</span><span style="color: #333333;">]</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><span style="color: #333333;"> </span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">get</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><span style="color: #333333;"> </span><span style="color: #009695;">return</span><span style="color: #333333;"> </span><span style="color: #333333;">_items</span><span style="color: #333333;">[</span><span style="color: #333333;">index</span><span style="color: #333333;">]</span><span style="color: #333333;">;</span><span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">override</span><span style="color: #333333;"> Android</span><span style="color: #333333;">.</span><span style="color: #333333;">Views</span><span style="color: #333333;">.</span><span style="color: #3364a4;">View</span><span style="color: #333333;"> </span><span style="color: #333333;">GetView</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">int</span><span style="color: #333333;"> </span><span style="color: #333333;">position</span><span style="color: #333333;">,</span><span style="color: #333333;"> Android</span><span style="color: #333333;">.</span><span style="color: #333333;">Views</span><span style="color: #333333;">.</span><span style="color: #3364a4;">View</span><span style="color: #333333;"> </span><span style="color: #333333;">convertView</span><span style="color: #333333;">,</span><span style="color: #333333;"> Android</span><span style="color: #333333;">.</span><span style="color: #333333;">Views</span><span style="color: #333333;">.</span><span style="color: #3364a4;">ViewGroup</span><span style="color: #333333;"> </span><span style="color: #333333;">parent</span><span style="color: #333333;">)</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">view</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">convertView</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;">(</span><span style="color: #333333;">view</span><span style="color: #333333;"> </span><span style="color: #333333;">==</span><span style="color: #333333;"> </span><span style="color: #009695;">null</span><span style="color: #333333;">)</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">view</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">_context</span><span style="color: #333333;">.</span><span style="color: #333333;">LayoutInflater</span><span style="color: #333333;">.</span><span style="color: #333333;">Inflate</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Layout</span><span style="color: #333333;">.</span><span style="color: #333333;">spinner_item</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #009695;">null</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #333333;">view</span><span style="color: #333333;">.</span><span style="color: #333333;">FindViewById</span><span style="color: #333333;"><</span><span style="color: #3364a4;">TextView</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Id</span><span style="color: #333333;">.</span><span style="color: #333333;">text</span><span style="color: #333333;">)</span><span style="color: #333333;">.</span><span style="color: #333333;">Text</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">_items</span><span style="color: #333333;">[</span><span style="color: #333333;">position</span><span style="color: #333333;">]</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">return</span><span style="color: #333333;"> </span><span style="color: #333333;">view</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">override</span><span style="color: #333333;"> </span><span style="color: #009695;">int</span><span style="color: #333333;"> </span><span style="color: #333333;">Count</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">get</span><span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">return</span><span style="color: #333333;"> </span><span style="color: #333333;">_items</span><span style="color: #333333;">.</span><span style="color: #333333;">Count</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span></span>
<br />
<br />
Once I made that update, I noticed my views loaded much quicker.<br />
<br />
Next time I am going to dig into iOS development, and why it can be a challenge. Given that iOS 9 just came out this past week, I am also using this as an "excuse" to learn iOS 9.Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com0tag:blogger.com,1999:blog-7888235610450058747.post-43909245754540810732015-08-31T16:25:00.001-07:002015-08-31T16:32:57.663-07:00Android ListViews and Updating the Backend Data<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif; font-size: small;">I wanted to spend at least one more post to try to put my app in a finished state so there was a lot of time spent on both backend code and getting my skills list to display properly.</span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif; font-size: small;"><br /></span>
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">My first thought was to use a ListView to display all of my skills, it seemed logical. It was a of items, numbers and a checkbox. Time to brush off what I learned from custom spinner items. Creating adapters for your ListView is actually pretty standard as a lot of the time the default elements are going to not provide what you need.</span></span><br />
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><br /></span></span>
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">The first step was to at least get my ListView organized and all my skills displayed. I already had all the hookups in place thanks to my work last week with implementing ViewPager. The first step was to create a new LayoutView, which housed my ListView. I then used a default ArrayAdapter to just grab a placeholder list of strings.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><br /></span>
<br />
<span style="font-family: Menlo;">
<span style="color: #333333; font-size: x-small;"> </span><span style="color: #009695; font-size: x-small;">public</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #009695; font-size: x-small;">override</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #3364a4; font-size: x-small;">View</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">OnCreateView</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">(</span><span style="color: #3364a4; font-size: x-small;">LayoutInflater</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">inflater</span><span style="color: #333333; font-size: x-small;">,</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #3364a4; font-size: x-small;">ViewGroup</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">container</span><span style="color: #333333; font-size: x-small;">,</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #3364a4; font-size: x-small;">Bundle</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">savedInstanceState</span><span style="color: #333333; font-size: x-small;">)</span></span><span style="font-size: x-small;"><br /><span style="font-family: Menlo;">
<span style="color: #333333;"> </span><span style="color: #333333;">{</span></span><br /><span style="font-family: Menlo;">
<span style="color: #333333;"> </span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">root</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">inflater</span><span style="color: #333333;">.</span><span style="color: #333333;">Inflate</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Layout</span><span style="color: #333333;">.</span><span style="color: #333333;">fragment_charsheet_skills</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;">container</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #009695;">false</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span><br /><span style="font-family: Menlo;">
<span style="color: #333333;"> </span><span style="color: #3364a4;">ListView</span><span style="color: #333333;"> </span><span style="color: #333333;">view</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">root</span><span style="color: #333333;">.</span><span style="color: #333333;">FindViewById</span><span style="color: #333333;"><</span><span style="color: #3364a4;">ListView</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Id</span><span style="color: #333333;">.</span><span style="color: #333333;">skillsList</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span><br /><span style="font-family: Menlo;">
<span style="color: #333333;"> </span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">skills</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">((</span><span style="color: #3364a4;">CharacterSheetActivity</span><span style="color: #333333;">)</span><span style="color: #009695;">this</span><span style="color: #333333;">.</span><span style="color: #333333;">Activity</span><span style="color: #333333;">)</span><span style="color: #333333;">.</span><span style="color: #333333;">CharacterInformation</span><span style="color: #333333;">.</span><span style="color: #333333;">Skills</span><span style="color: #333333;">;</span></span><br /><span style="font-family: Menlo;">
<span style="color: #333333;"> </span><span style="color: #333333;">view</span><span style="color: #333333;">.</span><span style="color: #333333;">Adapter</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">ArrayAdapter</span><span style="color: #333333;"><</span><span style="color: #009695;">string</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">this</span><span style="color: #333333;">.</span><span style="color: #333333;">Activity</span><span style="color: #333333;">,</span><span style="color: #333333;">Android</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Layout</span><span style="color: #333333;">.</span><span style="color: #333333;">SimpleListItem1</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;">skills</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span><br /><span style="font-family: Menlo;">
</span><br /><span style="font-family: Menlo;">
<span style="color: #333333;"> </span><span style="color: #009695;">return</span><span style="color: #333333;"> </span><span style="color: #333333;">root</span><span style="color: #333333;">;</span></span><br /><span style="font-family: Menlo;">
</span><br /><span style="font-family: Menlo;">
<span style="color: #333333;"> </span><span style="color: #333333;">}</span></span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;"> Pretty straight forward, and shows at least a starting point:</span></span></span><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXLPuFKFON0MWb603IZrTUmZpbHwhVScEtMUYkxUfZWZND7FEHZ2fr_E7ZLuy4LwPDkvtq6JXGInjGSRWtm9nEg1qAiUY6u54ebU2EaPjBYkYhiYRuEyUqWEspxPFiuEk4yLIzX78Hm5U/s1600/Skills_stringsOnly.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXLPuFKFON0MWb603IZrTUmZpbHwhVScEtMUYkxUfZWZND7FEHZ2fr_E7ZLuy4LwPDkvtq6JXGInjGSRWtm9nEg1qAiUY6u54ebU2EaPjBYkYhiYRuEyUqWEspxPFiuEk4yLIzX78Hm5U/s320/Skills_stringsOnly.png" width="180" /></a><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;"> </span></span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;">We have a successful ListView! Now to add the Custom Adapter. In this case, I want to display not only the name, but the ability mod score, whether or not the character is trained, and then the final value. (Mod + Proficiency)</span></span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;">The adapter is set up and in order. The first challenge I ran into was getting my items to not clump together. RelativeLayout was not really an option here, so a little searching I discovered one effective option was to use the "Weight" tag to give each item equal weight within the control. </span></span></span><br />
<br />
<span style="font-family: Menlo;">
<span style="color: #333333; font-size: x-small;"> </span></span><br />
<br />
<br />
<br />
<br />
<br />
<span style="font-family: Menlo;"><span style="color: #333333; font-size: x-small;"><</span><span style="color: #3364a4; font-size: x-small;">LinearLayout</span><span style="color: #3364a4; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">xmlns:android</span><span style="color: #333333; font-size: x-small;">=</span><span style="color: #f57d00; font-size: x-small;">"</span><span style="color: #f57d00; font-size: x-small;">http</span><span style="color: #f57d00; font-size: x-small;">:</span><span style="color: #f57d00; font-size: x-small;">/</span><span style="color: #f57d00; font-size: x-small;">/</span><span style="color: #f57d00; font-size: x-small;">schemas</span><span style="color: #f57d00; font-size: x-small;">.</span><span style="color: #f57d00; font-size: x-small;">android</span><span style="color: #f57d00; font-size: x-small;">.</span><span style="color: #f57d00; font-size: x-small;">com</span><span style="color: #f57d00; font-size: x-small;">/</span><span style="color: #f57d00; font-size: x-small;">apk</span><span style="color: #f57d00; font-size: x-small;">/</span><span style="color: #f57d00; font-size: x-small;">res</span><span style="color: #f57d00; font-size: x-small;">/</span><span style="color: #f57d00; font-size: x-small;">android</span><span style="color: #f57d00; font-size: x-small;">"</span><span style="font-size: x-small;"><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:orientation</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">horizontal</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_width</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">match_parent</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_height</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">match_parent</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:padding</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">5dp</span><span style="color: #f57d00;">"</span><span style="color: #333333;">></span><br />
<span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #3364a4;">TextView</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:id</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">id</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">skillName</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_width</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_height</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:text</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">Placeholder</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_weight</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">1</span><span style="color: #f57d00;">"</span><span style="color: #3364a4;"> </span><span style="color: #333333;">/</span><span style="color: #333333;">></span><br />
<span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #3364a4;">TextView</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:id</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">id</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">modValue</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_width</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_height</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_weight</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">1</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:text</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">3</span><span style="color: #f57d00;">"</span><span style="color: #3364a4;"> </span><span style="color: #333333;">/</span><span style="color: #333333;">></span><br />
<span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #3364a4;">CheckBox</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:id</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">id</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">isTrained</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_width</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">32</span><span style="color: #f57d00;">.</span><span style="color: #f57d00;">0dp</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_height</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_weight</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">1</span><span style="color: #f57d00;">"</span><span style="color: #3364a4;"> </span><span style="color: #333333;">/</span><span style="color: #333333;">></span><br />
<span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #3364a4;">TextView</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:id</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">id</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">totalValue</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_width</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_height</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_weight</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">1</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:text</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">5</span><span style="color: #f57d00;">"</span><span style="color: #3364a4;"> </span><span style="color: #333333;">/</span><span style="color: #333333;">></span><br />
<span style="color: #333333;"><</span><span style="color: #333333;">/</span><span style="color: #3364a4;">LinearLayout</span><span style="color: #333333;">></span></span></span>
<br />
<br />
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;">In theory that worked well, but then I realized I had a problem once I got the final result running.</span></span></span><br />
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;"><br /></span></span></span>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZj2fhl5RUG7YlLDpDQm5WC7pqV8WIgwpdvrXCFcs35UuME2ry_T0HYgWJ01LXZtQqvX_4auGEOenTI1dXKg7g6yEmlxAj8bPC4hLkwGKD04L_kk10H3Xb5r1AW1yhOObjgHhEKnJHg6w/s1600/Layout.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="139" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZj2fhl5RUG7YlLDpDQm5WC7pqV8WIgwpdvrXCFcs35UuME2ry_T0HYgWJ01LXZtQqvX_4auGEOenTI1dXKg7g6yEmlxAj8bPC4hLkwGKD04L_kk10H3Xb5r1AW1yhOObjgHhEKnJHg6w/s320/Layout.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Looks Perfect</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgls-r_UxeRBFnnWIE9ipsCeyUBK4Txmbur3JOXoqfGRUwMGiK0E8wtXWvUy889GXMlVdEK0h0hpln2DFX1LAs5m_-vF9rg9aZvzG-gxaTcT31W3-iSfUgHvN5wKukAxXyUtuGYXdWHod8/s1600/Skills_listview_Adapter.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgls-r_UxeRBFnnWIE9ipsCeyUBK4Txmbur3JOXoqfGRUwMGiK0E8wtXWvUy889GXMlVdEK0h0hpln2DFX1LAs5m_-vF9rg9aZvzG-gxaTcT31W3-iSfUgHvN5wKukAxXyUtuGYXdWHod8/s320/Skills_listview_Adapter.png" width="180" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Maybe I need to think this through...</td></tr>
</tbody></table>
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">As the weights are row specific, it does not help align each column. Once again, for implementation and times sake I decided to call that "good enough" for now. </span></span></span><br />
<br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">The next step was to work on my back end code. As can be seen in the above, I am hard coding all of my values, and no hookup event for the proficiency checkbox. This actually required a lot of back end work, which was good to revisit and clean up the data. </span></span></span><br />
<br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"> Now, I will preface by saying I do not admit this code will be the best. I'm playing more of the functional over proper card here. As a side project it will regularly be a work in progress. </span></span></span><br />
<br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">I created both a Skill and SkillsList class on my back end. The reason for the latter is it gave me a collection that I could house some of the more static concepts like what skills have what ability mods, and a fully populated list of all possible names. Again, not proud of it, but its functional. Then, at launch all possible skills are preloaded based on starting stats. This gives me all my initial conditions that I access as accessor methods. (Loading data I will revisit at a later point).</span></span></span><br />
<br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">From an input standpoint the two big changes I needed to make sure happened were </span></span></span><br />
<br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">a) update final values as proficiency was enabled</span></span></span><br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">b) update mods when ability scores are changed.</span></span></span><br />
<br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">For the first, I did an inline set of code, pretty straight forward.</span></span></span><br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><br /></span></span></span>
<br />
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="color: #333333; font-size: x-small;">proficient</span><span style="color: #333333; font-size: x-small;">.</span><span style="color: #333333; font-size: x-small;">CheckedChange</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">+=</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">(</span><span style="color: #009695; font-size: x-small;">object</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">sender</span><span style="color: #333333; font-size: x-small;">,</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #3364a4; font-size: x-small;">CompoundButton</span><span style="color: #333333; font-size: x-small;">.</span><span style="color: #3364a4; font-size: x-small;">CheckedChangeEventArgs</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">e</span><span style="color: #333333; font-size: x-small;">)</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">=</span><span style="color: #333333; font-size: x-small;">></span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;"> </span></span><br />
<span style="font-family: Menlo; font-size: x-small;"><span style="color: #333333;">{<span style="font-family: Menlo;"><span style="color: #3364a4;"> </span></span></span></span><br />
<span style="font-family: Menlo; font-size: x-small;"><span style="color: #333333;"><span style="font-family: Menlo;"><span style="color: #3364a4;"> CharacterSheet</span><span style="color: #333333;"> </span><span style="color: #333333;">sheet</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">((</span><span style="color: #3364a4;">CharacterSheetActivity</span><span style="color: #333333;">)</span><span style="color: #333333;">_context</span><span style="color: #333333;">)</span><span style="color: #333333;">.</span><span style="color: #333333;">CharacterInformation</span><span style="color: #333333;">;</span></span>
</span><br /> </span><span style="font-size: x-small;">
<span style="font-family: Menlo;">
<span style="color: #333333;">sheet</span><span style="color: #333333;">.</span><span style="color: #333333;">Skills</span><span style="color: #333333;">[</span><span style="color: #333333;">position</span><span style="color: #333333;">]</span><span style="color: #333333;">.</span><span style="color: #333333;">IsProficient</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">e</span><span style="color: #333333;">.</span><span style="color: #333333;">IsChecked</span><span style="color: #333333;">;</span></span></span><br />
<span style="font-family: Menlo; font-size: x-small;"><span style="color: #333333;">
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="color: #333333;"> skillMod</span><span style="color: #333333;">.</span><span style="color: #333333;">Text</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">sheet</span><span style="color: #333333;">.</span><span style="color: #333333;">Skills</span><span style="color: #333333;"> </span><span style="color: #333333;">[</span><span style="color: #333333;">position</span><span style="color: #333333;">]</span><span style="color: #333333;">.</span><span style="color: #333333;">TotalValue</span><span style="color: #333333;"> </span><span style="color: #333333;">+</span><span style="color: #333333;"> </span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">"</span><span style="color: #333333;">;</span></span>
</span></span><span style="font-family: Menlo; font-size: x-small;"><span style="color: #333333;"><span style="font-family: Menlo;"><span style="color: #333333;"></span></span>
</span><span style="color: #333333;"></span><br /><span style="color: #333333;"></span><span style="color: #333333;">}</span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">On the flip side, with all of my Attribute code, I added this line:</span></span><br />
<br />
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="font-size: x-small;"><span style="color: #333333;">character</span><span style="color: #333333;">.</span><span style="color: #333333;">UpdateSkills</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Attributes</span><span style="color: #333333;">.</span><span style="color: #3364a4;">AttributeName</span><span style="color: #333333;">.</span><span style="color: #333333;">STR</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span></span><br />
<br />
<span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="color: #333333;">Which is essentially calling an update method within my SkillsList:</span></span></span>
<br />
<span style="color: #333333;"><span style="font-size: small;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"></span></span></span><br />
<span style="font-size: x-small;"><span style="font-family: Menlo;"><span style="color: #333333;"></span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">void</span><span style="color: #333333;"> </span><span style="color: #333333;">UpdateSkillMod</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Attributes</span><span style="color: #333333;">.</span><span style="color: #3364a4;">AttributeName</span><span style="color: #333333;"> </span><span style="color: #333333;">type</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #009695;">int</span><span style="color: #333333;"> </span><span style="color: #333333;">mod</span><span style="color: #333333;">)</span></span></span><br />
<span style="font-size: x-small;"><span style="font-family: Menlo;"><span style="color: #333333;"></span><span style="color: #333333;">{</span><br /> <span style="color: #333333;"></span><span style="color: #009695;">foreach</span><span style="color: #333333;">(</span><span style="color: #3364a4;">Skill</span><span style="color: #333333;"> skill </span><span style="color: #009695;">in</span><span style="color: #333333;"> </span><span style="color: #333333;">_skills</span><span style="color: #333333;">)</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><span style="color: #333333;"> </span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">if</span><span style="color: #333333;">(</span><span style="color: #333333;">skill</span><span style="color: #333333;">.</span><span style="color: #333333;">ModType</span><span style="color: #333333;"> </span><span style="color: #333333;">==</span><span style="color: #333333;"> </span><span style="color: #333333;">type</span><span style="color: #333333;">)</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">skill</span><span style="color: #333333;">.</span><span style="color: #333333;">ModValue</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">mod</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span><br /><span style="color: #333333;"></span><span style="color: #333333;">}</span></span></span><br />
<br />
<span style="font-size: x-small;"><span style="font-family: Menlo;"><span style="color: #333333;"><span style="font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;"><span style="font-size: small;">This is simply an enumeration through all skills that updates the ModValue of the associated type. That gets us to our final version, which we will hold with for now.</span></span></span></span></span><br />
<span style="font-size: x-small;"><span style="font-family: Menlo;"><span style="font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQcWpjeTSeNbW97blVB5-v0zK386h2WriPn4ZQsPbEGHgKj8jJhRud8EqiZkMUjDZTJEYxc0fIAKDgYnmAtKqfpckO_DUDTigXXvUw8CwlyvVonQkUrqRZ1pHDINLlag-nkV3vkHQuF_E/s1600/Skills_Nowwithmods.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQcWpjeTSeNbW97blVB5-v0zK386h2WriPn4ZQsPbEGHgKj8jJhRud8EqiZkMUjDZTJEYxc0fIAKDgYnmAtKqfpckO_DUDTigXXvUw8CwlyvVonQkUrqRZ1pHDINLlag-nkV3vkHQuF_E/s320/Skills_Nowwithmods.png" width="180" /></a><br />On the back end I also did a lot of cleanup for better preparation for when I need to load character data. At this point I am going to call the Android version of the app in a good spot and now move to get an iOS skin running with this.</span></span></span></span>Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com0tag:blogger.com,1999:blog-7888235610450058747.post-87994835403315575492015-08-14T15:37:00.000-07:002015-08-14T15:46:21.873-07:00Implementing the Toolbar and Scrolling Tabs<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">After spending a lot of time working on what was essentially a single page view, I felt like I had enough blocked functionality to really start broadening my horizons. There is too much data on a single character sheet to warrant it all on one view, nor would that make for pretty UI Code.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">As a reference, here is what we are basing everything off of, pulled straight from the <a href="http://dnd.wizards.com/articles/features/character_sheets">Dungeons and Dragons Website</a></span></span><br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEBw80Tl8AiXk8Xd2SR4pPyTKXR8m0OcEamsvWAdRkJbGjN4EbVLRK8as9xPFWau185NLIOL4ppwWUG2U4HkSJOxW7_K-CBwGnNMblsRNP4rs-jqXv9_uNpKnDsdL-nQIGcSOe1QBNxE0/s1600/Screenshot+2015-07-28+14.07.47.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEBw80Tl8AiXk8Xd2SR4pPyTKXR8m0OcEamsvWAdRkJbGjN4EbVLRK8as9xPFWau185NLIOL4ppwWUG2U4HkSJOxW7_K-CBwGnNMblsRNP4rs-jqXv9_uNpKnDsdL-nQIGcSOe1QBNxE0/s320/Screenshot+2015-07-28+14.07.47.png" width="247" /> </a></span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">This does not include the spells page, that will be its own beast that I will tackle later, but there are some logical groupings of information that we can use. What makes the most sense is to add a Tab Control based layout to scroll through sections of information.</span></span></div>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">First step was the Toolbar. I wanted to try to use all the new latest and greatest and was previously using an ActionBar. Luckily James Montemagno gave a great overview for adding a Toolbar to your app to replace the ActionBar, I suggest starting with a read there:</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><a href="https://blog.xamarin.com/android-tips-hello-toolbar-goodbye-action-bar/">https://blog.xamarin.com/android-tips-hello-toolbar-goodbye-action-bar/</a></span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">From a visual side of things everything looked roughly the same, but gives me greater flexibility in the long run. Next step was to add new menu items. I have learned that Android really likes its .xml files and menus are no different. For now, we will start with a new, save and load button. For spacial consideration I am just showing the add button for now, but it gives the app a nice look I think:</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1gc8Is-2zuhTFirXE-vtcgEFGWP-Tc5PG1bKWlF55XW_LbGFkJINAqoYk9pmV1xT4VVZNxhck7ydMWSIycSgyHJK04EiBCP_13-G_WzaJGwMjTba1xyzuYx_6Jh2FKq20jNIz9xzHxec/s1600/New_Home.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1gc8Is-2zuhTFirXE-vtcgEFGWP-Tc5PG1bKWlF55XW_LbGFkJINAqoYk9pmV1xT4VVZNxhck7ydMWSIycSgyHJK04EiBCP_13-G_WzaJGwMjTba1xyzuYx_6Jh2FKq20jNIz9xzHxec/s320/New_Home.png" width="180" /> </a></span></span></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">I also am going to remove the floating action button for the time being. I have some ideas for it down the line, but likely will only resurface once I get a more complete product (much later).</span></span></div>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">The next step was to add a TabLayout to the toolbar. I also wanted to include both tap
and swipe navigation as it adds a logical flow to the app. This is where
I also had to learn about fragments and ViewPagers. This definitely took a bit of research as there were a number of parts to get a handle on.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">From
a high level overview, Fragments are a way for Android to both
compartmentalize UI into component pieces, to allow you to better
support multiple screen sizes, and just break down your UI easier. A
good overview that helped me can be found here:</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><a href="http://developer.xamarin.com/guides/android/platform_features/fragments/">http://developer.xamarin.com/guides/android/platform_features/fragments/</a></span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">To create my desired setup, this guide on the Android developer docs was highly valuable:</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><a href="http://developer.android.com/training/implementing-navigation/lateral.html">http://developer.android.com/training/implementing-navigation/lateral.html</a></span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">You
break it down by having your TabLayout add 2+ ViewPager objects to
represent each tab. Each ViewPager object is going to be a unique
Fragment on the back end, or basically a UI view. Really cool stuff.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">So
the first thing I need to do is set up each of my ViewPager objects, so
that they are grouped together and can be "swipable". The following
code handles all of that.</span></span><br />
<span style="font-size: small;"><br /></span>
<span style="font-family: inherit; font-size: small;">
<span style="font-family: Menlo;">
<span style="color: #009695; font-size: x-small;">var</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">viewPager</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">=</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">FindViewById</span><span style="color: #333333; font-size: x-small;"><</span><span style="color: #3364a4; font-size: x-small;">ViewPager</span><span style="color: #333333; font-size: x-small;">></span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">(</span><span style="color: #3364a4; font-size: x-small;">Resource</span><span style="color: #333333; font-size: x-small;">.</span><span style="color: #3364a4; font-size: x-small;">Id</span><span style="color: #333333; font-size: x-small;">.</span><span style="color: #333333; font-size: x-small;">viewPager</span><span style="color: #333333; font-size: x-small;">)</span><span style="color: #333333; font-size: x-small;">;</span><span style="font-size: x-small;"><br /><span style="color: #333333;">SetupViewPagers</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">viewPager</span><span style="color: #333333;">);</span></span></span></span><br />
<span style="font-size: x-small;"><br /></span>
<span style="font-family: inherit; font-size: x-small;"><span style="font-family: Menlo;"><span style="color: #333333;"><span style="font-family: Menlo;"><span style="color: #009695;">private</span><span style="color: #333333;"> </span><span style="color: #009695;">void</span><span style="color: #333333;"> </span><span style="color: #333333;">SetupViewPagers</span><span style="color: #333333;">(</span><span style="color: #3364a4;">ViewPager</span><span style="color: #333333;"> </span><span style="color: #333333;">viewPager</span><span style="color: #333333;">)</span><br /><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">adapter</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">MyAdapter</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">SupportFragmentManager</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">adapter</span><span style="color: #333333;">.</span><span style="color: #333333;">AddFragment</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">CharSheetOverviewFragment</span><span style="color: #333333;"> </span><span style="color: #333333;">()</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">Overview</span><span style="color: #f57d00;">"</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">adapter</span><span style="color: #333333;">.</span><span style="color: #333333;">AddFragment</span><span style="color: #333333;">(</span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">CharSheetSkillsFragment</span><span style="color: #333333;">()</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">Skills</span><span style="color: #f57d00;">"</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">viewPager</span><span style="color: #333333;">.</span><span style="color: #333333;">Adapter</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">adapter</span><span style="color: #333333;">;</span><br /><span style="color: #333333;">}</span></span></span></span></span><br />
<span style="font-size: small;"><br /></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><span style="color: #333333;"><span style="color: #333333;">This
will create my ViewPager object, where the SetupViewPagers method
creates each individual Page, and then sets the adapter to group them
together. The final result is a ViewPager object, or a number of views
that are side by side and have built in scrolling. Pretty neat.
SupportFragmentManager is a predefined Adapter provided by the Android
Support Package that we need to set all this up. the viewPager resource
is simply something that I added to my main .axml file that will house
the ViewPager spells.</span></span></span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><span style="color: #333333;"><span style="color: #333333;">From
there you are following the same process as normal. You create a
Fragment .axml file and a correspoding Activity class to load it. The
difference being instead of inheriting from "Activity" you are
inheriting from Fragment. Your OnCreateView method inflates the fragment
UI and returns the view.</span></span></span></span><br />
<span style="font-family: Menlo; font-size: small;"><span style="color: #333333;"> </span><span style="color: #009695; font-size: x-small;">public</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #009695; font-size: x-small;">override</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #3364a4; font-size: x-small;">View</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">OnCreateView</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">(</span><span style="color: #3364a4; font-size: x-small;">LayoutInflater</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">inflater</span><span style="color: #333333; font-size: x-small;">,</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #3364a4; font-size: x-small;">ViewGroup</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">container</span><span style="color: #333333; font-size: x-small;">,</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #3364a4; font-size: x-small;">Bundle</span><span style="color: #333333; font-size: x-small;"> </span><span style="color: #333333; font-size: x-small;">savedInstanceState</span><span style="color: #333333; font-size: x-small;">)</span></span><br />
<span style="font-family: Menlo; font-size: x-small;"><span style="color: #333333;">{</span></span><br />
<span style="font-family: Menlo; font-size: x-small;"><span style="color: #009695;"> var</span><span style="color: #333333;"> </span><span style="color: #333333;">root</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">inflater</span><span style="color: #333333;">.</span><span style="color: #333333;">Inflate</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Layout</span><span style="color: #333333;">.</span><span style="color: #333333;">fragment_charsheet_overview</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;"><br />container</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #009695;">false</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br /> <span style="color: #009695;">return</span><span style="color: #333333;"> </span><span style="color: #333333;">root</span><span style="color: #333333;">;</span><br /><span style="color: #333333;">}</span></span><br />
<span style="font-size: small;"><br /></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">One of the cool side effects of using Fragments is they also maintain a reference to the parent Activity which loaded them. So in my case, the parent Activity, a CharacterSheetView has a loaded set of character Data. Each of my fragments can pull from that data by using this.Activity.</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">A view of what we see now can be found below, I have been updating some of the code to modify how my attributes are being displayed, moving from a TableLayout to GridLayout</span></span><br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv9pSPkqot5XXof5BFmK_eZZ0LJBvMcoIW-duafoP2GriMHLTNUyAsBCMqQJ7RHxBnZVlUT36KO4CqrCqYiqOB-Fd3qf1t7hLzpqdCPv6PfqHEh94PLXcSgyoJV36cxjn8Tjm7rVRbLX8/s1600/Nexus+5+%2528Lollipop%2529+Screenshot+1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv9pSPkqot5XXof5BFmK_eZZ0LJBvMcoIW-duafoP2GriMHLTNUyAsBCMqQJ7RHxBnZVlUT36KO4CqrCqYiqOB-Fd3qf1t7hLzpqdCPv6PfqHEh94PLXcSgyoJV36cxjn8Tjm7rVRbLX8/s320/Nexus+5+%2528Lollipop%2529+Screenshot+1.png" width="180" /></a></span></span>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVAye00ETl0CV6LbsqhPmns1MRlpWD9FLqgcP8k6IiqgUPoaHXQHpZBhk8GVIfiWFAceqHDgxGoU4TcFOlfnVbK5yL6lmn-J7Qlh70rsCDYTYLhKcll1bEoCbDESTabBCuKCFtKxH37g/s1600/Nexus+5+%2528Lollipop%2529+Screenshot+2.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVAye00ETl0CV6LbsqhPmns1MRlpWD9FLqgcP8k6IiqgUPoaHXQHpZBhk8GVIfiWFAceqHDgxGoU4TcFOlfnVbK5yL6lmn-J7Qlh70rsCDYTYLhKcll1bEoCbDESTabBCuKCFtKxH37g/s320/Nexus+5+%2528Lollipop%2529+Screenshot+2.png" width="180" /></a></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;">I
am going to spend a little more time polishing the attribute list and
then actually look to start replicating this in iOS to help broaden my
skillset. I do know that I will likely use a ListView for the skills so I
may just tackle that next. We will see.</span></span></div>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><span style="font-size: small;"><br /></span>
</span><span style="font-size: small;"><br /></span>Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com0tag:blogger.com,1999:blog-7888235610450058747.post-33925961836372294412015-07-31T08:39:00.000-07:002015-07-31T08:39:05.922-07:00Data Validation of Numeric Edit Text in AndroidAfter spending some time to learn Material design, I felt it would be worth my time to take a break and focus on actually getting data onto my app and start progressing, then do a design pass later. I was churning my wheels trying to get all the character attributes set up and decided it was best to just get something on paper. I settled on a TableLayout to organize the labels from the character attributes and modifiers. I also did a bit of playing with design and cleanup and had something at least organized:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaPaidkWSrialN-TtPiuxf60_Li7nDDbr8QF5SfedZmwfPoLyzUnxZMHXoBsOBI-v1kV3LkE8-vh5JDin4R54KSBylZxzRPcOnwaAvIsASGvvdXjZWnI2Ib2GDwRTM_ilC3hqOImGnB7Q/s1600/Screenshot+2015-07-16+15.18.03.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaPaidkWSrialN-TtPiuxf60_Li7nDDbr8QF5SfedZmwfPoLyzUnxZMHXoBsOBI-v1kV3LkE8-vh5JDin4R54KSBylZxzRPcOnwaAvIsASGvvdXjZWnI2Ib2GDwRTM_ilC3hqOImGnB7Q/s400/Screenshot+2015-07-16+15.18.03.png" width="217" /></a>Overall this is rather respectable, it has a semi clean look and gives logical organization of the data. Am I in love with it? No, but it is something. The biggest challenge was getting the labels to stretch across the entirety of the view, instead of getting clumped. It took a bit of searching, but I found this attribute:<br />
<br />
<span style="font-family: Menlo;">
<span style="color: #3364a4;"></span><span style="color: #333333;">android:stretchColumns</span></span>
<br />
<br />
Which made all the difference. It allowed me to get the desired spread. I likely should revisit the spacing size of the central Numeric EditText but since this is more placeholder I say sufficient for now.<br />
<br />
The next big step was setting it so that when the user sets his Attribute value, it would auto update the modifier on the back end. The initial setup was not terrible, you hook up a "TextChanged" event handler, grab the values, update accordingly.<br />
<br />
<span style="font-family: Menlo;">
<span style="font-size: x-small;"><span style="color: #333333;"> </span><span style="color: #009695;">void</span><span style="color: #333333;"> </span><span style="color: #333333;">OnStrengthChanged</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">object</span><span style="color: #333333;"> </span><span style="color: #333333;">sender</span><span style="color: #333333;">,</span><span style="color: #333333;"> Android</span><span style="color: #333333;">.</span><span style="color: #333333;">Text</span><span style="color: #333333;">.</span><span style="color: #3364a4;">TextChangedEventArgs</span><span style="color: #333333;"> </span><span style="color: #333333;">e</span><span style="color: #333333;">)</span><br /><span style="color: #333333;"></span><span style="color: #333333;">{</span><span style="color: #333333;"></span><span style="color: #009695;"> </span></span></span><br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #009695;"> var</span><span style="color: #333333;"> </span><span style="color: #333333;">numField</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">EditText</span><span style="color: #333333;">)</span><span style="color: #333333;">sender</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">value</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">int</span><span style="color: #333333;">.</span><span style="color: #333333;">Parse</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">numField</span><span style="color: #333333;">.</span><span style="color: #333333;">Text</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> characterData</span><span style="color: #333333;">.</span><span style="color: #333333;">SetSingleAttribute</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">Attributes</span><span style="color: #333333;">{</span><span style="color: #333333;"> Strength </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">value</span><span style="color: #333333;"> </span><span style="color: #333333;">})</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">mod</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">FindViewById</span><span style="color: #333333;"><</span><span style="color: #3364a4;">TextView</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Id</span><span style="color: #333333;">.</span><span style="color: #333333;">strengthMod</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">mod</span><span style="color: #333333;">.</span><span style="color: #333333;">Text</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">testCharacter</span><span style="color: #333333;">.</span><span style="color: #333333;">FinalAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">StrengthModifier</span><span style="color: #333333;">.</span><span style="color: #333333;">ToString</span><span style="color: #333333;"> </span><span style="color: #333333;">()</span><span style="color: #333333;">;</span></span></span><br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #333333;"></span><span style="color: #333333;">}</span></span></span><br />
<br />
Overall, rather straight forward. I currently store Attributes as a single object that contains the individual properties for both Values and modifiers, basically a special array container with some validation inside. "characterData" is my storage for all applicable data. All of that is defined in my shared PCL. I think this is an area that could use a refactor. Currently my SetSingleAttribute is something like this:<br />
<span style="font-size: x-small;"><br /></span>
<span style="font-size: x-small;">
</span><span style="font-family: Menlo;"><span style="font-size: x-small;">
<span style="color: #333333;"> </span><span style="color: #009695;">public</span><span style="color: #333333;"> </span><span style="color: #009695;">void</span><span style="color: #333333;"> </span><span style="color: #333333;">SetSingleAttribute</span><span style="color: #333333;">(</span><span style="color: #3364a4;">Attributes</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">)</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">{</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Strength</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Strength</span><span style="color: #333333;"> </span><span style="color: #333333;">==</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;"> </span><span style="color: #333333;">?</span><span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Strength</span><span style="color: #333333;"> </span><span style="color: #333333;">:</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Strength</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Dexterity</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Dexterity</span><span style="color: #333333;"> </span><span style="color: #333333;">==</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;"> </span><span style="color: #333333;">?</span><span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Dexterity</span><span style="color: #333333;"> </span><span style="color: #333333;">:</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Dexterity</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Constitution</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Constitution</span><span style="color: #333333;"> </span><span style="color: #333333;">==</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;"> </span><span style="color: #333333;">?</span><span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Constitution</span><span style="color: #333333;"> </span><span style="color: #333333;">:</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Constitution</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Intelligence</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Intelligence</span><span style="color: #333333;"> </span><span style="color: #333333;">==</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;"> </span><span style="color: #333333;">?</span><span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Intelligence</span><span style="color: #333333;"> </span><span style="color: #333333;">:</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Intelligence</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Wisdom</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Wisdom</span><span style="color: #333333;"> </span><span style="color: #333333;">==</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;"> </span><span style="color: #333333;">?</span><span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Wisdom</span><span style="color: #333333;"> </span><span style="color: #333333;">:</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Wisdom</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Charisma</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Charisma</span><span style="color: #333333;"> </span><span style="color: #333333;">==</span><span style="color: #333333;"> </span><span style="color: #f57d00;">0</span><span style="color: #333333;"> </span><span style="color: #333333;">?</span><span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Charisma</span><span style="color: #333333;"> </span><span style="color: #333333;">:</span><span style="color: #333333;"> </span><span style="color: #333333;">attributes</span><span style="color: #333333;">.</span><span style="color: #333333;">Charisma</span><span style="color: #333333;">;</span><br />
<br />
<span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">baseAttributes</span><span style="color: #333333;"> </span><span style="color: #333333;">-</span><span style="color: #333333;"> </span><span style="color: #333333;">Race</span><span style="color: #333333;">.</span><span style="color: #333333;">BonusAttributes</span><span style="color: #333333;">;</span><br />
<span style="color: #333333;"> </span><span style="color: #333333;">}</span></span></span><br />
<br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"></span></span><br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"></span></span><br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"></span></span><br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"></span></span><br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"></span></span><br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #333333;"></span></span></span>Basically I find the attribute that has been modified as all the others have been nulled out. I need to spend some more time on this, especially once I implement racial and feat bonuses. For now, it gets things moving forward while I block out all the data.<br />
<br />
One challenge that I ran into was editing attribute values. The default behavior when clicking these fields (as they are just text fields) is to allow the user to edit the entry. To handle the scenario where a user deletes the existing values, I was running into an awkward case of trying to convert an empty string to a number, which does not work very well, and left an unintuitive experience. What I did to solve it was set the fields "Hint" parameter:<br />
<br />
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="font-size: x-small;"><span style="color: #333333;">strValue</span><span style="color: #333333;">.</span><span style="color: #333333;">Hint</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">8</span><span style="color: #f57d00;">"</span><span style="color: #333333;">;</span></span></span><span style="font-size: x-small;"> </span><br />
<br />
Then you get a nice greyed out sample field, without disrupting your flow:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKuuo7z3kBe-DWW_Mji4BHewc7E3AaBsooDrgGRly8Jj9dvJp001nlXCQ5NZjK4ZYlsLdTC4ucsZjOm7r0eYdyOdsCKeWa1ce5BG_vMYhE-tC6s34pMzucrHCxMlLoThGPyysPPXZtpU0/s1600/Screenshot+2015-07-27+13.38.05.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKuuo7z3kBe-DWW_Mji4BHewc7E3AaBsooDrgGRly8Jj9dvJp001nlXCQ5NZjK4ZYlsLdTC4ucsZjOm7r0eYdyOdsCKeWa1ce5BG_vMYhE-tC6s34pMzucrHCxMlLoThGPyysPPXZtpU0/s1600/Screenshot+2015-07-27+13.38.05.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">As you can see, there is a nice greyed entry, more intuitive.</td><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
This is definitely coming along well. For some preliminary data validation I also set maxLength to 2 to prevent numbers larger than 2 digits. Ideally I should limit to something like 6-20 as per the rules, but it is a start. As a note, a more complete complete implementation would use either a custom class of EditText or InputFilters.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com0tag:blogger.com,1999:blog-7888235610450058747.post-34430955034539797772015-07-17T10:00:00.000-07:002015-07-17T13:42:18.106-07:00Creating Custom Views with a SpinnerThe next step in my app was making a quick cosmetic change. If you
recall my drop downs for Race and Character classes were left text
aligned. This is due to the default Resource settings I was used at its
creation. Creating spinners, there are two layout settings that I
discovered you can play with.<br />
<br />
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="font-size: x-small;"><span style="color: #3364a4;">Spinner</span><span style="color: #333333;"> </span><span style="color: #333333;">races</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #333333;">FindViewById</span><span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #3364a4;">Spinner</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Id</span><span style="color: #333333;">.</span><span style="color: #333333;">charRace</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span></span>
<br />
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="font-size: x-small;"><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">adapter</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">ArrayAdapter</span><span style="color: #333333;"><</span><span style="color: #009695;">string</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">this</span><span style="color: #333333;">, </span></span></span><span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #333333;"><span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #333333;">Android</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Layout</span><span style="color: #333333;">.</span><span style="color: #333333;">SimpleSpinnerItem1</span></span></span></span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;">items</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span><br /><span style="color: #333333;"></span><span style="color: #333333;">adapter</span><span style="color: #333333;">.</span><span style="color: #333333;">SetDropDownViewResource</span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #333333;">Android</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Layout</span><span style="color: #333333;">.</span><span style="color: #333333;">SimpleSpinnerDropDownItem</span><span style="color: #333333;"> </span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span></span><br />
<br />
When you create a Spinner control, you have to set its adapter, which basically determines how it displays the data added, and will tell the Spinner what type of data objects it should expect. The above was my original code.<br />
<br />
The first line finds the Spinner in the Android Resources, the second initializes the Adapter to contain/expect an array of type string, and the third sets the display of the individual items when you click the spinner and dropdown. Digging around, I learned it should be as simple as overriding the default Android.Resource.Layout to use a custom layout instead of a default one. Pretty straightforward right? So I created a new android .axml called spinner_item with the following code:<br />
<br />
<span style="font-family: Menlo;">
<span style="font-size: x-small;"><span style="color: #009695;"><span style="color: #333333;">xml</span><span style="color: #333333;"> </span><span style="color: #333333;">version</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">1</span><span style="color: #f57d00;">.</span><span style="color: #f57d00;">0</span><span style="color: #f57d00;">"</span><span style="color: #333333;"> </span><span style="color: #333333;">encoding</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">utf</span><span style="color: #f57d00;">-</span><span style="color: #f57d00;">8</span><span style="color: #f57d00;">"</span><span style="color: #009695;">?></span><br />
<span style="color: #333333;"><</span><span style="color: #3364a4;">TextView</span><span style="color: #3364a4;"> </span><span style="color: #333333;">xmlns:android</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">http</span><span style="color: #f57d00;">:</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">schemas</span><span style="color: #f57d00;">.</span><span style="color: #f57d00;">android</span><span style="color: #f57d00;">.</span><span style="color: #f57d00;">com</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">apk</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">res</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">android</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_width</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">match_parent</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_height</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">match_parent</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:gravity</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">right</span><span style="color: #f57d00;">"</span><span style="color: #3364a4;"> </span><span style="color: #333333;">/</span><span style="color: #333333;">></span></span></span></span><br />
<br />
as all I needed was right aligned text. Problem was, when I tried to reference it, I was getting compile errors:<br />
<br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">adapter</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">ArrayAdapter</span><span style="color: #333333;"><</span><span style="color: #009695;">string</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">this</span><span style="color: #333333;">, </span></span></span><span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #333333;"><span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #333333;">Android</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Layout</span><span style="color: #333333;">.spinner_item</span><span style="color: #333333;"></span></span></span></span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;">items</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span></span><br />
<br />
<span style="font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #333333;"></span></span></span>This was confusing as everything I read said this should work. It was then, digging through Xamarins documentation that I realized I was missing something:<br />
<br />
<a href="http://developer.xamarin.com/guides/android/application_fundamentals/resources_in_android/part_1_-_android_resource_basics/">http://developer.xamarin.com/guides/android/application_fundamentals/resources_in_android/part_1_-_android_resource_basics/ </a><br />
<br />
When referencing resources programmatically (in code), they can be accessed via the Resources class hierarchy which uses the following syntax:<br />
@[<packagename>.]Resource.<resourcetype>.<resourcename></resourcename></resourcetype></packagename><br />
<br />
I noticed I was using Android.Resource.Layout, key word being "ANDROID", or the default resources. Since I was using resources local to my own project, I could just say<br />
<br />
Resource.Layout.spinner_item and this would find my new custom layout. Adding that we get this:<br />
<span style="font-family: Menlo;">
<span style="color: #333333;"></span><span style="font-size: x-small;"><span style="color: #009695;">var</span><span style="color: #333333;"> </span><span style="color: #333333;">adapter</span><span style="color: #333333;"> </span><span style="color: #333333;">=</span><span style="color: #333333;"> </span><span style="color: #009695;">new</span><span style="color: #333333;"> </span><span style="color: #3364a4;">ArrayAdapter</span><span style="color: #333333;"><</span><span style="color: #009695;">string</span><span style="color: #333333;">></span><span style="color: #333333;"> </span><span style="color: #333333;">(</span><span style="color: #009695;">this</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #3364a4;">Resource</span><span style="color: #333333;">.</span><span style="color: #3364a4;">Layout</span><span style="color: #333333;">.</span><span style="color: #333333;">spinner_item</span><span style="color: #333333;">,</span><span style="color: #333333;"> </span><span style="color: #333333;">items</span><span style="color: #333333;">)</span><span style="color: #333333;">;</span></span></span><span style="font-size: x-small;"> </span><br />
<br />
<span style="font-size: x-small;"> </span>And we get the following: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSsAs7w102zlfP-AH9YtWmnlkJg8X0JXGpT13I86iyfkSlyFXbUti334UvT4fpgvvkvWGPTfuJdtcTLt1OiYkrQICtLgncnXnucq6D9iYhXGcmO7SjZ9afHS5ouLBOiHeqE_jZTM6WqLo/s1600/Screenshot+2015-07-02+14.57.48.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="124" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSsAs7w102zlfP-AH9YtWmnlkJg8X0JXGpT13I86iyfkSlyFXbUti334UvT4fpgvvkvWGPTfuJdtcTLt1OiYkrQICtLgncnXnucq6D9iYhXGcmO7SjZ9afHS5ouLBOiHeqE_jZTM6WqLo/s320/Screenshot+2015-07-02+14.57.48.png" width="320" /></a></div>
<br />
This looks much better, and a lot cleaner due to how the combo boxes are displaying the data. I am still debating whether or not this falls in line with Material design but for now I am content with it, it looks clean. I have since decided that this is a first pass and so I will likely do a "good enough" approach to get my information visible and then do a full pass pater to get things better organized.<br />
<br />
<br />
<br />
<br />
<br />
<br />Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com0tag:blogger.com,1999:blog-7888235610450058747.post-15670511778380074712015-07-01T09:25:00.002-07:002015-07-14T11:37:49.510-07:00Getting Started with App development, Android and Material DesignSeeing that I joined the ranks of the Xamarin Certified Developers last month, and working as a Sales Engineer at Xamarin, I figured it
was about time to actually try my hand at building an app. Upon getting
started I quickly realized that it is one thing to know all the pieces
and the technical theory behind development, it is another to actually
be capable of using it in practice.<br />
<br />
For now, my goal
is to work on an Android app which will ultimately be scaled to include
iOS, (Maybe Windows Phone), and then write different technical aspects
and learn things like Xamarin.Forms, MVVM Cross, Azure Mobile Services
and others. Really it will just be my attempts to be more active in the
development community.<br />
<br />
The current app I have planned will be themed after a Character
Sheet for Dungeons and Dragons, using the 5th generation ruleset. Nerdy, but rather
straight forward in its use case.<br />
<br />
If you would like to follow the app, you can find the Github repository here: <br />
<br />
<a href="https://github.com/psycosyd/DnD5e_CBMobile">https://github.com/psycosyd/DnD5e_CBMobile</a><br />
<br />
Getting started, one of my biggest stumbling blocks has actually been UI design and development. Normally I am a huge fan of UI development and design but I admit that Android is not the most intuitive, nor simple.<br />
<br />
Part of the problem is theory vs implementation. Google has really done a wonderful job driving direction through their documents on Material Design, found here:<br />
<a href="https://www.blogger.com/goog_1912432516"><br /></a>
<a href="http://www.google.com/design/spec/material-design/introduction.html">http://www.google.com/design/spec/material-design/introduction.html</a><br />
<br />
It helps give good clarity, color, layout and foundational principles to creating a great android application. <br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4TJvLpWw-aOF4QtJuoeu7e2RawYaaM9inP1Aoh69uvBHDu7rsQk3NFhjvHkc1qlxIChCcjn921kcQziUhsH64ez5Ym89vIE5avTh3utsKQcACuf7TPLYbgcA7ErUFyCfx_sYr7s-WI-E/s1600/components_lists_keylines4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4TJvLpWw-aOF4QtJuoeu7e2RawYaaM9inP1Aoh69uvBHDu7rsQk3NFhjvHkc1qlxIChCcjn921kcQziUhsH64ez5Ym89vIE5avTh3utsKQcACuf7TPLYbgcA7ErUFyCfx_sYr7s-WI-E/s400/components_lists_keylines4.png" width="225" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">I'm glad you have this great mock up, but where do I sign up for this?</td><td class="tr-caption" style="text-align: center;"><br /></td><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
The problem is, while it gives some great rules to follow, it is not as helpful on how the job gets done. As I started this process on my own Dungeons and Dragons app, this is what I started seeing:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwul5PKPoHmMz5ucnOGDRLP8o8ZIjEhMhXTBVE1dRWY75s_NXhBqW8e_mIoa8ywQpIGkClEW0oY9JiulDSogn9WsfACBzYIHZbrbkqI-Fy0nupTJ0kbcgdk-0WXDAd40pYuD_4_ff1Ilg/s1600/Screenshot+2015-06-24+17.15.42.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwul5PKPoHmMz5ucnOGDRLP8o8ZIjEhMhXTBVE1dRWY75s_NXhBqW8e_mIoa8ywQpIGkClEW0oY9JiulDSogn9WsfACBzYIHZbrbkqI-Fy0nupTJ0kbcgdk-0WXDAd40pYuD_4_ff1Ilg/s400/Screenshot+2015-06-24+17.15.42.png" width="218" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">I don't know about you, but something seems lacking. I can't quite tell</td></tr>
</tbody></table>
The big missing factor is the bridge between design and implementation. I conceptually get what Google is preaching, but have no foundation on how to make it happen. Luckily, I am a rather stubborn individual, and like to hammer at something until it works. One thing that I found helped was to start organizing/grouping logical data groups into CardViews. Additionally, coloring backgrounds helped to visually display where my layouts were being positioned.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFYseh2IMiyiKWPveY3nxUeRDaGUjC2CZv4v30psrPHhhm7Oh3G25v9pAK7LS8XdZn1JBC063P2_Gj8R9oIsHpmGaw5W-Ay8AmkXhGX_exyWgK4NWAKypR-0tFt_e5if2m4c2UAD2_3Zk/s1600/Screenshot+2015-06-30+14.22.08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFYseh2IMiyiKWPveY3nxUeRDaGUjC2CZv4v30psrPHhhm7Oh3G25v9pAK7LS8XdZn1JBC063P2_Gj8R9oIsHpmGaw5W-Ay8AmkXhGX_exyWgK4NWAKypR-0tFt_e5if2m4c2UAD2_3Zk/s320/Screenshot+2015-06-30+14.22.08.png" width="176" /></a></div>
A couple new factors coming into play here. The CardViews added a nice layer to group logical data. I also had to do some discovery with RelativeLayout and positioning. I had to right justify my entry/input fields, and then centered them by aligning their baselines to the labels on the left. Much cleaner. Now to do a custom adapter to my Spinner controls so we don't have obvious whitespace and we are in business!<br />
<br />
To get the top portion organized, most of my actual layout placement was done with my settings using layout_below, alignParentRight (on the right hand elements), and alignBaseLine to get each row lined up. You can see code below:<br />
<br />
<span style="font-family: Menlo;"><span style="color: #333333;"> <</span><span style="color: #3364a4;">TextView</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:text</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">Character</span><span style="color: #f57d00;"> </span><span style="color: #f57d00;">Level</span><span style="color: #f57d00;">:</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:id</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">id</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">charLevelLabel</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_width</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_height</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_below</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">id</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">charName</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:textSize</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@dimen</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">textTitle</span><span style="color: #f57d00;">"</span><span style="color: #3364a4;"> </span><span style="color: #333333;">/</span><span style="color: #333333;">></span><br />
<span style="color: #333333;"> </span><span style="color: #333333;"><</span><span style="color: #3364a4;">EditText</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:id</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@</span><span style="color: #f57d00;">+</span><span style="color: #f57d00;">id</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">charLevel</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_width</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_height</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">wrap_content</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_alignParentRight</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">true</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:layout_alignBaseline</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">@id</span><span style="color: #f57d00;">/</span><span style="color: #f57d00;">charLevelLabel</span><span style="color: #f57d00;">"</span><br />
<span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #3364a4;"> </span><span style="color: #333333;">android:numeric</span><span style="color: #333333;">=</span><span style="color: #f57d00;">"</span><span style="color: #f57d00;">integer</span><span style="color: #f57d00;">"</span><span style="color: #3364a4;"> </span><span style="color: #333333;">/</span><span style="color: #333333;">></span></span> <br />
<br />
<br />
Still this is a promising start. This next week will focus on getting a custom adapter set up for my spinner controls as well as work on the attributes layout, and code behind. Most of this initial phase has been just blocking UI and getting basic pairings set up.<br />
<br />
<span style="font-family: Menlo;"><span style="color: #333333;"><br /></span></span>
<br />
<div style="text-align: left;">
</div>
Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com1tag:blogger.com,1999:blog-7888235610450058747.post-19616494756350181602015-06-23T22:52:00.002-07:002015-07-01T09:16:30.902-07:00New Life, New Adventures- All MobileSo, it has been a while since I actually recalled I had a blog. Jobs have come, jobs have gone and I now find myself working as a Sales Engineer/Customer Success Engineer for Xamarin.<br />
<br />
What does that mean? Well I am kind of a hybrid of a Support Engineer, Technology Evangelist, Xamarin Champion and a mobile consultant.<br />
<br />
As part of my responsibilities I also have a charge to have an understanding and broad expertise of the mobile ecosystem. I will be using this blog to also track some of my own personal accomplishments and discoveries as I delve into mobile development, so here goes nothing!Jameshttp://www.blogger.com/profile/11878057915915639473noreply@blogger.com1