U And I:: Adam King
Are you tired of having TOO many paint tools at your disposal? Do you scoff at the mention of Fireworks, Photoshop, or Flash? Do you wish you could revert back to the days of fingerpainting? There’s an app for that. Introducing Paint–™.
I wanted to write a paint app as a way to work with touch event tracking and management of variables between activities, while being able to use a fairly wide range of widgets. The MainActivity is the canvas that allows the drawing of paths. A second activity, the Brush Settings activity, contains a progress bar that allows you to adjust the brush width, a spinner which allows you to select a color, and a toggle button that lets you toggle the blurring mask for the brush (textfields separate these and provide information). I used a RelativeLayout to set these, mostly to play around with this type of layout; the setup is probably the same as a LinearLayout would be, but I feel like I have more control with the RelativeLayout. The four buttons on the bottom (Accept, Cancel, Save, Load) are within a LinearLayout nested in the RelativeLayout.
I lied. There are a few extraneous paint tools such as blurring and saving/loading; creating the blur mask was simple to do, but finding how to save bitmaps to the gallery took many attempts before finding a way that worked – once finding a way, it was a bit easier learning to load images from the gallery as well. Most of the lessons with this file I/O; the list is rather long and painful, but I’ll boil it down to some of the essentials:
- A black canvas is easier on the eyes than a white canvas when working late nights decrypting blocks of red console text.
- Attempting to use cache or memory arrays to store Bitmaps induces serious headaches; I don’t think they were set up with the mindset of being used.
- You can easily and conveniently store information in a file private to your application:
FileOutputStream fos = this.openFileOutput("screenSave.JPEG", Context.MODE_PRIVATE); screenSave.compress(Bitmap.CompressFormat.JPEG, 100, fos);
- I ended up shipping Intents back and forth using startActivity before learning about the startActivityForResult; this constant use of startActivity may result in several instances of the MainActivity filling up the runtime stack. Fortunately, Professor Johnson tracked down some flags that can be set on intents to dictate other behaviors of activities (such as checking to see if an activity is already running and closing all activities on the stack on the way to that activity instead of just tossing a new one on the stack) by a simple .addFlags() on the intent.
- More heartbreaking than coding the Intents a bit off is learning that everything I was passing with the intents could be stored in Android’s Stored Preferences.
- I don’t know how correct it is, but I found handling orientation change in the onDestroy() method to be the easiest way to do it, the supposed orientation change listener failed miserably at what its title claims.
Overall, I’m sure it’s still not the most efficient way to write a painting app, but a lot was learned in passing data and having data persist when working between activities and a fair amount was learned about saving and loading files.
Side note: Originally, I was rotating images 90 degrees when loading them in, but when loading in an image saved with the painting app it was then loading in incorrectly; I could be way off base, but I think the emulator camera may save images in landscape orientation. Regardless, it’s not a huge issue and I’d need a device to truly debug everything that’s going on, so maybe if I come back to the project someday to build on it it’s something to be fixed.