Intro to Android Development
  • Welcome
  • Syllabus
  • Hack Challenge
  • Resources
    • Lecture Videos
    • Ed Discussion
    • Git & GitHub Help/How-To
    • Setting up Android Studio
    • Starting an Android Studio Project & Making an Emulator
    • Importing, Exporting, & Submitting Your Projects to CMS
  • SP25 Course Material
    • Week 1 | Course Logistics, Kotlin, & Basic UI
      • Relevant Links
      • Demo/Lecture: Eatery Card
      • A0: Eatery Card (Follow-Along)
    • Week 2 | States, Components, LazyColumn
      • Relevant Links
      • Demo: Todo List
      • A2: Shopping List
    • Week 3 | Navigation & Animations
      • Relevant Links
      • Demo: Onboarding
      • A3: Stock Trading (RobbingGood)
    • Week 4 | MVVM and Flows
      • Relevant Links
      • Demo: Eatery Card 2
      • A4: Chat of a Lifetime
    • Week 5 | Dumb Components & UIEvents
      • Relevant Links
      • Demo: Music Player
      • A5: Rate My Vibe
    • Week 6 | Coroutines, Networking, JSON
      • Relevant Links
      • Demo: Retrofit
      • A6: You Should Even Lift, Bro.
  • Bonus Week | Android Job Search
    • Relevant Links
    • Android Technical Interview Question!
  • Textbook
    • 1. Introduction to the Editor and Views
      • 1.1 Introduction to the Editor
      • 1.2 SDK Management
      • 1.3 Kotlin Overview
      • 1.4 Views
      • 1.5 Android Studio Project Demo + Understanding The Editor
    • 2. Jetpack Compose
      • 2.1 Introduction
      • 2.2 Layouts
      • 2.3 Modifiers
      • 2.4 Animations
      • 2.5 Lazy Lists
      • 2.6 Reactive UI
    • 3. Intents and Manifest
      • 3.1 Activities
      • 3.2 Implicit Intents
      • 3.3 Explicit Intents
      • 3.4 Manifest
      • 3.5 Permissions
      • 3.6 Summary
    • 4. Navigation
      • 4.1 Types of Navigation
      • 4.2 Implementation of the Bottom Navigation Bar
    • 5. Data and Persistent Storage
      • 5.1 Singleton Classes
      • 5.2 Shared Preferences
      • 5.3 Rooms
      • 5.4 Entities
      • 5.5 Data Access Objects
      • 5.6 Databases
    • 5.5 Concurrency
      • 5.5.1 Coroutines
      • 5.5.2 Implementation of Coroutines
      • 5.5.3 Coroutines with Networking Calls
    • 6. Networking and 3rd Party libraries
      • 6.1 HTTP Overview
      • 6.2 3rd Party Libraries
      • 6.3 JSON and Moshi
      • 6.4 Retrofit
      • 6.5 Summary
    • 7. MVVM Design Pattern
      • 7.1 Key Idea
      • 7.2 Implementation Ideas
    • 8. Flows
    • 9. The Art and Ontology of Software
    • 10. 🔥 Firebase
      • 10.1 Setting up Firebase
      • 10.2 Authentication
      • 10.3 Analytics
      • 10.4 Messaging
      • 10.5 Firestore
  • Additional Topics
    • Git and GitHub
    • Exporting to APK
  • Archive
    • Archived Native Android Textbook Pages
      • 1. Layouts and More Views
        • 1.1 File Structure and File Types
        • 1.2 Resource Files
        • 1.3 Button and Input Control
        • 1.4 ViewGroups
        • 1.5 Summary + A Note On Chapter 2 Topics
      • 2. RecyclerViews
        • 2.1 RecyclerViews
        • 2.2 RecyclerView Performance
        • 2.3 Implementation of a Recycler View
        • 2.4 Implementation with Input Controls
        • 2.5 Filtering RecyclerViews
        • 2.6 Recyclerview Demo
      • 3. ListViews and Searching
        • 3.1 ListView vs. RecyclerView
        • 3.2 ListView Performance
        • 3.3 Implementation of a ListView
        • 3.4 Searching in a List View
      • 4. Fragments
        • 4.1 What are Fragments?
        • 4.2 Lifecycle of a Fragment
        • 4.3 Integrating a Fragment into an Activity
        • 4.4 Sharing Data Between Fragments
        • 4.5 Fragment Slide Shows
      • 5. OkHttp
      • 6. Activity Lifecycle
      • 7. Implementation of Tab Layout
    • Fall 2024 Course Material
      • Lecture 1 & Exercise 1: Introduction to Android
      • Lecture 1.5: Beauty of Kotlin
      • Lecture 2 & HW 2: Modifiers, Lazylists and Reactive UI
      • Lecture 3 & HW 3: Animations, Intents and Manifest
      • Lecture 4 & HW 4: Coroutines & Navigation
      • Lecture 5 & HW 5: Persistent Storage, Networking, and JSON Parsing
      • Lecture 6 & HW 6: MVVM, Flows
      • Bonus Lectures & Bonus HW
      • Bonus Lecture: Industry Practice
    • Spring 2024 Course Material
      • Lecture 1 & Exercise 1: Introduction to Android
      • Lecture 4 & HW 4: LazyLists
      • Lecture 6 & HW 6: Networking, Data, and Persistent Storage
    • Spring 2020 Course Material
      • Week 1: Intro to the Editor
      • Week 2: Views and Layouts
      • Week 3: Intent and Manifest
      • Week 4: ListView and RecyclerView
      • Week 5: Fragments
      • Week 6: Networking
    • Spring 2021 Lecture & HW 8: Networking & 3rd Party APIs
    • HackOurCampus Workshop
