View Course Path

Create a Notes App in Android – Full code and simple explanation

What will you learn while building a notes app?

  1. Linking an ArrayList to a ListView with the help of an ArrayAdapter.
  2. Using an Intent to jump between two Activities and sending data through Intents.
  3. Using a multiline EditText and changing its text orientations.
  4. Adding permanent storage to the app using SharedPreferences.
  5. Using the AlertDialog library.
  6. Learn how to add the Menu functionality.
  7. Using onItemLongClickListener() on Views.
  8. Using addTextChanged() and newTextWatcher() to check behaviour of text changing.
Note: Find the full code of the Note Making app towards the end of the post. Read the entire post for further clarification and explanations.

How to build a notes app in Android?

Making a Notes application is relatively simple; this article provides you with all the required step-by-step procedures. You’re just required to know the basic usage of the Java language and functioning of the Android Studio. We’ll use a ListView to select and display the created notes in the MainActivity of our project. To add and edit a note, we’re going to use the OnItemClickListener() function to get redirected to another activity, where we’ll use an EditText view to make changes and then save the note.

The storage of the data can be made viable in many ways, notably:

  • SQLite
  • SharedPreferences
  • External Database Client
  • Hosting on a Server (Cloud storage)

We’ll be using SharedPreferences for our app in this project.

But skipping the rest of the formal introductions, let’s dive right into the initial steps to create the Note Making app from scratch, in the easiest, and yet a very efficient way. Let’s begin!

Components required for this app

  1. ListView: To display the created notes.
  2. Menu: To add a note.
  3. A secondary Activity: To actually add a note.
  4. EditText: To create/edit a note.

Building the interface for our notes app

We begin with the Android Studio application (here, v3.6.3 is used) and proceed by selecting an “Empty Activity” to start building our app. Then by giving a name to our project and selecting the minimum supported Android version, we proceed.

Selecting the Activity
Selecting the Activity

 

Straightaway heading to the activity_main.xml file, we get rid of the default text line and add a ListView to our app-screen from the Legacy tab of the Palette. Give it an ID of “listView” and set up the layout and margins. The ListView element is added to the XML file, with all its intrinsic properties defined by a value in the “.”

It will look somewhat like this:

<ListView
android:id="@+id/listView"
android:layout_width="409dp"
android:layout_height="729dp"
tools:layout_editor_absoluteX="1dp"
tools:layout_editor_absoluteY="1dp" />

Alternatively, if you wish to make this dynamic, then you can add the values “wrap_content” and “match_parent.”

Then, we head right over to the MainActivity.java file to start writing our code!

Coding the functionality of our notes app:

Now, we switch over to the coding part of our project.

We’ll be jumping around our activities a lot in this project. So make sure you read the explanation part to know which piece of code is going where.

Step 1: Setting Up The MainActivity

  • In the onCreate() method, we begin by setting up our ListView and finding the view by its ID.
  • Now we’re going to need an ArrayList of strings linked to our ListView, and we’ll need to access the ArrayList from all parts of our code, so define it outside the onCreate() method, in the MainActivity block.
  • To form the link, we also require an ArrayAdapter as well, which we also declare in the MainActivity block. For now, just add the field “Example note” to the ArrayList and define the ArrayAdapter using the “this” context and the ArrayList, which you created and set it up to the ListView.

The MainActivity class looks like this right now:

public class MainActivity extends AppCompatActivity {

    ArrayList<String> notes = new ArrayList<String>();
    ArrayAdapter<String> arrayAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listView = (ListView)findViewById(R.id.listView);

        notes.add("Example Note");
        arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, notes);
        listView.setAdapter(arrayAdapter);              
       }
}

So what’s happening in this code?

  1. We are defining our ArrayList and ArrayAdapter objects outside the onCreate function. This is because we want to use these objects in other functions too.
  2. We are creating a new ListView object (listView), and connecting it to the listView we created in the XML file by its ID (listView). Don’t get confused because we gave them both similar names. You can use different names.
  3. Next, we are adding an example note to our List.
  4. Finally, we are defining our ArrayAdapter.

What is an ArrayAdapter?

ArrayAdapter forms the link between the ArrayList and the items on the ListView. It can be used as a constructor in many ways. You can read the complete ArrayAdapter documentation.

The ArrayAdapter we are using has three parameters.

