Tuesday 18 November 2014

Build an ASCII Art Editor: Interface Setup

The Android platform offers a wide range of storage options for use within your apps. In this tutorial series, we are going to explore some of the data storage facilities provided by the Android SDK by building a simple project: an ASCII art editor.
Project Overview

This tutorial series on Creating a Simple ASCII Art Editor is in four parts:

Building the User Interface
Image Export & User Configuration
Database Creation & Querying
Saving and Deleting ASCII Pictures
By the end of this tutorial series, the user will be able to enter text characters to draw their ASCII artwork, save the art to a database, or even export their creation as an image file. The user will also be able to choose to display settings that determine the text and background colors for the ASCII art canvas.

To achieve all of this, the app will use Shared Preferences, an SQLite database, and external storage in the form of the device SD card (if one is available). In this first part of the series we will get the application set up and build most of the user interface elements. In part 2, we will handle exporting the image and letting the user choose display settings. In the final two parts we will work with the SQLite database.

Here is a preview of the app in action while the user enters ASCII characters:

Step 1: Create an Android Project

Start a new Android project in Eclipse. Choose your application and package names as well as target and minimum SDK versions. If you're using the newest version of the ADT (Android Developer Tools) for Eclipse, you can select an application icon as well. We won't be spending too much time on the decorative elements of the app in this series so that we can focus on the storage options. Let Eclipse generate your main app Activity while building the new project, entering an Activity and layout name of your choice:

Step 2: Build the Main Layout

Eclipse may now open the layout for your new Activity - if it doesn't open it yourself so that we can work on it. Depending on your ADT, Eclipse may automatically generate a Relative Layout, however we are using a Linear Layout, so replace the existing content with the following:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="5dp" >

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/intro"
    android:textStyle="bold"
    tools:context=".MainActivity" />

</LinearLayout>
If necessary alter the context attribute to reflect the main Activity name you picked. Open the app's strings resource file ("res/values/strings.xml"). Add the following string, which we referred to in the layout file:

1
<string name="intro">Enter your ASCII art below!</string>
If your strings file contains a string with "title_activity_main" as its name attribute, alter it to reflect whatever text you want to appear in the app title bar, as this string may be automatically set as the Activity label when Eclipse generates a new project. We will be adding items to the strings resource as we build the layout, so keep the file open.

Back in the main layout file, let's add the editable text area for users to enter their ASCII characters. After the introductory TextView, add an EditText:

<EditText
    android:id="@+id/ascii_text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="#ffffff"
    android:background="#000000"
    android:typeface="monospace"
    android:gravity="top|left"
    android:hint=""
    android:inputType="textMultiLine"
    android:lines="10"
    android:maxLines="10"
    android:minLines="10"
    android:singleLine="false"
    android:scrollbars="vertical"
/>
Take a moment to look over these attributes. The ID will let us identify the text-field in Java. The text color and background have initial values, but we will be allowing the user to set these later. The text-field will initially be empty and will have 10 lines for user input. The other attributes are decorative, so you can alter them if you wish to use a different design.

Next we are going to display a series of buttons for user control, so add a layout for them after the EditText:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

</LinearLayout>
Inside this, place the first three buttons:

<Button
    android:id="@+id/save_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/save" />
<Button
    android:id="@+id/export_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/export" />
<Button
    android:id="@+id/load_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/load" />
Each button has an ID for identification in Java and an text string which we will define soon. We need a second row of buttons, so after the Linear Layout for these three, add another:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
<Button
    android:id="@+id/new_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/new_pic" />
<Button
    android:id="@+id/delete_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/delete" />
<Button
    android:id="@+id/set_colors_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#333333"
    android:padding="5dp"
    android:text="@string/set_colors"
    android:textColor="#ffffff"
    android:textStyle="italic" />
</LinearLayout>
Notice that the last button is slightly different - it's for setting the user display preferences. Add the button strings listed to your strings XML values file:

<string name="save">Save</string>
<string name="export">Export</string>
<string name="load">Load</string>
<string name="new_pic">New</string>
<string name="delete">Delete</string>
<string name="set_colors">Settings</string>
Here is a preview of the main Activity:

As you can see, we aren't dedicating too much effort to the design for the app so that we can focus on the storage aspect in this tutorial series, but you can of course come up with any design features you like.

Step 3: Build the Settings Layout

On pressing the Settings button, the user will be able to choose text and background colors for the text-area. To this end, create a new Activity in your project by selecting its main package in Eclipse and choosing File, New, Class. Give your class the name "ColorChooser" and extend its opening declaration as follows:

