Friday, April 19, 2019

Testing out Flutter

It was hack-a-thon days at work so I decided to try Flutter. I found a blank starter app then spent 10 Google Searches to about every two lines of code I actually wrote it seemed like. Flutter and Dart have both been evolving so much that a number of searches showed old information. At least most of the Stack Overflow stuff pointed you to the newer way of doing things.

For the past two years I have been doing Kotlin so I kept forgetting to add ; to the end of lines. Already know the IDE but I did not want to pollute Android Studio so I grabbed IntelliJ and set up under that. Configuration was pretty straight forward and since I am on a MacBook I could test both iOS and Android builds. Did all the work on Android emulator then tried it on iOS from time to time.

I used the Material look and I have zero if / then checks for Android or iOS. Small app so that does not prove a lot but for what I did I ran into no issues.

App has an image, read from assets, and 6 buttons with icons from the Icons package and text in a grid layout to go to other areas. One button shows an Alert Dialog. One goes to a screen with a ListView. The ListView is populated with items I read from a JSON file in the assets area.

I learned about Row, Column, Container, ListView, TextStyle, Expanded and all sorts of Widget properties. I have used a lot of layout managers over the years so I was able to get up to speed pretty quickly but I did a lot of searches to find what I needed and I refactored the layout code at least 6 times. Lots of indenting and easy to screw up a ( ) and [ ] matches or miss the ; at the end. The errors given by IDE generally pretty good.

Imported Intl, DateFormat and Decimal. Wrote converters for JSON as I have Date Time and Decimal needs due to Double having accuracy issues. Learned how to grab a file from assets. I did not mess with any network stuff as you need to login with OAuth first to get to any of our data and that seems like it would eat up both days.

Felt like I got a lot done in a day and a half. Very frustrating at first as getting anything simple to work took a lot of web searching and I went down so many wrong paths. First I was setting up the icon buttons as decorated columns then found I should be using FlatButton instead so I could get the actually tapped event and the tapped visual effects. Initial ListView code I found was very complicated but I found a simpler version and got it running quickly.

So am I a Flutter convert? No, I just wanted to see what it is all about. We use a number of 3rd parties for interaction with Credit Card readers and what not that probably would be a massive pain to deal with in Flutter. I was impressed at the speed of testing stuff in my small two screen app. The instant run is nice. Having an identical app on two platforms is sweet. Setting up images sucked as you have to manually add them into the YAML file. I just want all things in a directory to be there. On-line help is all over the place, some old, some new, some expecting you to know a lot especially when they talk about packages. They don't always mention what to add to your YAML so you do another search to find out that info.

Do I see some usages here? Kinda, like any app that appears to start out small you go "oh, I could do this simple app and get a free iOS version" but then you start adding more and more stuff then you hit some wall where you need something deeper in hardware and you are screwed.

Next areas would be doing actual REST calls, doing complicated UI work, SQLite interaction, lifecycle fun, shared preferences, animations, and basically being a real full featured app.

Glad I had time to play with it as was paid to do it. Time to save the code to Git and move back into my Kotlin reality. Worry is when I demo it this afternoon that the big bosses will think I found the holy grail of coding. Setting expectations is the key here.

Friday, September 21, 2018

Doing a little iOS work - Xcode is as bad as I remember

Our iOS programmer left. We have a new one starting next month. During the change over time I am doing some updates to the iOS code. Luckily before he left I got a pretty good overview of the current code so I am not running blind.

The fun is always Xcode. Never have liked that IDE much but it has been a few years since I did iOS work so I figured it has had time to improve. While Swift may have improved the areas I use daily to code have not. Git support is still barebones so I had to use SourceTree. SourceTree is nice and all but I shouldn't have to leave the IDE to interact with source control. I almost never touch SourceTree when doing work in Android Studio. I can easily create branches, merge things, remove branches, check history etc. right in the tool I am already using. I guess Apple really does not care about improving this area because as far as I can tell zero changes here.

Next up is searching. Yes Xcode gives you a number of ways to do it but it changes the mode a lot. If I look up usage of an enum, method or variable then the next time I search it is in that mode. I search for text a lot. Paying attention to the mode it is in because I right clicked on something in code but not on the search panel is frustrating.

Archiving stinks. Who thought this was a good word for building for release? Archive to me means put something out to pasture, you are done with it, store it way as it is old. But here is means build the latest for the store or TestFlight. I battled provisions / certificates / other crap for 45 minutes to get things out on TestFlight. Then I build the IAP for a user and that took a long time. I just started the export and let it run but dang was it slow.

There is also the wonderful fun of Interface Builder. So many tabs to get to settings. I will fully admit I like editing XML manually on Android. See all settings in one place, easy search and replaces as needed, easy to see cut and paste issues that I need to set up as styles. So much clicking in IB and you have to click on little [edit] links instead of on text. Might be powerful but it gets in your way when it comes to speed. Android gives me a choice, use visual editor if I want, manual if I don't. Yes IB generates XML but would you really manually edit what it creates? Last time I did a lot of iOS coding I skipped IB and did it all in code. Worked great for me as I am used to visualizing my layouts into manual XML creation. I used Masonry at the time so it was AutoLayout. Now that I use constraint layout on Android they are even closer.

