0

I'm a 16-year-old trying to build a productivity app. This is my first time every coding in Kotlin, using Android Studio, and developing an app, so please don't be too harsh. :)

What I Want

My app is a calendar app in which opening the app presents a calendarView that allows you to pick a date. Choosing the date opens a note template view containing a text field that the user can write their notes in. After writing their notes, the user can press the 'Back' button to return to the date choosing screen and begin the process of taking notes once again in another date. If a note for a date is already created, the note and it's contents are accessed and spit onto the note template.

Issue

Once I create my first note upon opening the app, it works fine and I can exit to the date screen with no problem. However, when I try to click another date to create a new Note, there is no response.

My Attempt To Fix The Issue

I tried troubleshooting to see what the issue was by creating a Toast popup everytime the DateChange listener detected a date was chosen. I found that my listener was not functioning at all after coming back to the date choosing screen after clicking the back button. I have even tried asking Chat GPT, but to no avail. I'm trying my hardest to find the issue but I'm losing hope fast. I will leave my code down below, please comment and let me know of any solutions or mistakes I have made. Thanks for your time!

Code begins below -




package com.effici.application

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.widget.Button
import android.widget.CalendarView
import android.widget.TextView
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import com.google.android.material.textfield.TextInputEditText

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.date_screen)
        val dateChoosingCalendar = findViewById<CalendarView>(R.id.dateChoosingCalendar)
        lateinit var noteInputField: TextInputEditText
        var notesList = arrayListOf<Note>()
        lateinit var backButton: Button

        dateChoosingCalendar.setOnDateChangeListener { _, year, month, dayOfMonth ->
                val chosenDate = "$dayOfMonth-${month + 1}-$year"
                var noteAlreadyCreated = false
                var noteIndex = 0
                for (i in 0 until notesList.size) {
                    if (chosenDate == notesList[i].date) {
                        noteAlreadyCreated = true
                        noteIndex = i
                        break
                    }
                }

                if (noteAlreadyCreated) {
                    println("Note already created.")
                    setContentView(R.layout.note_template)
                    noteInputField = findViewById<TextInputEditText>(R.id.noteTakingField)
                    backButton = findViewById<Button>(R.id.changeButton)
                    backButton.setOnClickListener {
                        notesList[noteIndex].text = noteInputField.text
                        setContentView(R.layout.date_screen)
                        noteInputField.setText(notesList[noteIndex].text)
                    }
                } else {
                    notesList.add(Note(userinp = null, dateParam = chosenDate))
                    noteIndex = notesList.size - 1
                    setContentView(R.layout.note_template)
                    noteInputField = findViewById<TextInputEditText>(R.id.noteTakingField)
                    backButton = findViewById<Button>(R.id.changeButton)
                    println("A note for $chosenDate is added.")
                    backButton.setOnClickListener {
                        notesList[noteIndex].text = noteInputField.text
                        setContentView(R.layout.date_screen)
                    }
                }
            }
        }

    }


class Note(val userinp: Editable?, val dateParam: String)
{
    var text: Editable? = userinp
    var date = dateParam
}
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Normally, you would NEVER call `setContentView` more than once in the same Activity. Your two different screens need to handle different logic, but you're mish-mashing it all together into one class, so it's almost impossible to follow the logic. And it will be very fragile and prone to bugs that will cause crashes. You either need to create a separate Activity class for each screen, or use a Fragment to represent each screen and host them both in the same Activity. – Tenfour04 Jul 14 '23 at 18:31
  • The Android documentation has instructions on how to do this. Multiple activities is easier for beginners, although it has some downsides so Fragments are the recommended way to do it. Also, you will have to eventually change it so you are putting the notes in a file or database, or else they will be lost the moment the user exits the app or rotates the screen. – Tenfour04 Jul 14 '23 at 18:33
  • [It's not a good idea to use `setContentView` multiple times](https://stackoverflow.com/q/22227950/8192914). But, as a quick fix, you can try initializing `dataChoosingCalendar` and its listener inside `onResume()`. let me know if this solution fails. I would still recommend that you use fragment or another activity for your note view – ganjaam Jul 14 '23 at 18:35
  • @ganjaam's link's answers only mention the performance problems with calling it multiple times, but I think a much bigger issue is that your code becomes extremely convoluted. You will be leaking layouts from holding obsolete views in variables/properties, and it will be difficult to track what state the app is in. – Tenfour04 Jul 14 '23 at 18:37
  • First of all, thank you both for your information filled responses! Could you elaborate on how creating separate activity classes and managing them works @Tenfour04? I should also note that the note_template is a different activity, and I'm going to it by using setContentView(). – Nandan Praveen Jul 17 '23 at 13:43
  • Start by reading this: https://developer.android.com/guide/components/activities/intro-activities then look up tutorials on getting a result from another activity. If you do this with multiple activities instead of fragments, you will need to move your list into a ViewModel first (you will have to do this regardless to protect it from screen rotations, but you will have to do it immediately to protect it from activity changes ). – Tenfour04 Jul 17 '23 at 14:11
  • I will do everything you mentioned above and let you know any final questions I have. Thank you SO much for this, I can't express in words how grateful I am for your help. – Nandan Praveen Jul 17 '23 at 15:31

0 Answers0