Powered by GitBook
On this page
  • Release Code:
  • Requirements:

Was this helpful?

  1. SP25 Course Material
  2. Week 4 | MVVM and Flows

A4: Chat of a Lifetime

Asking the real questions in life!

PreviousDemo: Eatery Card 2NextWeek 5 | Dumb Components & UIEvents

Last updated 2 months ago

Was this helpful?

This assignment has a release code! Please download it below, extract it, and open it in Android Studio. Ensure it can compile and run fine on your emulator before starting this assignment.

For our third assignment, we'll have you implement the ViewModel to connect up a mock chat app! Instead of chatting with another real person (as that would require a lot of real, complex networking), we'll have you chat with a mini pocket philosopher on your phone!

We've had enough assignments about money at this point, haven't we? And money isn't happiness, after all...

Let's walk through the code, shall we?

Release Code:

Expand each of the files below for a description of the release code!

ChatRepository.kt

A Model class that performs (mock) networking tasks to implement that chatbot/chat functionality.

DO NOT EDIT THIS FILE.

You may interface with this file, though, using the following properties, to complete (mock) networking:

  • chatMessageFlow: A flow emitting a list of (all) the chat messages in the history of the chat.

  • currentlyTypingFlow: A flow emitting (as a Boolean) whether the chatbot is "typing" or not.

  • botNameFlow: A flow emitting the name of the chat bot.

  • sendMessage(text: String): A mock networking function that will send the user's text message as a chat message.

ChatViewModel.kt

A (Hilt) ViewModel class that connects up ChatRepository.kt and ChatScreen.kt.

You'll mostly be working in this file for your solution. This file is VERY incomplete.

For starters though, we've given you...

  • uiStateFlow: The (only) state flow that your VM should use to emit state down to the UI. Emits an object of type ChatUiState.

  • ChatUiState: A data class representing the UI state that contains ALL the data that ChatScreen.kt needs to know. This class is currently incomplete; you'll need to add fields here as you go.

ChatScreen.kt

The primary (and only) UI screen in this assignment. It consists of a header, a body consisting of chat messages in a big LazyColumn, and a footer where the user can type in a message and send.

For organization, this file consists of several @Composables:

  • ChatScreen(): The main screen Composable.

  • ChatFooter(): The footer, where the text field and send button lay.

  • ChatHeader(): The header, where the chat bot's name and last sent text lay.

There happens to be a @Preview here for the header; take a look if you'd like!

