Saturday, March 17, 2012

Instrutorials - Part 4 - API calls and UI problems

Hi all,

Once again another update on my Bachelor's Thesis. I tried finishing the search implementation, consisting of both API calls and a decent interface.


Like I stated in my previous post, I'm using @pjv_'s library for managing the API calls to I already had a good idea about how I'd make the interface, so I first started getting those API calls to work.

@pjv_'s library was a bit difficult to get started with. It uses a MuseScore object which contains everything JSON related, but had a huge constructor and not that much documentation (since it was originally developed just for personal use). Therefore I downloaded and checked the source code Collectionista, the app for which this library was created. After digging trough numerous source files I finally found what I was looking for and based my code for initiating an API call on some code I found in Collectionista.

So, now I had a way to contact the API. I decided to implement the search function before browsing, since search is basically sending a customized query to the API, and parsing the server reply. Since the library I used contained all resulting data in Score objects, it was quite easy to get the results of a query -  meaning Title, composer, number of pages of a score, etc. However, all feedback was textual.

I wanted to give the user a quick peek at the scores. As they say, an image speaks more than a thousand words. The Musescore API provides some static links to small generated thumb images of the scores. However, this functionality is not supported in @pjv_'s library. Therefore, I extended his library so that Score objects can also contain a bitmap, meaning that the thumb can be stored in the Score object. The developer himself is responsible for filling this variable, since this image is requested in a second query. Also, it should still be possible to use the library without thumb images. If the functionality to fetch these images was included in a normal query, a lot more of data would be used by the application, even if it doesn't even need the images.

Each score contained in the response by the server is shown in the application, along with the Title, Composer, number of pages, and a thumbnail. These thumbnails are loaded in the background, so on first sight they might show blank, but once they are loaded they are instantly shown. This thumbnail loading is another reason why I decided to store these images in the Score objects. Android deallocates every item in a ListView when it is not visible. Therefore, images would be deleted on scrolling, while others had to be loaded. Upon scrolling back to the top, the bottom ones would be deleted and the first ones would be downloaded again. This created lag because of the constant background threads fetching those thumbnails. By storing the images in the Score objects each image only needs to be fetched once. When fetched, it is stored in the Score object. Therefore, while scrolling these images can be instantly loading without needing to create numerous new threads to fetch these images once again.

The results of a search query are shown in a ListView. As you can see, one can add search parameters. A keyword or a query to search for as well as the instrument the score should be written for. (About the first screenshot, a ListView in Android doesn't show a scrollbar unless interacted with - the list of piano scores on which the keyword Bach applies is substantially higher than 5). What now rests is creating a link between this Activity and the actual meat of the app Activity (which playbacks the files). This can be done by clicking on an item in the ListView, since these are all connected to a Score object which can be used to fetch the corresponding MIDI file from the API.


Sunday, March 4, 2012

Instrutorials - Part 3 - Starting with the UI, API

Hi all,

After a few busy weeks finally another update!

I've started work on the main interface of the app. You can see a screenshot below, but it's still rather empty:

Just so you know, the keyboard has nothing to do with the application, it's just Swype :)

Another screenshot in landscape:

This beautifully shows how awesome and clean the new Action Bar is. On landscape the tabs are included in the Action Bar so no space is wasted. However, the implementation is a lot more difficult than Google admits, so it was a bit of a hassle.

One of the reasons is that TabLayout is now deprecated. If one wants to use tabs, the Action Bar is the only valid way to go. Coupling that with Fragments, TabListeners and LayoutInflators and it's a whole lot more work than a simple TabLayout. At least it looks nice these days.
One of the things I've learned in the last weeks is that Google is a troll. Read the following:

Google: One of the things we leaned during the TTUI course at University Hasselt: If you want developers to use specific design choices, make those choices the easy option. Don't make it impossibly difficult. Using gestures to switch between tabs is one of the most difficult UI implementations that exists for Android. For starters: If you want developers to use it that bad, just add it to the SDK, instead of using difficult code in your own apps and not sharing it. Thanks.

Anyway back to the subject:

I also started to work on the API connection. For this i use @pjv_'s library. You can find it on Github:
This had a few complications.

  1. I have some experience with Subversion. Git, however, is a whole new world for me. Getting to know all commands, how to use them at what times,... I guess I'll get the hang of it by using it.
  2. The API wrapper didn't really include an example. It was used in Collectionista (same developer), which is a huge app already, so it was a bit difficult getting it to work. But after clearing some things with the developer I finally successfully queried the API and gotten some valid results. Yay!
I have no screenshots to show off about the API, unless you're interested in pure text-based command-line prints. But, being able to see those prints after a few weeks was a big leap forward.

Another busy week ahead so it might be one or two weeks until my next post.
Progress is slow but steady. And that's what counts.