public ArrayAdapter (Context context, int resource, int textViewResourceId)
  1. Context: The current context. This value can’t be null. In this example, the current context is given by “this.”
  2. Resource: The resource ID for a layout file containing a layout to use when instantiating views.
  3. textViewResourceId: The id of the TextView within the layout resource to be populated

We have taken care of the basic set-up of our app. Moving on, we need to add a new activity that would take care of the creating and saving of the new notes that we’ll add to our app.

Step 2: Building the Note Editing Activity

We go to File->New->Activity->Gallery, and we select a new “Empty Activity” to add to our project, which will take care of editing and saving notes. We’ll redirect to this activity whenever we’d want to add a new note or edit an existing one.

New Activity in notes app
Creating a new empty Activity

 

Straightaway, we jump to the XML file of this activity and add a “Multiline” EditText to it and make it full screen and give it an ID.

Linking the two activities and sending data with an Intent

Now we jump back over to the MainActivity.java file and set up an onItemClickListener() to the ListView so that when we tap on a note-line, we jump over to our Note Editing activity. We do this by creating an Intent with the getApplicationContext() and to make it jump to the Note Editing activity that we have created. Along with the intent, we send the integer position variable by the putExtra() method, which tells us which row was clicked on to make it viable to add/edit the note just to that position and leave the rest of the ListView unaffected.

Add this following code inside the onCreate() function in MainActivity.java.

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    {
        Intent intent = new Intent(getApplicationContext(), NoteEditorActivity.class);
        intent.putExtra("noteID", position);            //to tell us which row of listView was tapped
        startActivity(intent);
    }
});

Receiving data with an Intent

Then we set up an Intent in the Note Editor Activity as well, that gets the sent intent and data via the getIntent() and getIntExtra() methods accordingly. We set up a default value = -1 for the noteID variable so that if there is an error while calling the Note Editor Activity, some random number doesn’t get passed into the noteID variable of that activity.

Add this code in the NoteEditorActivity.java file. (If you can’t locate this activity, then it’s the java file of the new empty activity you set up.)

public class NoteEditorActivity extends AppCompatActivity {

    int noteID;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_note_editor);

        EditText editText = (EditText)findViewById(R.id.editText);
        Intent intent = getIntent();
        noteID = intent.getIntExtra("noteID", -1);         //default value is -1 (in case of intent error)
    }
}

Now, we set up the EditText’s data to the value stored in the MainActivity’s notes ArrayList, with respect to the value of the noteID variable. But for this, we need to be able to access the notes ArrayList from the Note Editor Activity. This is done by adding the static keyword to the declaration of the ArrayList back in the MainActivity, i.e. :

static ArrayList<String> notes = new ArrayList<String>();

The EditText of the Note Editor Activity gets its value by:

if(noteID != -1)
{
    editText.setText(MainActivity.notes.get(noteID));
}

Also, to make the text appear on the top-left on the screen, you might need to change the gravity of the EditText to top|left via the xml file.

Setting up a textWatcher() argument to know when a note is edited

Now, we need to add an addTextChangedListener() to our EditText so that it runs the desired code when any text is typed/modified into the current note.

It takes in a new TextWatcher() argument, which then implements some methods by default. Out of those, we need to work in the onTextChanged() method, where we would require to update the notes ArrayList as the text in the EditText field is being changed. Here, we change the value of the desired position of the “notes” by using the set() method and providing the CharSequence to the noteID by converting it to a String. We also have to use the notifyDataSetChanged() method on the ArrayAdapter to update our ListView in the MainActivity as well. So, we add the “static” keyword in the ArrayAdapter’s definition as well.

editText.addTextChangedListener(new TextWatcher()
{
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after)
    {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)
    {
        MainActivity.notes.set(noteID, String.valueOf(s));
        MainActivity.arrayAdapter.notifyDataSetChanged();
    }

    @Override
    public void afterTextChanged(Editable s)
    {

    }
});

Step 3: Adding a menu to the app for adding new notes

Now that we’ve linked both our activities and set up the editing of the notes, we move on to add the feature of adding new notes to our app. We do this by creating a drop-down menu in our app.

First, right-click on the res folder and create a new directory and name it “menu.” Now, add a new menu resource file within that directory and name it aptly. Go into the menu resource file and create a new item that is supposed to add a new note when it is clicked. The menu file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id = "@+id/add_note"
          android:title="Add Note"></item>

</menu>

