Get AI summaries of any video or article — Sign up free
MIT App Inventor Diary App Tutorial | Display Pictures in ListView | Personal Diary App with Images thumbnail

MIT App Inventor Diary App Tutorial | Display Pictures in ListView | Personal Diary App with Images

Obsidian Soft·
5 min read

Based on Obsidian Soft's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Screen 1 stores each diary entry as a three-item list: date text, entry text, and the image picture path.

Briefing

A personal diary app built with MIT App Inventor stores dated text entries alongside user-chosen or camera-captured images, then displays everything in a searchable ListView with working view and delete flows. The core workflow is straightforward: pick a date, type an entry, attach an image (either via ImagePicker or Camera), and press Save—after which the entry appears in the list and can be opened on a second screen for full viewing.

The interface is arranged on Screen 1 using multiple horizontal layouts to keep controls aligned: a read-only Date Text box paired with a DatePicker, an Entry Text box for the diary content, and an image component to hold the selected/taken picture. Three buttons—Camera, Choose (ImagePicker), and Save—sit alongside these fields. Below them, a ListView is configured with “Image and Text” layout so each row can show a main text (date), detail text (diary entry), and an image (the picture). The ListView also enables a filter bar so users can search entries. Additional buttons (View and Delete) handle navigation and removal, while invisible components support the app’s logic: Clock for the current date, TinyDB for persistence, Notifier for alerts, and Camera for photo capture.

On Screen 1 initialization, the app sets the DatePicker to the current date using Clock.Now, then formats the chosen day/month/year into the read-only date display. When the user picks a date, the DatePicker’s AfterDateSet event updates the Date Text. Image selection is handled by ImagePicker’s selection event, which assigns the chosen image to the Image component’s Picture property. Camera capture is handled by calling Camera.TakePicture; once a photo is successfully taken, Camera’s AfterPicture event provides a file path that is stored into the Image.Picture property.

Saving is gated by validation: the app checks that the image is not empty and that the entry text is not empty. If either is missing, Notifier.ShowAlert prompts the user to provide the missing data. If both are present, the app constructs a three-item list representing one diary entry—(1) date text, (2) entry text, (3) image picture path—and appends it to a global Diary Entries list. TinyDB persists the updated list under the tag “entries,” and the ListView is populated by iterating through the stored diary entries and adding items with the same three-slot ordering.

The View button requires a selection in the ListView; if none is selected, an alert asks the user to choose an entry. When an item is selected, Screen 2 opens and receives the selected three-item list as a start value. Screen 2 initializes a local three-item list, then displays the date in the first label, the entry text in the second label, and the image in its image component from the third slot. The Delete button similarly requires a selection; it removes the selected item from both the in-memory list and the ListView, then writes the updated list back to TinyDB so the change persists.

Overall, the app demonstrates a complete end-to-end pattern in MIT App Inventor: UI input → validation → image capture/selection → structured list storage → TinyDB persistence → ListView rendering → screen-to-screen passing → delete with durable updates.

Cornell Notes

The diary app uses MIT App Inventor to save dated text entries with images and show them in a searchable ListView. Each diary entry is stored as a three-item list in a fixed order: date text, entry text, and the image picture path. TinyDB persists the entire list under the tag “entries,” and Screen 1 repopulates the ListView by iterating through stored items. A View button passes the selected three-item list to Screen 2, where labels and the image component display the chosen entry. A Delete button removes the selected item from both the ListView and the stored list, then saves the updated list back to TinyDB.

How does the app represent each diary entry so it can be saved and later displayed with text and images?

Each entry is built as a three-item list in a consistent order: (1) the date text from the read-only Date Text box, (2) the diary content from Entry Text, and (3) the image picture path from the Image component’s Picture property. When saving, that three-item list is added to the global Diary Entries list, then persisted to TinyDB. When loading, the app reads each stored three-item list and maps slot 1 to the ListView main text, slot 2 to the ListView detail text, and slot 3 to the ListView image.

What events connect user actions (date, image, camera) to the app’s on-screen fields?

Date selection uses the DatePicker’s AfterDateSet event to update the read-only Date Text box. Image selection uses ImagePicker’s selection event to set Image.Picture to the chosen image. Camera capture calls Camera.TakePicture on the Camera button click; once the photo is captured, Camera’s AfterPicture event provides a picture path, which is assigned to Image.Picture.

What validation prevents empty diary entries from being stored?

On Save button click, the app checks two conditions using an if-then-else structure: the image must not be empty (Image.Picture != empty) and the diary text must not be empty (Entry Text != empty). If either check fails, Notifier.ShowAlert displays a message prompting the user to provide a picture and/or enter diary text. Only when both are present does the app construct the three-item entry list and save it.

How does TinyDB persistence work in this app, and why does the tag matter?

TinyDB stores the entire Diary Entries list using TinyDB.StoreValue with the tag “entries.” When Screen 1 initializes, it loads data using TinyDB.GetValue with the same tag “entries,” defaulting to an empty list if no value exists. The tag must match exactly; using a different tag would cause the app to read and write different datasets, breaking persistence and list loading.

How does the View button transfer the selected diary entry to Screen 2?

The View button first checks ListView.SelectionIndex is not equal to 0 (the tutorial treats selection index 0 as “nothing selected”). If a selection exists, it opens Screen 2 and passes the selected three-item list using ListView’s selection index to index into the Diary Entries list. Screen 2 then reads the start value into a local three-item list and displays slot 1 in the date label, slot 2 in the entry label, and slot 3 in the image component.

What steps does the Delete button take to remove an entry permanently?

The Delete button also requires a valid ListView selection. It removes the selected item from the in-memory Diary Entries list using RemoveListItem with the selection index, and it removes the corresponding row from the ListView using ListView.RemoveItemAtIndex with the same selection index. Then it saves the updated Diary Entries list back to TinyDB using TinyDB.StoreValue with the tag “entries,” ensuring the deletion persists across app restarts.

Review Questions

  1. What fixed ordering of fields does the app use inside the three-item list for each diary entry, and where does each slot get displayed?
  2. Why must the TinyDB tag match exactly between storing and loading, and what default value does the app use when no data exists?
  3. How do the View and Delete buttons both rely on ListView.SelectionIndex, and what happens when nothing is selected?

Key Points

  1. 1

    Screen 1 stores each diary entry as a three-item list: date text, entry text, and the image picture path.

  2. 2

    Image attachment supports both ImagePicker selection and Camera capture, with Camera.AfterPicture providing a path for Image.Picture.

  3. 3

    Save button validation blocks storage unless both Image.Picture and Entry Text are non-empty, using Notifier.ShowAlert for feedback.

  4. 4

    TinyDB persistence uses the tag “entries” to store and retrieve the full Diary Entries list.

  5. 5

    ListView is configured with “Image and Text” layout so each row can show date, entry text, and an image.

  6. 6

    View passes the selected three-item list to Screen 2 via start value, where labels and the image component are populated from list slots.

  7. 7

    Delete removes the selected item from both the in-memory list and the ListView, then writes the updated list back to TinyDB.

Highlights

Each diary entry is stored as a three-slot list (date, text, image path), making saving and later rendering consistent.
TinyDB persistence hinges on using the exact same tag “entries” for both StoreValue and GetValue.
Screen 2 renders the chosen entry by pulling slot 1 into the date label, slot 2 into the entry label, and slot 3 into the image component.
The app’s Save flow validates both image presence and text presence before writing anything to TinyDB.
View and Delete both depend on ListView.SelectionIndex to determine which entry the user selected.

Topics

Mentioned

  • MIT
  • DB