Sunday, January 24, 2016

Choices I

             

GitHub

I thought I had already made, a post about this one, but I guess this will be the first. This is a simple app. A user will be able to add items to a list, press a button, and one of the list items will be selected. I'd like to have a navigation drawer that will contain previous lists that users have made.

 I did a bit of work on this last month, I just wanted to see if I could set up a search view, and it worked out pretty well. All that code is commented out at the moment. Today I've been experimenting a bit with Circular Progress Buttons, Ideally, each list item will be a CPB, and when the decision button is pressed, they will change color or disappear or animate or something.

Next, I want to just get get it working, so that I can add items, and use the decision button to select one.




Monday, January 4, 2016

Calculator VIII: It Doesn't Quite Add Up

GitHub

So I noticed a couple issues with my calculator a few days ago and I've been putting off fixing them. The idea of going back into code that I wrote months ago didn't seem appealing. How would I remember how certain things worked? If I changed one thing, would it mess up something important that I had done before. But I jumped into it today, and saw that I had done a good enough job the first time that, even without comments, I was able to remember how it fit together pretty easily, and it's all fairly modular, so I was making changes to specific things rather than having to fix things multiple times across my code.

There were three problems initially. The "-" button was only worked if there was already a number onscreen, so users couldn't start a calculation with a negative number. Also, if the square root button was pressed while a negative number was onscreen the app would crash. And finally, app allows users to chain operations i.e. 5 + 5 + 6, rather than having to press 5 + 5 = 10 + 6, but when the square root button is pressed for a second operation, it would give the square root of the second number and completely disregard the first. In fixing these issues, I realized that I had another problem with operations not displaying correctly after square root was pressed. After pressing SR, the value for the next operation would always be 0.

The negative problem was fairly easy to solve. When pressing "-", I just needed to check if the screen was empty, and if so use my pressKey() method to display a negative symbol onscreen. I also just had to add a check to see if just "-" was onscreen, so two operation buttons couldn't be pressed in a row. The SR, crashes I dealt with by adding a boolean in my pressSqrt() method that is false unless the first character onscreen is "-", and then adding a check against this boolean before Math.sqrt is used.

The other issues were a bit trickier. I ran into the operational errors with the SR button, but wasn't exactly sure what was causing it. I knew though, that this operational button was set up differently than the others, because it was meant to be used with just one value rather than two like the +/- buttons. So I used my operation() method as an example. I saw that in that method I was setting the value that would be used in my operation display. I wasn't doing this in my pressSqrt() method, and that was my problem.

With this out of the way, I turned to the SR button's the mid-operation problem. Again, because the button is meant to be used with just one value, I wanted to disable it's use mid operation. I thought the best way to do this, would be just checking the contents of the operation TextView, so that if there were anything there, SR wouldn't do anything. I checked to see if "" was in the operation TextView, but this did not work. Even if the TextView was cleared(which happens automatically after "=" or "AC" is pressed), the SR button would be completely disabled. I took a look at my variable and saw that in those situations, it contained not "", but "", and line break and another blank space. The operation TextView contains two lines, one for the value, and one for the operator, hence my problem. I fixed it by adding a trim() to my check, and viola, a perfectly(until I realize something else is wrong) working calculator.


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.

 

Sunday, November 1, 2015

One Thing I

I haven't had much time recently, and I used most of what I did have to go through a book on Java Data Structures and finish the Big Nerd Ranch Guide to Android Programming. Since I've been away from programming on my own, I've decided to start with something pretty simple to get back into the swing of things.




This idea is that a user writes one activity that they absolutely must complete that day. They are able to choose the time the day officially starts via that timePicker. If the do it, they check complete and it's a success, otherwise it's a failure. Another activity to display History. It will show like "4/5 successes" and have a success rate. There will also be a tally of when the user does not chose one thing to do, but these will count as failures. 

Pretty straightforward, and I'll need be able to save the history.



Friday, August 28, 2015

Enemies V

GitHub

Bugfixes


Last night, I showed a friend the app and he pointed out that, while he couldn't enter an empty text field he could enter a blank one that's just full of spaces. To fix it, I just used trim() on my input variables before validation. I also noticed a few other things while I was at it.


When users edit a text field, I have the previous text show up in the edittext. The cursor was always at the beginning of the text, and I would always have to place it at the end. After a little research, I figured out that I could amend this with the edittext's setselection() property. It was still a little tricky. I was using it in a dialog builder, and it wasn't having any effect. I realized that the setselection() statement has to be the last thing before I call builder.setview().


I also decided to institute a 30 character limit for Enemy names, which I put into the textWatcher that I had already set up. I disabled the submit button and displayed a toast. A problem then arose that every character the user entered after the limit would generate it's own subsequent toast. So I set up a Toast variable set to null, and a displayToast() method, which checks for the value of toast. If the toast is null, it is created and displayed, otherwise the toast is cancelled. Fuck. I just realized that this won't work if there are multiple Enemies, because there is only one toast value. I guess I'll have to set the toast to null after a certain point, like after submit is clicked, that way the Toast variable will start out fresh for every new entry. I guess when the Add or edit buttons are pressed.


I've still got to tackled Data persistence to finish this up. I've been looking into it, and I think my best option is to use a combination of shared preferences and Gson to convert my Enemy and Reason objects into json data.

Thursday, August 27, 2015

Enemies IV

                                

GitHub

Changes

So, I styled my cards a bit and increased the text size. I also did move to a new library for my FAButton and it works pretty much like I want it to. Like in my other ListView, I added delete/edit function onLongItemClick. The biggest change was another update to my data model, mostly to support the date for my timestamp. I could have probably made one before, but I was concerned that if the data wasn't attached specifically to each description, I'd have a lot of trouble saving it. 


Previous Model
Enemy Class:
Name(String), Descriptions(ArrayList<String>) 

New Model
Enemy Class:
name(String), Reasons(ArrayList<Reason>)
Reason Class:
description(String), time(Date)


This made completing my CardAdapter much easier, because I really needed a description and a timestamp that were attached to the same object. I used a viewholder pattern for my card adapter.


I've come to a realization

Last night, after literally three hours of scouring google and stackoverflow and fighting with my code, I decided that it really wasn't worth it to style my dialogs. I had some other cool ideas in mind for this app too: Swipe to delete with a snackbar, longClick select for my detail page that would switch out the add FAB with one for deleting posts. I'm not doing those either. The 1.0 version of Enemies is going to look pretty much as it does now. At this point, it is just an egregious waste of time to spend hours trying to implement some design feature(The brown and yellow dialogs I had in mind would have looked horrible anyway.) I want to be pushing myself in new directions and learning valuable new things. Basically, learning how to effectively work with java is going to take precedence right now. I'll be back eventually to style the crap out of this app, and hopefully when I do, it will come a lot easier.


So now all that's left is data persistence.