Was able to pull off the critical changes need for next weeks release. I have never programmed in Swift but it is similar enough to Kotlin, which I have used for past 18 months, it was not too hard. Reactive Swift too boot but again the Kotlin syntax leads you that direction as well.

I came super close to downloading AppCode to use as a 30 day trial to get me over this hump until next dev appears. I may still do that if I have to spend much more time in the code. I have used AppCode at previous positions. Since it basically is same IDE as Android Studio I can hum right along using it and it works great with Git. Maybe I should just have work pony up for it anyway as I end up in the iOS code from time to time as it is. All my other Android tools are free so this can't be asking too much right?

Sunday, December 17, 2017

Going full ConstraintLayout

Started a new project and decided to go full ConstraintLayout. I figure it is the future so I might as well use it. I used AutoLayout when I was doing iOS work so I have the general idea down.

First off I am using 1.1 because it has Barriers, Guides and Groups. To properly replace TableLayouts you need Barriers. This allows you to say "Hey, here are X controls, I want an edge to be based on the longest one". This is what happens with stretched TableLayout columns. It also means your layout will adjust if you change text label widths which can easily happen in other languages. Trying to stay on top of the internationalization game.

Group is nice if you need to hide a group of controls which you may need to do if you have a Switch that toggles visibility of a number of items.

Guides allow you to do percentage layouts. This gets rid of that deprecated layout.

Now my layouts are nice and flat. I went back to previous app and converted most of those layouts as well. The conversion tool in Android Studio is hit and miss. If you have just a RelativeLayout it will probably do a decent job converting it but you may have to set a width to 0dp here and there as the control may be set to start / end against another control but have a width of match_parent.

I also find you have to put in spacer controls at the bottom of some layouts, especially row layouts used in a RecyclerView, as the bottom margin is ignored for the lowest item in a layout. Did not cause too many issues.

I recommend you give this a shot as well.




Friday, October 20, 2017

Moved from minimum SDK 19 to 21

Looking at our Flurry stats we had zero uses on SDK 19 so it was time to make the switch. Happy I did. I was able to delete a bunch of resolution dependent PNG files and move to vector based XML files.

One minor issue, drawable start / end for a TextView, even the AppCompat version, does not support tint color until API 23. Easy enough, just did a separate ImageView and TextView to get the same look. Very few areas needed this change.

I was also able to kill some code that was checking for older SDK versions. Nice to be able to clean up all that crap as well.

Impact on final APK was minimal but I sure like the clean up in the resource area.

I also started to use the applicationIdSuffix ".debug" in the build file. Now you can have the Play Store Version of the app and a new debug version on same device. Lets me see if I screwed up the look of things when I play with layouts.

Decided to update the tint color for the status area of the screen as well. If you are running a debug version it is purple, light blue for release versions. Lets you instantly see what version you are running. Of course the launcher icon has a big BETA banner on it as well so you know at launch time which one you are using.

Knocking off some technical debt while I wait on server to have new features in place. Good to see some progress in this area.

Friday, October 13, 2017

Removing ListView and PercentRelativeLayout

For my tech debt I am removing all ListViews and Percent RelativeLayouts. List View has been replaced with RecyclerView. When I started the current app I did ListView, bad Kevin, because it was easy to pop into place especially since I was just learning Kotlin. Now that I have a lot of Recycler views and I can really use their power it is time to replace all the ListViews. I only have two left to go after swapping one out today. It was much easier than I set myself up for it being and since I now know to use multiple adapters instead of trying to cram everything into one adapter with crazy boolean logic it because super easy.

One of the last two that needs replacing is of the infinite scroll variety so I will have to get that working. I have not done an infinite scroll for a RecyclerView yet.

For PercentRelativeLayout I am swapping in ConstraintLayout. The auto conversion, at least with Android Studio 2.3, gets you 80% of the way there. I had to get the rest of it tweaked to look like it did before but it was not too bad. I can see the power of ConstraintLayout but the IDE has too many issues for me to want to switch everything to it. My understanding is AS 3.0 is much better but I will wait until that hits release. Did not want to have deprecated layouts in the code. I know Google will leave them around for a long time but learning ConstraintLayout was a good mental exercise. I have used auto layout for iOS development and MigLayout for desktop Java which made wrapping my head around ConstraintLayout pretty easy. A couple of videos to learn some tricks and I have not run into something I can't make it do. Looking forward to using the Group functionality in the 1.1 release as well.

I have tested my code under AS 3.0 Beta. I had to replace one control I was using. It was from GitHub and has not been updated in a long time so chances of it getting fixed are slim. The replacement was not too hard to write and works out well plus I have a lot more control. Always happy to get rid of a 3rd party dependency especially when I get more power out of the end result.

