Thursday, October 31, 2013

NotePad

In this post, you will learn to create a simple NotePad app for Android. The NotePad app can be used to view files that contain text inside. These files can be txt, html, xml, and java files. You can open the app and then browse for a file to open or alternatively you can select a file from Android to open. The current document can be edited and saved. The user can create a new file by clicking the new document icon from the action bar. The new file will be stored in the notes directory of external card of the device.

NotePad for Android


To start developing the NotePad app, now you need to create a new project. The project name will be NotePad. There are two activities in this app. The first one is the MainActivity that firstly runs when the NotePad opens. This activity represents the interface that allows the user to select a file to open.

NotePad browse for file


This MainActivity will list files and folders in the external card of the device. Below is the content of the activity_main.xml file. In this file, one ListView component is defined. The ListView will display the list of files and folders for selection.

activity_main.xml file

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ListView
            android:id="@+id/files_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:paddingBottom="5dp"
            android:paddingTop="5dp"
     
            />

</RelativeLayout>


Each row or item of the ListView displays both image and text. The image will be the file icon image or directory image. Thus it must be customized to work in this way. When customizing the ListView, as i mentioned in the previous posts, you need to define the layout file of the list and the data source of the list. Here is the content of the listlayout.xml file of the list.

listlayout file

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dip" >

<ImageView
    android:id="@+id/icon"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:padding="5sp"
    android:contentDescription="icon_image"
 />

<TextView
    android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#0000ff"
        android:textStyle="bold" >
</TextView>
</LinearLayout>


The data source of the list will be an instance of the class that extends the ArrayAdapter class. I call it ListAdapterModel class. You can download the ListAdapterModel.java file from here.
To get explanation about customizing the data source of the ListView, you might want to read the File Chooser post.

When a file is selected from the list, another activity will open and the content of the file is shown there. The data to be sent from the MainActity of the second activity (NoteActivity) is the full path of the file. The openNoteActivity method of the MainActivity class will be called to send the path file to the NoteActivity. Click the MainActivity to download the MainActivity.java file.
On the NoteActivity, you will see the content of the selected file. The EditText component is used to display the file content and allow the user to edit the content. Below is the layout file of the NoteActivity.

activity_note.xml file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"  
    android:background="#dfdfdf"    
     >

 <EditText
     android:id="@+id/txt_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:scrollbars="vertical"  
     android:textColor="#000000"
     android:gravity="top"
     android:inputType="text"
     android:textSize="16sp" />

</RelativeLayout>

You can download the NoteActivity.java file from here. The NoteActivity has an action bar. To support the old Android versions, the NotePad app uses the SherlockActionBar library to set up the action bar. You might want to read TexViewer to learn how to import this library in to your project. On the action bar, there are four items. The first item represented by the new document icon will be clicked to call the createNew method so that a new blank document will open. The second item allows you to save the edited document by calling the saveWork document. The third and forth items allow you to zoom in or zoom out the content of the current document by calling the zoomin and zoomout methods.. The items of the action bar are defined in the note.xml file that is stored in the menu folder of the project.

note.xml file

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/Theme.Sherlock"
    >
 
    <item
        android:id="@+id/newitem"
        android:icon="@drawable/new_icon"
        android:title="new"
        android:showAsAction="always"
        style="@style/Theme.Sherlock"
     
    />
    <item
        android:id="@+id/saveitem"
        android:title="save"
        android:showAsAction="always"
        android:icon="@drawable/save_icon"
        style="@style/Theme.Sherlock"
    />
    <item
        android:id="@+id/zoomin"
        android:title="zoomin"
        android:showAsAction="always"
        android:icon="@drawable/zoomin"
        style="@style/Theme.Sherlock"
    />

    <item
        android:id="@+id/zoomout"
        android:title="zoomout"
        android:showAsAction="always"
        android:icon="@drawable/zoomout"
        style="@style/Theme.Sherlock"
    />

</menu>

Before running the NotePad app, you need to edit the AndroidManifest file of the project to allow the app to use the external sdcard and to register the app in the list of avaiable apps to open the selected file. Here is the content of the AndroidManifest.xml file.

AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.notepad"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/note_icon"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock.Light.DarkActionBar" >
        <activity
            android:name="com.example.notepad.MainActivity"
            android:configChanges="orientation"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.txt" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.rtf" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.java" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.xml" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.html" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.txt" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.rtf" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.java" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.xml" />
                <data android:host="*" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PICK" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:mimeType="*/*" />
                <data android:pathPattern=".*\\.html" />
                <data android:host="*" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.notepad.NoteActivity"
            android:label="@string/title_activity_note"
            android:configChanges="orientation"
            android:parentActivityName="MainActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="MainActivity" />
        </activity>
    </application>

</manifest>


Download the apk file of the NotePad app

No comments:

Post a Comment