1
public class ColorChooser extends Activity {
You will need to add an import for the Activity class if Eclipse does not add it automatically:

1
import <span class="skimlinks-unlinked">android.app.Activity</span>;
Add the onCreate method inside the class:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.color_choice);
}
This requires the following import:

1
import <span class="skimlinks-unlinked">android.os.Bundle</span>;
Save your class and add the specified layout file by choosing the "res/layout" folder and selecting File, New, File. Enter "color_choice.xml" as the file name to match what we have in the Activity class. Click Finish and Eclipse should open your file. This layout is going to include a Scroll View with a Linear Layout inside it, so add them as follows:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:padding="10dp" >
        
</LinearLayout>
</ScrollView>
Inside the Linear Layout, first add an explanatory text-field:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/color"
    android:textStyle="italic" />
Add the specified string to your strings values file:

1
<string name="color">Choose a color scheme:</string>
Back in the layout for the color chooser, add an Image Button for each color scheme you want to use. We will be using three options:

<ImageButton
    android:id="@+id/colors_0"
    android:layout_width="75dp"
    android:layout_height="75dp"
    android:scaleType="fitXY"
    android:background="#00000000"
    android:contentDescription="@string/colors0"
    android:onClick="setColors"
    android:padding="5dp"
    android:src="@drawable/colors0"
    android:tag="#000000 #ffffff" />
<ImageButton
    android:id="@+id/colors_1"
    android:layout_width="75dp"
    android:layout_height="75dp"
    android:scaleType="fitXY"
    android:background="#00000000"
    android:contentDescription="@string/colors1"
    android:onClick="setColors"
    android:padding="5dp"
    android:src="@drawable/colors1"
    android:tag="#ffffff #000000" />
<ImageButton
    android:id="@+id/colors_2"
    android:layout_width="75dp"
    android:layout_height="75dp"
    android:scaleType="fitXY"
    android:background="#00000000"
    android:contentDescription="@string/colors2"
    android:onClick="setColors"
    android:padding="5dp"
    android:src="@drawable/colors2"
    android:tag="#ffcc00 #000099" />
Take a moment to look over this code. Each Image Button has an ID with an incrementing integer suffix. The onClick attribute specifies a method which will execute in the Activity using this layout whenever users click a button. Each button also has a tag representing the two colors for the scheme as hexadecimal strings. When the user clicks a button, the setColors method will execute (we will write it later) - from there the Java code will be able to retrieve the tag, which tells us the colors to set for text and background. You can create your own button images or use these:

 
You need a copy of each image in each drawables folder in your app directory - you can copy them into each folder in your Eclipse workspace directory. If you are creating your own button images, you can tailor them to different screen sizes. Once you have the images in your drawables folders you can refresh the project in Eclipse to update it. Add the three strings indicated to your strings values file:

<string name="colors0">Black on White</string>
<string name="colors1">White on Black</string>
<string name="colors2">Yellow on Blue</string>
We are going to apply a theme to the Activity when we write the Manifest file, so it will appear as follows:

Step 4: Edit the Project Manifest

Let's round part 1 off by editing the project Manifest file. Open it in Eclipse by double-clicking it in the application package. Choose the XML tab to edit the code directly. We need user permission to write to external storage, which is what we are going to do when users export their drawings. Inside the Manifest element but outside the application element, add the permission element:

1
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
The app is going to have three Activities - the main Activity, the color chooser and one which will launch when the user wants to load a saved image. After the existing Activity element in your Manifest, add the other two inside the application element:

<activity android:name=".ColorChooser" android:theme="@android:style/Theme.Dialog"></activity>
<activity android:name=".PicChooser" android:theme="@android:style/Theme.Dialog"></activity>
These two will appear as pop-up style screens on top of the main Activity screen. We will create the Activity and layout for the "PicChooser" screen when we build the database elements of the project. The source code download contains the full Manifest file if you need to check yours (it may vary slightly depending on which ADT version you are using and what options you chose when creating the project). If you run your application now you will see the editable text-field but none of the buttons will function yet.

Conclusion

That's our project set up and ready for building the application logic. Use the attached source code download to check your code if you are unsure about any of it. In the next part we will handle exporting the user's entered artwork as an image file and implement the color scheme configuration feature. In the following two parts we will implement the saving, deleting and loading functions, all of which will use an SQLite database.

No comments:

Post a Comment