Wednesday, December 9, 2015

StatMan IV: Not so Fast

GitHub


I fixed an issue with the points column not sorting. Did a lot of refactoring also -- added a bunch of helper classes, and my code is a lot cleaner.

So I let my friends see the app last night and now I've got a lot of new ideas. The basic idea is a record of individual games. I want hamburger that will open up a navigation drawer. The drawer will have a button to add a new game, and underneath a list of all games played. Pressing the button will make the list disappear and bring up fields to fill out: Win/Loss, Score, individual stats. Once they're saved, the main page will update automatically and the list of games will reappear. I guess the games when clicked on will show the stats for each game.

This is a whole lot to do, and I want to move on to other things, so I'm going to continue working on it, but just here and there.

Tuesday, December 8, 2015

Enemies VI: My Own Worst Enemy

Pictures are mostly the same as the old one, the only difference is that now the data is saved.




GitHub


Wow, this has been on the shelf for a while. I was about 94% done, but I got stuck on data persistence. Saving an arraylist of objects that contains other objects? How is that even possible? I spent most of my time, the last couple months going through books Android and CS books and I left this for so long that it became harder and harder to come back. With my last app though, I dipped my toe in the water of sharePrefs, and that gave me the confidence to at least look at this app again.

I thought I'd just tinker around with Gson a bit today. I tried out some sample methods and set log tags to see what data I go back. It took me a couple hours, but I had a pretty good handle on it. Then all that was left was applying my new found knowledge to Enemies. The work I did before hand really helped, and I made my way through some difficult problems. I guess it's a requirement for programming, but everything is necessarily broken down into smaller parts. I'm always taken aback when I'm finished with something, I'm so focused on working through each piece of the puzzle and it's a pleasant surprise when they all fit together.


App Breakdown



This is a note-taking app. The twist is that it's only for noting who your enemies are and why. It may seem on it's face like a kind of shitty or even evil app to make. I'm not a guy with not a lot of enemies, so I likely won't use it. I just though of it and it seemed like a cool idea. I'm a novice, so I have to make simple apps that many people have made before. I didn't want to just make an app that takes notes and then saves them. I feel by adding specificity, I gave my simple app some substance. I'll make a super benevolent app to make up for it karmically.

The look of the app is the result of my making one Google image search and not being able to let go of the prospect of a cool picture. I like it overall. I love that image, as I said, and like the way the title looks like it's cut out of the picture. While this was my original vision and I do like it, it has a bit of an early 2000s website feel too it.

Users can add Enemies to their list. Long presses of each list item brings up the option to edit or delete. A short press leads to another page, where users can add reasons why the enemy is on their list. Reasons can also be edited or deleted via long press. Enemies and Reasons are saved when the app is closed or just stopped.






Small Features 


  • Every user entry has a character limit, and if they are exceeded, confirmation buttons are disabled.

  • Reasons are dated

  • The reason entry has a character count that turns red when exceeded.

  • When a user edits something, the original text appears in the edittext and with a cursor at the end. It sounds like not that big a deal, but it took some work to figure out.

  • A beautiful floating action button that disappears while scrolling the list.




Part I'm most Proud Of



It's been so long that I don't really remember what was most annoying about this app. It probably had something to do with getting that custom font to look right.

When the ReasonActivity closed, I needed to get its data to the MainActivity. This tripped me up at first. I saved a json string to SharedPrefs in a key-value pair. The key was the enemy name.(enemy.getName(), jsonString). I was sending that to a method in the main activity that retrieves reasons, The problem was that this method isn't tied to any particular enemy, So I was sending a Reason data to the main activity, and didn't know how to add it to the appropriate Enemy. After a few minutes it dawned on me that I could store as many key-value pairs as I want in sharedPref, so I sent the Enemy name with a generic key("key", enemy.getName()). This was probably an obvious solution, but when I figured it out I felt like a goddamn genius.







Statman III: Three Entries and I'm Already Done

The afternoon after my last post I had planned to do work on this a bit more and finish it over the week. I ended up working until 2 a.m., stopping only to eat occasionally pace around frantically. I'm really happy with how it turned out.




Github


I started with the layout. I found a nice hockey themed phone wallpaper to use as my background. I loved the look of semi-transparent cards, so I was excited to use them on my own app. I replaced my custom list items with a custom card item. And I mostly just copied the code from Enemies, but these were a lot simpler. It was important  to me that the characters were readable, so I tweaked those a bit to get them where they are. The pictures, I think, add some color to the app, and they're accentuated further by the greyscale background.


Data persistence, was my next priority. I used Gson to convert my Player objects into a json string. Then I saved that with sharedpreferences. This was done in the activity's onPause method so that the stats would be saved anytime the app is no longer visible. Previously the onCreate method contained a declaration of a new arrayList that contains all my Players. I replaced this with a call of my method pullData(), which checks the sharedPrefs for data, and retrieves it if it exists, or instantiates a new ArrayList if there's not data within sharedPrefs.