I tried using the ThreeTenAndroid library for time / date management but it was broken for Korea. After the start up crashes started to pile up it was time to switch. I am now using JODA Time. Was a pretty easy swap out. Not using standard Android Calendar / Date/ SimpleDataFormat as I was running into thread safety issues and was tired of screwing around with that. I know I added a bit to the size of my APK but working code is the best kind of code.

Added more Flurry event calls for even more analytic reporting. I do find Flurry very handy for both our Android and iOS products. You only get as much out of it as you put into it. The Flurry webpage interface can be frustrating for sure but when it does work and the data comes back you get solid results. It does let me know when a new feature is being used. I have also found some features that are never used. Painful as that might be knowing the answer is good. I really wish they did a solid Android App so I could monitor error reports on my phone. Using the website on a phone sucks at best. The Android App is super limited in functionality to be nearly useless.

Wednesday, August 30, 2017

Updating to be more in compliance with Oreo ProgressDialog deprecation

Oreo deprecated the progress dialog. That big fun thing that would dim the screen, pop-up, show the spinning circle then disappear when whatever operation was done.

The Google Material team is saying that is bad and users should be able to keep using the UI and cancel stuff. Once you target Android 26 any progress dialog usage gets flagged as a warning.

At first I was thinking "Oh man this is going to suck, I can't do that" but then I started to try getting rid of it in a few places and by damned things look a lot better. You don't have that flicker effect where the screen dims, see dialog even if for a fleeting moment, the screen brightens again. I have removed calling the progress dialog from all the places that load data so far. It is only actually referenced in one helper area. I have also replace how that helper area works and I am showing a custom dialog fragment. It looks pretty much exactly like the old ProgressDialog but now I have no warnings in my code.

The big benefit is user can cancel out of an operation if it is taking too long and move to another part of the app.

Using Retrofit was a huge advantage here as it supports cancelling network calls. Really had to tweak just a little bit of code for that to work nicely. 

Finding the proper place to put the busy indicator in the UI takes a little bit of thinking. I use Recycler Views instead of List Views so I made a very simple recycler view adapter that hosts a piece of text and the horizontal indeterminate progress indicator. I set that as the recycler view adapter while I am busy doing network stuff such as loading the details I really want to show. The user can hit the BACK button on the action bar or the button on bottom of device and I exit the activity with no issues as I just cancel network operations in onDestroy. Otherwise once I have the data I swap in the adapter that shows it.

It is really nice and clean looking and gives the user much better flexibility. Most of our network responses are pretty fast. There are a few areas we have to chain them to get all the data. It is funny watching QA hit something to start an operation then quickly try to pound the back button to make sure things cancel properly. I have some debug logging code in there so they can watch the output log to see if they truly did if fast enough. 

I am going to leave the progress dialog in place for credit card transaction processing and a few other key areas. I just can't have the user doing other things during that time. 

At first I was kind of pissed off at Google but once I got in there I totally see why they want you to stop using this UI freezer. The whole app feels cleaner and snappier. Very happy I tackled this area per the push from Google. Would love to kill it everywhere but some operations really do need to block the user from moving on.

I also cleaned up some code where the user was entering things such as an order number for look up. If they entered an order number that did not exist in the system, easy to mistype this sort of thing, they got a big pop-up "Order Not Found" dialog. I got rid of that too and just show the order was not found in the existing UI, highlight the text and have it ready for them to retry. So much less jarring to the user and it just seems so much friendlier. You are not being yelled out, just told can't find it and right back to trying again without needing to hit a CANCEL button on some dialog that is yelling at you.

Friday, July 28, 2017

Over a year in with Android watch and how it works with new phone

I have had my Huawei Android watch for over a year and now have a new HTC U11. I have worn a watch since I was in grade school so getting used to that part of the watch was super easy. My big concern was daily charging. I only need to charge it every two days and since I have multiple chargers at home and one at work that has not been an issue. Sure, it would be great if it lasted many days or had solar charging but it has not been the hassle I thought it might be.

When I had my Note 4 running Marshmallow the watch always won when it came to bluetooth which was annoying when I got in the car. With the HTC U11 the phone lets the car win when I start it up. That is great as I want to make and receive calls on the hands free BT in my car always. I don't know if this magic is due to the phone or Nougat but I am darn happy it works.

My watch updated to Android Wear 2.0 some time back. I was using Coffee for SMS support but no longer need to use that. Nice to have a keyboard right on the watch for quick replies. I have tested the drawing aspect as well and it works for sending back an emoji. Rest of the notifications work as expected and that is my favorite part of the watch. See the notification quickly and decide how much attention it needs.

Both of my sons have Zen 2 watches and get a lot of use out of them as well. I have found the watch to be a solid purchase and would dearly miss it should it decide to stop working.

Both the watch and phone have been solid in their pairing. I have not rebooted the watch since I got the new phone. I have rebooted the phone once outside of installing updates when it got overheated on a super hot day where I was also getting sick from heat stroke nearing conditions.