Skip to content

Archive for August, 2010

31
Aug

Working With Stateful ListView

What is Stateful ListView?

It’s not a coined term, but it’s obvious. Stateful ListView is a listview whose items change according to its state.the state is usually maintained by a custom ListAdapter.

Why would I need it?

I don’t know. But, I can tell you why did I need it. In my Birthdays application, I wanted to have a “Batch Edit” mode. When activated, it should allow users to mark multiple items using checkboxes. That means these checkboxes weren’t part of my “Standard” mode. I didn’t want to create whole new activity just to add a checkbox. So, I decided to have the checkbox in the hidden state by default. I wanted to somehow loop through all the items and make it visible.

Sounds pretty easy. What’s the problem?

The first one isn’t actually a problem. It is because of the way Android is designed. The ListView doesn’t load all the item at once to optimize memory management. Only visible items are loaded. So, one can’t exactly loop through all the items because they don’t exist. If you change only visible items, newly rendered items after scrolling don’t have the change. The new items are rendered by executing ListAdapter.getView() for each item. So, maintaining the state inside the adapter solves the issue.

Now all the new items are being rendered correctly but, it won’t change the already rendered (visible) items. To solve this, I combined the above two techniques – maintaining the state inside the ListAdapter for items not yet rendered and looping through all the visible items and changing them. This introduces another issue that consumed more time in identification and resolution then before.

Basically, if user switches between modes when the ListView is being scrolled, Android VM will throw NullPointerException because the requested ListItem doesn’t exist in the view.

What did you do?

The cause of this was the loop where I was trying to modify the items. When the function was being invoked, because of the still-scrolling ListView, indexes of visible ListItems changed and they were no longer available. I had to remove it for starters. Now, what I needed was a strategy to make the checkboxes visible for already rendered items. After a little bit of searching I found out that by calling Adapter.notifyDataSetChanged() I can re-render visible ListItem views. If anybody has an improved strategy to implement the scenario, please comment below. I will update the post accordingly.

The source code for Birthdays application I mentioned above can be accessed via Github.

19
Aug

Birthdays Released on Android Market

Yesterday, I released my first Android application on Android Market – Birthdays. It is a birthday reminder application which syncs all your contacts’ birthdays to your calendar.

One can say that I’m a forgetful person and while there are some advantages of this situation, I often forget birthdays of people who matter. As a solution to this, I started maintaining birthdate of a person into his/her contact. Back then, I had just bought an iPhone and I was pleased that it had a “Birthday” field in the address book. I didn’t hesitate paying $0.99 for a birthday reminder app which didn’t exactly “remind” me (iPhone didn’t support Push notifications or Calendar sync back then).To be exact, it helped only a little if at all.

In the same time period, I was also excited about Android as a development platform. When I got my first Android device, I tried out a few birthday reminder apps already available. Most of them didn’t work as I expected them to. While some did, they relied on a background service for notifications which will keep running at all times. So, I decided to start the development of yet another birthday reminder application which will get the job done while not being a resource-hog. While the journey of the development was quite educational, it was easier than I initially thought (probably because of a slight change in my job description). I still can’t believe it took me a year to develop and publish my first “real” application.

So, what’s next? The application is still very basic. I am going to explore android SDK some more by adding new features like facebook sync, two-way contact sync etc. I have had a lot of help from Android developer community so, I am going to write a few blog posts explaining some issues I faced in the development of this application as my contribution. I am also planning to open the source to public as soon as I am done with implementing all the features I have in my mind. The application source can be accessed from Github.

QR Code
If you haven’t yet tried it, give it a spin by downloading it from the Market. Do provide your feedback via comments below so that I can improve it further and make it more user-friendly.

A feature suggestion is also welcome. I will implement it as I get time to spare.

Note: Because of a major bug, all the calendar events created by Birthdays are being removed by Android upon reboot. I am working on an alternate way to sync the calendar. Please bear with me until I release a fix.

Changelog:

Birthdays v1.2 R6 (September 20, 2010):

  • Fixed the “Invalid Birthday” issue
  • Fixed crashes on Droid X
  • Corrected calendar event dates
  • Better calendar cleanup
  • A few minor bugfixes

Birthdays v1.1.beta (August 21, 2010):

  • Fixed the crash for non-HTC devices

Birthdays v1.0.beta (August 18, 2010):

  • Initial release
7
Aug

Installing Redmine 1.0 on Mac OS X Snow Leopard

I have been a great fan of Redmine since I came to know about it back in 2008. I have been using it ever since to track my personal as well as professional projects. I had an installation of good old Redmine 0.8.6 on my Snow Leopard and I decided to upgrade it to 1.0 RC. As always, installation was not so smooth for me, but I managed to do it and here’s how.

I followed Redmine Upgrade Instructions initially, which required me to upgrade to Rails v2.3.5 from v2.2.2 with all dependencies. Thanks to awesome rubygems, it was a cakewalk. But, I made a rookie mistake there. Instead of installing them in system path using sudo, I installed them in user directory (~/.gem). To check your gem installation location, you can execute gem list -d. Anyway, it eventually led to an error “Missing the Rails gem. Please `gem install -v=2.3.5 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed” . This was very confusing as Rails 2.3.5 was already installed and upon executing rails -v, it displayed Rails 2.3.5. I had to uninstall Rails 2.3.5 and all the dependencies from user directory and reinstall them in system path using sudo.

Second challenge was to make Rails 2.3.5 work with mysql. As I was using default mysql installation in snow leopard, which happens to be a 32-bit one, I was not able to install mysql gem for ruby. After a little bit of googling, I found out that I had to download and install 64-bit MySQL in order to compile 64-bit gem. So, I installed new MySQL instance, migrated all my data from the older instance and then installed mysql gem. And I finally got the new Redmine installation got up and running on apache.

I wish I can have the wordpress-like automated upgrade mechanism in Redmine.