-1

The code below relates to my DatePicker method that you can choose a date and the TextView displays the date chosen as shown https://i.stack.imgur.com/cco6D.png

I have a saveData() and loadData() function and when I go to save the data from my DatePicker, it doesn't display the date chosen by the user after I go back into my Letter created.

I currently have a setOnClickListener within my ActivityMain that doesn't seem to be called when the app is run and also my Toast I setup within saveData() also doesn't display when the data is inputted and updated and no data is being saved within shared_prefs within Android Device File Explorer which leads me to believe these might be problems that are stopping my app from saving user-inputted data but not sure how to go abouts fixing.

Where should I input the setOnClickListener within my saveData function?

activity_layout.xml code

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn_timePicker"
    android:text="What's the date?"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/textTime"
    android:layout_marginTop="20dp"
    android:textColor="#000000"
    android:textSize="22sp"
    android:textStyle="bold"
    tools:text="@tools:sample/date/ddmmyy"/> 
 

Here is the code in ActivityMain

class NewsActivity : AppCompatActivity(), AnkoLogger, DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener {



    var letter = NewsItemModel()
    lateinit var app : MainApp
    var edit = false
    val IMAGE_REQUEST = 1

    /* https://www.youtube.com/watch?v=GmmyCOpIutA&ab_channel=CodePalace */
    var day = 0
    var month = 0
    var year = 0
    var hour = 0
    var minute = 0