To set up this menu option’s functionality, we go back to MainActivity and add the method onCreateOptionsMenu() and use a MenuInflater to inflate the created Menu. Then, add the onOptionsItemSelected() and use it to create a jump to the Note Editor Activity whenever the Add Note option is clicked. This is done by using an Intent.

Head on over to MainActivity.java and add the following code after the onCreate function:

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.main_menu, menu);

    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item)
{
    super.onOptionsItemSelected(item);

    if(item.getItemId() == R.id.add_note)
    {
        Intent intent = new Intent(getApplicationContext(), NoteEditorActivity.class);
        startActivity(intent);
        return true;
    }

    return false;
}

We go back to the Note Editor Activity, where we write the code for adding a new note when the noteID is not equal to -1. Here, we first add a new empty string to the notes ArrayList because initially, the new note would be empty. Then we fetch the correct index, using the size of notes and store it in the noteID variable. And for this, we need to define the noteID outside of the onCreate() method in NoteEditorActivity.java:

if(noteID != -1)
{
    editText.setText(MainActivity.notes.get(noteID));
}

else
{
    MainActivity.notes.add("");                // as initially, the note is empty
    noteID = MainActivity.notes.size() - 1;
    MainActivity.arrayAdapter.notifyDataSetChanged();
}

 

Step 4: Deleting a note

Now that we have added the function to add a new note, it is time for us to invoke the note deletion process. We do this over in the MainActivity. For the deletion, we invoke a method onItemLongClickListener() that runs a code when an item is long-pressed.

Setting up an Alert Dialog

We invoke an Alert Dialog Builder to support the deletion process. It is done by AlertDialog.Builder() with the getApplicationContext() as its argument. Then, we set the message, the positive button, and the negative button, and also the onClick() method for the DialogInterface. This will delete the selected note with respect to its index. And then, just update the ArrayAdapter code in MainActivity.java:

listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id)
    {
        new AlertDialog.Builder(MainActivity.this)                   
                .setIcon(android.R.drawable.ic_dialog_alert)
                .setTitle("Delete?")
                .setMessage("Are you sure you want to delete this note?")
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which)                        
                    {
                        notes.remove(position);
                        arrayAdapter.notifyDataSetChanged();
                    }
                })

                .setNegativeButton("No", null)
                .show();

        return true;               
    }
});

Step 5: Storing data permanently using SharedPreferences

All that’s left now is to make sure our notes remain in the memory even after we close the app and restart it, i.e., permanent storage of the notes. We would need to update the permanent storage at two places:

  1. When we delete an item in the setOnItemLongClickListener()
  2. When we save the content of the note in the onTextChanged()

We can do this in many ways, i.e., SQLite, SharedPreferences, storing data on a server, etc. But here, we would proceed with the simplest method, which is, using SharedPreferences. First, we go to the onTextChanged() method and set up our SharedPreferences instance using the package name. Here we’ll use the HashSet data type, creating it with the help of the notes ArrayList. Finally, we save it in the SharedPreferences instance that we created with the title notes.

@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
    MainActivity.notes.set(noteID, String.valueOf(s));
    MainActivity.arrayAdapter.notifyDataSetChanged();

    SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("com.tanay.thunderbird.notes", Context.MODE_PRIVATE);
    HashSet<String> set = new HashSet<>(MainActivity.notes);
    sharedPreferences.edit().putStringSet("notes", set).apply();
}

 

And then, we can just copy-paste these same 3 lines to the setOnItemLongClickListener() method in the MainActivity.

Finally, we’re ready with our app. It has all the necessary functionalities of any other “notes” app. You can now share it with your friends and family and brag about it as much as you want!

Some features of note-making apps that are not covered in this post

  1.  We have not included any functionality to pin the important notes on top of the listView. But this can be simply done by changing the indices of the rows of the listView with respect to the row that has to be placed on the top.
  2. Several Notes applications make use of reminders and alarms, to use them as memos. This can be easily done by calling an intent to add an event in the calendar of your phone!

Full Code for a working Notes Application in Android

(Don’t forget to add your own package name at the top!)

MainActivity class of the Note Making app

MainActivity’s User Interface of the Note Making app

The Menu Interface in the MainActivity of the Note Making app

The NoteEditorActivity class of the Note Making app

(Don’t forget to add your own package name at the top!)

The NoteEditorActivity’s User Interface of the Notes app

Related courses for this will be up soon!