The pictures above demonstrate some stat sorting, a feature that I definitely wanted to implement. A user can press the stat category and sort the list by that category. I thought about this quite a bit before I even started working on the app, and I really wasn't sure how I'd do it. I guess the issue was that even if I could compared the properties of the Player objects, I didn't know how to sort my list by this comparison. I worked out how I'd do it in my head, and after a bit of research on Comparators, I figured out how to translate my idea into code.

At that point, I thought I was done, but the Points stat bothered me. It shouldn't be user edited, it should change automatically as goals and assists change. This was actually much harder than I though it would be. The TextView representing a stat only changes when the OK button is pressed on my dialog. The issue it that the method tied to that button is only references the text that has been touched. I tried a bunch of different things, but I ended up creating an additional version of that method that takes the points TextView as a parameter.



App Breakdown



This is a pretty simple application, it keeps track of the stats of a game my friends and I play. Each player is represented by their picture. Every stat, except for Points can manually edited via a +/- dialog; the Points stat updates automatically. Each category on the title bar can be pressed and it sorts it ascending or descending order. The statistics are saved every time the app is paused and saved data, if it exists, is pulled up whenever the app it opened.


Most Annoying Part



Hands down, the title bar. It took me at least an hour to get those letters in the right position. I had to do it through trial and error, and needed to run the app on my device because the display in Android Studio wasn't completely accurate. It seems like the visual aspect of apps, is something I always get hung up on. I spend lots of time trying to get certain views to look exactly the way I want.


Part I'm Most Proud of



The data persistence is not something I've ever used in one of my own apps before. I've used it plenty in apps I made with the help of textbooks and online courses, but when it came to my own ideas, the concepts I learned didn't exactly translate. I looked at some other people's apps that were close to what I wanted and it all seems so complicated. The prospect of saving data seemed daunting. But, as I mentioned before, this app in particular was really motivating for me. I wanted to finish it so I dove right in. I did little research(a lot) on Gson and sharedPreferences, and some toying around with test methods in my apps. After a while, I knew how to get it done and all of the things(most of the things) that seemed so complicated before, I understand now.




I might try to clean up the code a bit. I think I did a pretty good job, but there are probably things that I could do better. But unless my friends find bugs, I'm pretty much done with this.






 

Monday, December 7, 2015

StatMan II

               


GitHub


This is where I'm  at now. Every TextView holding a stat value is clickable, Clicks pull up a dialog with buttons to add or subtract from the value. And when OK is click, the dialog is dismissed and the new number is put in the TextView. Instead using a number picker, which I thought might be a little clunky, ending up making my own custom dialog with +/- buttons. Previously, I had made dialogs with AlertDialog.Builder, but that wouldn't work with the custom dialog that I created. Here I used a Dialog Object, the process, was a lot like more creating an activity or fragment. I had to reference each view from the xml and use it in code.


Now I've got just a few more things to do. The layout, I'm going to make beautiful, and I will probably need to make a new adapter for cards. Then the final piece is saving the data every time the app is closed and pulling up saved data every time the app is closed.

StatMan I

This is an app that's only going to be useful for me. My friends and I play NHL 16, as a team of four, online. We decided the other day that we should keep track of stats. While this will likely lead to petty in-fighting, selfish play, and the dissolution of our team dynamic, it also seemed to me like a great idea for a simple app I can make.

I think this will be fun and it's something that I told all of them I'd do, so I'll be accountable for it. Hearing "How's the StatMan app going" from someone really encourages me to want to put together a finished product that I can show them.

It's a simple idea - every player has a row, and were keeping track of goals, assists, points, as well as port game accolades. I want an image icon for each player, and I want able to sort the stats in ascending and descending order. Here's what I've got so far:






Obviously I've got a lot of work to do, but I'm pretty sure I know exactly how I'm going to do it. That top title bar needs to be adjusted to match up with the stats, the stats I's like to move from the listView they're in now, to semi=transparent cards over a hockey themed background. When the individual stats are touch, I want a number picker to show up that will change the stats accordingly. I also want so kind of feedback on those presses, probably just a color change. I also want to be able to save the stats. I'm probably going to do that in onStop, and use either a SQLite database or sharedPreferences with gson.

Things have gone smoothly so far, the only problem I had was with my images. They were causing an outofmemory error and crashing my app. I found a couple different fixes on stack overflow. One was to just add android:largeHeap="true" to my manifest. What I ending using was a post that pointed to this Android Devs page that lays out how to use a couple helper methods to load large bitmaps efficiently. This solved the issue and my app ran successfully.