There are a few other files here, but those are not too important and are mostly complete:

  • ChatBubble.kt is just a component for the Chat Bubble.

  • Other files are basically junk; don't worry about them.


Requirements:

Okay, onto the assignment!

This assignment is a bit different from previous assignments in that you'll be implementing features, one by one. The reason we do not split then into files is because your solution will often have to span several files for each feature.

(expand each of your features' requirements below!)

1) Reading the Message Flow

First, let's connect our chat up with our pocket philosopher! It wants to say some stuff to us right now, but we can't quite hear it just yet until we connect our VM to our Model repository!

  1. Inject an instance of ChatRepository.kt into our ViewModel.

  2. Read the flow value of the chat messages flow from the repository, using it to update (with a copy) the current Ui State Flow with the correct messages!

For this section, we've already hooked up the messages field from the UiState to the UI. So this should be all you need to do!

Note: If you've done this correctly, you should no longer see the initial test messages, and should now see the following chat:

Seems like our philosopher is trying to reach us! Let's finish the next parts so we can have a nice, deep chat :-)

2) Typing into the Text Field

If you currently try typing into the text field in the footer, nothing changes, and the text currently freezes at "TODO". Let's fix this!

  1. Add a new field to ChatUiState corresponding to the text currently typed into the text field.

  2. Pipeline this down the the UI such that the UI now reads from this text and puts it through the ChatFooter() into the BasicTextField value.

  3. Now time for the reverse direction! Add a new function onTextChanged(text: String) to your VM. Make it so that when you type text and the BasicTextField value changes, this VM method is called!

Hints:

  • You'll need to add new arguments to ChatFooter()!

  • Ideally, 2 new arguments: one for the text downwards, and one for the onTextChanged upwards!

You should now be able to type a message into the box. But you can't quite send it yet...

3) Sending a Message

Now let's allow ourselves to actually send a message to our philosopher!

  1. Change the derived field value isSendEnabled such that if the typed text (field in your ChatUiState from part 2) is non empty, it is true, otherwise false.

    1. If you've done this correctly, the Send button should now turn enabled if you've typed in text!

  2. Add an onSend() that gets called by the Button onClick in ChatFooter. You'll need to pipeline this onClick upwards, similar to what you did in part 2.

  3. Implement onSend() :

    1. Send the (typed in) message by calling chatRepository.sendMessage(...) .

    2. Clear the typed in message after the message is sent.

You should now be able to send a message and see your philosopher respond! In fact, you should actually be able to converse with your philosopher now. Try it out!

4) Reading the Header Flow Information

Okay, nearly there! But the name we've given our philosopher isn't quite showing up top! And our chat isn't keeping track of when our last message was sent... let's fix that!

  1. Similarly to previous parts, hook up ChatRepository's botNameFlow down through the Repository, to the VM, to the UI, so that the TODO text now reads the bot's name!

    1. It should be ??? at first, then populate with your name you've given after you give the philosopher a name.

  2. Do the same for timestampFlow such that the "Last message sent at: TODO" now reads the correct time!

(A lot of working with MVVM is going through these motions. After this, we just have one more and you'll be an expert!)

Here's an example of what you should see after you name your philosopher:

5) Reading the Currently Typing Flow

Finally for a finishing touch! Your philosopher often pauses and takes time to think, but also takes time to type out a response! It'd be great if you could have a little indicator for that...

Thankfully, your UI already has this! See the TODO for part 5) in ChatScreen?

  1. Read from currentlyTypingFlow from the chat repository (down through the VM, to the UI) to put the correct boolean condition for if the philosopher is typing (instead of just currently FALSE).

If you've solved A4 correctly, your solution should look something like this...

When you're done, export your project through Android Studio and upload your ZIP to CMS! Congrats on finishing A4!

Note: Perhaps you find it annoying that you have to scroll with each message manually? We'll learn a solution for that next week with UIEvents!

114KB
a4-release.zip
archive
A4 Release Code!
7MB
a4-soln-demo.mp4
A4 Soln Demo Video!
Exporting with File -> Export -> Export to Zip File...