    var savedDay = 0
    var savedMonth = 0
    var savedYear = 0
    var savedHour = 0
    var savedMinute = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_letter)
        app = application as MainApp

        loadData()


        btn_timePicker.setOnClickListener {
            saveData()
            Log.d("ClickListener", "just got clicked")
        }

        ratingBar.rating = 2.5f
        ratingBar.stepSize = .5f

        pickDate()

        val dropDownList = arrayOf("Latest", "Coronavirus Updates", "Crime", "Traffic and Travel", "Business", "Politics", "Weather", "Education", "Health")

        val adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, dropDownList)
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_item)
        statusFilter.adapter = adapter
        statusFilter.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{

            override fun onNothingSelected(parent: AdapterView<*>?) {
            }



            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
                if(statusFilter.selectedItemPosition == 1){
                    condition1()
                }
                if(statusFilter.selectedItemPosition == 2){
                    condition2()
                }
                if(statusFilter.selectedItemPosition == 3){
                    condition3()
                }
                if(statusFilter.selectedItemPosition == 4){
                    condition4()
                }
                if(statusFilter.selectedItemPosition == 5){
                    condition5()
                }
                if(statusFilter.selectedItemPosition == 6){
                    condition6()
                }
                if(statusFilter.selectedItemPosition == 7){
                    condition7()
                }
                if(statusFilter.selectedItemPosition == 8){
                    condition8()
                }
                if(statusFilter.selectedItemPosition == 9){
                    condition9()
                }
            }

            private fun condition1(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
            private fun condition2(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
            private fun condition3(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
            private fun condition4(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
            private fun condition5(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
            private fun condition6(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
            private fun condition7(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
            private fun condition8(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
            private fun condition9(){
                Toast.makeText(getApplicationContext(), "selected Item: " + statusFilter.selectedItem, Toast.LENGTH_LONG).show()
            }
        }

        val submission = findViewById<Button>(R.id.submit_button)

        submission.setOnClickListener {
            Toast.makeText(this, "Button is clicked", Toast.LENGTH_LONG)
        }


        ratingBar.setOnRatingBarChangeListener { ratingBar, rating, fromUser ->
            Toast.makeText(this, "Rating: $rating", Toast.LENGTH_SHORT).show()
        }




        LetterLocation.setOnClickListener {
            startActivity(intentFor<MapsActivity>())
        }

        chooseImage.setOnClickListener {
            showImagePicker(this, IMAGE_REQUEST)
        }

        if (intent.hasExtra("NewsLetter_edit")) {
            edit = true
            letterImage.setImageBitmap(readImageFromPath(this, letter.image))
            if (letter.image != null) {
                chooseImage.setText(R.string.change_letter_image)
            }
            letter = intent.extras?.getParcelable<NewsItemModel>("NewsLetter_edit")!!
            letterTitle.setText(letter.title)
            letterDescription.setText(letter.description)
            letterAuthor.setText(letter.author)
            letterImage.setImageBitmap(readImageFromPath(this, letter.image))
            btnAdd.setText(R.string.save_letter)
        }

        btnAdd.setOnClickListener() {
            letter.title = letterTitle.text.toString()
            letter.description = letterDescription.text.toString()
            letter.author = letterAuthor.text.toString()
            if (letter.title.isEmpty()) {
                toast(R.string.enter_letter_title)
            } else {
                if (edit) {
                    app.letters.update(letter.copy())
                } else {
                    app.letters.create(letter.copy())
                }
            }
            info("add Button Pressed: $letterTitle")
            setResult(AppCompatActivity.RESULT_OK)
            finish()
        }

        toolbarAdd.title = title
        setSupportActionBar(toolbarAdd)
    }

   private fun saveData() {
        val insertedText = btn_timePicker.text.toString()
        val key1 = "STRING_KEY"
        val key2 = "BOOLEAN_KEY"

        textTime.text = insertedText
        val sharedPreferences = getSharedPreferences("sharedPrefs", Context.MODE_PRIVATE) ?: return

            with(sharedPreferences.edit()) {
                putString(key1, insertedText)
                apply()
            }
            Toast.makeText(this@NewsActivity, "Data Saved", Toast.LENGTH_SHORT).show()
        }


    private fun loadData() {
        val sharedPreferences  = getSharedPreferences("sharedPrefs", Context.MODE_PRIVATE)
        val savedString = sharedPreferences.getString("STRING_KEY", null)

        textTime.text = savedString
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_letter, menu)
        if (edit && menu != null) menu.getItem(0).setVisible(true)
        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item?.itemId) {
            R.id.item_delete -> {
                app.letters.delete(letter)
                finish()
            }
            R.id.item_cancel -> {
                finish()
            }
        }
        return super.onOptionsItemSelected(item)
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            IMAGE_REQUEST -> {
                if (data != null) {
                    letter.image = data.getData().toString()
                    letterImage.setImageBitmap(readImage(this, resultCode, data))
                    chooseImage.setText(R.string.change_letter_image)
                }
            }
        }
    }


    private fun getDateTimeCalendar(){
        val cal = Calendar.getInstance()
        day = cal.get(Calendar.DAY_OF_MONTH)
        month = cal.get(Calendar.MONTH)
        year = cal.get(Calendar.YEAR)
        hour = cal.get(Calendar.HOUR)
        minute = cal.get(Calendar.MINUTE)
    }

    private fun pickDate() {
            getDateTimeCalendar()

            DatePickerDialog(this, this, year, month, day).show()
    }


    override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
        savedDay = dayOfMonth
        savedMonth = month
        savedYear = year

        getDateTimeCalendar()
        TimePickerDialog(this, this, hour, minute, true).show()
    }

    override fun onTimeSet(view: TimePicker?, hourOfDay: Int, minute: Int) {
        savedHour = hourOfDay
        savedMinute = minute

        textTime.text = "\n $savedDay-$savedMonth-$savedYear\n Hour: $savedHour Minute: $savedMinute"
    }

    fun onClick(v: View?) {
        (this@DialogFragment.getActivity() as NewsActivity).onDialogOKPressed()
        dismiss()
    }
}
a_local_nobody
  • 7,947
  • 5
  • 29
  • 51
Londre
  • 1
  • 2
  • I mean it looks fine from what you've posted (which isn't everything so we don't know if you're setting up your click listener properly). You should probably stick a logging line in the click listener, so you can see it's definitely being triggered. Also I don't know if it'll cause an issue (it might) but you've got a preference ``editor`` inside another ``editor`` for some reason - the outer ``apply`` might override the inner one, and it's the inner one that's actually saving data. *"The last one to call apply wins"* – cactustictacs Apr 30 '21 at 18:28
  • @cactustictacs Where would I setup the click listener you're talking about as I don't think I set one up, the only clickListener I have setup is the one within the post 'btn_timePicker.setOnClickListener { saveData()}' I can show more code if needed to help see what could be the issue. That makes sense so I removed the outer apply just so it wont cause any later issues but didn't solve the problem unfortunately but I appreciate the explanation you added. – Londre Apr 30 '21 at 18:43
  • Yeah that's the click listener I mean, stick a ``Log.d("ClickListener", "just got clicked")`` line in there so you can see that it's actually firing, so you know ``sendData`` is being called. If it is, the problem is in ``sendData``, and if it's not then the problem is with how the click listener is being set up. And we can't see how you're setting it up, because you haven't posted your ``onCreate`` or wherever you're doing it, you just said it's "in ActivityMain" somewhere. Also you need to remove the outer ``edit`` too - you want one ``edit -> put -> apply`` thing going on – cactustictacs Apr 30 '21 at 19:10
  • That onClickListener is the one that I mentioned is within onCreate within my post, that's my only listener I have. I ran the app with the log message in and I didn't get any return in the Log saying that it got clicked which I assume means that is the issue, I think I made a small mistake with setting up the Click listener but I am not sure, but that one I have within my post is my only clickListener related to btn_timePicker. Also sorry but I don't understand which edit you are referring to on the outer, is it within saveData() ? – Londre Apr 30 '21 at 19:20
  • You certainly shouldn’t be calling `sharedPreferences.edit()` twice. In your edited code, you are not calling `apply()` on the editor that you actually changed, so the change is not saved. The `apply` function that you are using is the scope function which has nothing to do specifically with SharedPreferences. You can use debugging to see if your click listener is getting triggered. Put a breakpoint in the listener. – Tenfour04 Apr 30 '21 at 20:35
  • You'll have to post your whole activity code for anyone to check what you're doing with the listener, if you put a log statement in it and it doesn't fire when you click the button, the listener isn't set. And I'm saying you should have one ``edit -> putInt etc -> apply`` transaction in ``saveData``. Check here if you're not sure what it looks like: https://developer.android.com/training/data-storage/shared-preferences#WriteSharedPreference – cactustictacs Apr 30 '21 at 21:27
  • I applied the changes you said to make but still no luck, I have updated it with my full activity – Londre Apr 30 '21 at 22:59
  • @cactustictacs do you see anything unusual that could be the issue within the code? If not I might just have to do a database instead since I don't have much time and I really don't know what is the issue with this, I heard SharedPrefs can be buggy sometimes but don't know if its the case for me or not. – Londre May 01 '21 at 13:05
  • @Tenfour04 or would you happen to maybe see an error that I can't within my code? – Londre May 01 '21 at 13:29
  • please don't use android studio if you're not asking about a feature of the IDE, rather just make use of `android` - tags do make a difference – a_local_nobody May 01 '21 at 18:03
  • Oh my bad, sorry. – Londre May 01 '21 at 18:08

