Colin's Journal: A place for thoughts about politics, software, and daily life.
In previous releases of ExpenseClam I’ve introduced two major new features: mileage and attachments. Of the two, mileage proved to be the easier to do within the existing application structure.
When designing the mileage functionality I decided early on that I wanted to make mileage work the same way as other types of expense as closely as possible. Mileage expenses would appear in the same list of unclaimed expenses, be exported in the same spreadsheet file and be moved into claims in the same fashion.
The easiest way to do this would be to have a mileage specific screen that generated expense records using exactly the same format as normal expenses. This approach is used by a number of competitors and is very lightweight to implement.
The downside to this design is that once a mileage record has been entered it loses mileage specific fields (such as distance, mileage rate, etc). I decided on a slightly more involved way of solving the problem: extending the expenses records to have mileage specific fields and creating a specific set of screens for creating and editing mileage records.
The code that lists expenses required only minor tweaking in order to distinguish between the two record types. The export code required additional columns in the spreadsheet output for mileage records, and code for managing expenses in claims was unchanged.
When a new or existing expense is opened ExpenseClam determines which UI is required and launches the appropriate Activity. Both sets of screens have a common super class that contains all the common logic for managing the life cycle of creating, discarding and saving expenses. Code for handling receipts is restricted to the expense handling class, while distance calculation logic is restricted to the mileage class, hopefully making maintenance easy.
If I had dropped support for Android versions earlier than Honeycomb I could probably have maintained a common activity and used separate fragments to achieve the same effect. However to support Gingerbread and earlier I have most of the Actionbar logic in the Activities, along with code for coordinating interactions between other Activities.
Email: colin at owlfish.com