1 Answers1

0

In your onCreate when the activity first gets created, you're setting the click listener like this:

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    btn_timePicker.setOnClickListener {
        saveData()
    }

and then a few lines down you call pickDate(), which does this:

private fun pickDate() {
    btn_timePicker.setOnClickListener {
        getDateTimeCalendar()
        DatePickerDialog(this, this, year, month, day).show()
    }
}

You're setting a new click listener on the same button, btn_timePicker, overwriting the first one that calls saveData()


You're also doing this...

private fun saveData() {
    val insertedText = btn_timePicker.text.toString()
    ...
    with(sharedPreferences.edit()) {
        putString(key1, insertedText)

btn_timePicker sure is uh, getting some use here! I'm not even sure what you're doing and if it could even work, but this is Not Good. Here, Tenfour04 has an answer for a simple way of passing data from a Dialog to an Activity, make a function on the Activity you can call and pass in a time or whatever, then you can save it or whatever you want to do:

Start Dialog for result to return value to main activity

cactustictacs
  • 17,935
  • 2
  • 14
  • 25
  • Ohh I didn't even see the onClickListener under pickDate() as I got that code from the tutorial, I must have missed it.. I've updated the post with my current code and also the saveData() code was given to me to use by someone on here that suggested it being a fix. Also the code Tenfour04 had up wasn't in the Kotlin language so I am getting some errors over onDialogOKPressed() and the DialogFragment, i've replaced the activity in relation to mine which you can see within the post as it's my updated code. – Londre May 01 '21 at 17:58
  • Also i've noticed removing the ''btn_timePicker.setOnClickListener '' within pickDate() now just displays a map everytime you go to create a letter which resets the value saved from the user each time. But the actual onClickListener now works which is progress! – Londre May 01 '21 at 18:07
  • ``(activity as NewsActivity).doThing(dataYouWantToSend)`` in the dialog's click listener. Create that function in your activity and do your saving there. Make the button only open the dialog, and nothing else. Honestly I can't give you any more help than that, there's all kinds of stuff going on in there and I don't have time to pick it apart, sorry – cactustictacs May 01 '21 at 18:08
  • Oh, i'm getting an error on activity alone already but i'll do some research, just 1 last thing if you see this, what is supposed to be inputted for 'doThing' as it's not very explanatory. – Londre May 01 '21 at 18:16
  • whatever data you want to send back from the dialog, a time or whatever. You need to write a function in the activity that's showing the dialog, which handles whatever it is you want to get from the dialog. Then you call that function from inside the dialog, passing in the data. It's a way of communicating with the activity - it's not the best but it's the simplest! – cactustictacs May 01 '21 at 18:24
  • Oh is it supposed to be its own function and not a function within saveData() where you said it was messed up at? – Londre May 01 '21 at 18:30