Search code examples
androidkotlindatelocaledatepickerdialog

Two issues with DatePickerDialog (Android/Kotlin)


I am a newbie in programming and just now I am learning Kotlin for android programming. At the moment, I am working on app todo list, where there is an EditText input with id datePickerEditText. When you click on EditText input, Calendar is displayed. So you can choose date.

I want to find a solution for 2 issues.

  1. At the moment, I do not know how to use russian locale while choosing date. It should use such format: day:month in russian:year.

  2. DatePickerDialog should give the user to choose any date, not only current date.

I found 2 solutions, but in the first, date format and locale are not in russian. But it gives an opportunity to choose any date and sends the chosen date to EditText.

Second solution is good in date formating and using russian locale. But there is a problem. It sends current date to the TextEdit despite of you choose another date.

Here is the code of the first solution:

import android.app.DatePickerDialog
import android.app.Dialog
import android.icu.util.Calendar
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.EditText

class CustomDialog(var activity: MainActivity) : Dialog(activity),  View.OnClickListener {

    var yes: Button? = null
    var no: Button? = null
    private lateinit var inputField: EditText
    private lateinit var inputDescription: EditText
    private lateinit var editTextDate: EditText


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.dialog_template)
        inputField = findViewById(R.id.dialogInput)
        inputDescription = findViewById(R.id.dialogDescription)

        val lp = WindowManager.LayoutParams()
        lp.copyFrom(this.window?.attributes)
        lp.width = WindowManager.LayoutParams.MATCH_PARENT
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT
        lp.gravity = Gravity.CENTER
        this.window?.attributes = lp

        yes = findViewById<Button>(R.id.dialogOkButton)
        no = findViewById<Button>(R.id.dialogCancelButton)
        editTextDate = findViewById(R.id.datePickerEditText)
        yes?.setOnClickListener(this)
        no?.setOnClickListener(this)

        editTextDate.setOnClickListener {

            // on below line we are getting
            // the instance of our calendar.
            val c = Calendar.getInstance()



            // on below line we are getting
            // our day, month and year.
            val year = c.get(Calendar.YEAR)
            val month = c.get(Calendar.MONTH)
            val day = c.get(Calendar.DAY_OF_MONTH)

            // on below line we are creating a
            // variable for date picker dialog.
            val datePickerDialog = DatePickerDialog(
                // on below line we are passing context.
                activity,
                { view, year, monthOfYear, dayOfMonth ->
                    // on below line we are setting
                    // date to our edit text.
                   val dat = (dayOfMonth.toString() + "-" + (monthOfYear + 1) + "-" + year)
                    editTextDate.setText(dat)


                },
                // on below line we are passing year, month
                // and day for the selected date in our date picker.
                year,
                month,
                day
            )

            // at last we are calling show
            // to display our date picker dialog.
            datePickerDialog.show()
        }

    }

    override fun onClick(view: View){
        when (view.id) {
            R.id.dialogOkButton -> {
                val inputResult = inputField.text
                val inputDescription = inputDescription.text
                val inputDate = editTextDate.text
                activity.addItem(inputResult.toString(), inputDescription.toString(), inputDate.toString())
                dismiss()
            }
            R.id.dialogCancelButton -> {
                dismiss()
            }
            else -> {
            }
        }
    }

}

Here is the code of the second solution:

import android.app.DatePickerDialog
import android.app.Dialog
import android.icu.util.Calendar
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.EditText

class CustomDialog(var activity: MainActivity) : Dialog(activity),  View.OnClickListener {

    var yes: Button? = null
    var no: Button? = null
    private lateinit var inputField: EditText
    private lateinit var inputDescription: EditText
    private lateinit var editTextDate: EditText


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.dialog_template)
        inputField = findViewById(R.id.dialogInput)
        inputDescription = findViewById(R.id.dialogDescription)

        val lp = WindowManager.LayoutParams()
        lp.copyFrom(this.window?.attributes)
        lp.width = WindowManager.LayoutParams.MATCH_PARENT
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT
        lp.gravity = Gravity.CENTER
        this.window?.attributes = lp

        yes = findViewById<Button>(R.id.dialogOkButton)
        no = findViewById<Button>(R.id.dialogCancelButton)
        editTextDate = findViewById(R.id.datePickerEditText)
        yes?.setOnClickListener(this)
        no?.setOnClickListener(this)

        editTextDate.setOnClickListener {

            // on below line we are getting
            // the instance of our calendar.
            val c = Calendar.getInstance()



            // on below line we are getting
            // our day, month and year.
            val year = c.get(Calendar.YEAR)
            val month = c.get(Calendar.MONTH)
            val day = c.get(Calendar.DAY_OF_MONTH)

            // on below line we are creating a
            // variable for date picker dialog.
            val datePickerDialog = DatePickerDialog(
                // on below line we are passing context.
                activity,
                { view, year, monthOfYear, dayOfMonth ->


                    val simpleDateFormat = SimpleDateFormat("EEEE, dd-MMM-yyyy hh:mm:ss a", Locale("ru"))
                   val dateTime = simpleDateFormat.format(c.time)
                   editTextDate.setText(dateTime)


                },
                // on below line we are passing year, month
                // and day for the selected date in our date picker.
                year,
                month,
                day
            )
           // datePickerDialog.datePicker.locale = Locale("ru")

            // at last we are calling show
            // to display our date picker dialog.
            datePickerDialog.show()
        }

    }

    override fun onClick(view: View){
        when (view.id) {
            R.id.dialogOkButton -> {
                val inputResult = inputField.text
                val inputDescription = inputDescription.text
                val inputDate = editTextDate.text
                activity.addItem(inputResult.toString(), inputDescription.toString(), inputDate.toString())
                dismiss()
            }
            R.id.dialogCancelButton -> {
                dismiss()
            }
            else -> {
            }
        }
    }

}

How to set the code in order DatePickerDialog should use russian locale with date format day:month in russian:year? If to choose not current date in DatePickerDialog, it should be sent to EditText input as is.

Thank you!

How to set the code in order DatePickerDialog should use russian locale with date format day:month in russian:year? If to choose not current date in DatePickerDialog, it should be sent to EditText input as is.

Thank you!


Solution

  • Looking at your second solution here:

    { view, year, monthOfYear, dayOfMonth ->
        val simpleDateFormat = SimpleDateFormat("EEEE, dd-MMM-yyyy hh:mm:ss a", Locale("ru"))
        val dateTime = simpleDateFormat.format(c.time)
        editTextDate.setText(dateTime)
    },
    

    Notice you are formatting the time from c, which is a Calendar you set up with the current date. You need to format by using the date that is being passed to this lambda, like this:

    { view, year, monthOfYear, dayOfMonth ->
        val simpleDateFormat = SimpleDateFormat("EEEE, dd-MMM-yyyy hh:mm:ss a", Locale("ru"))
        val selectedDateCalendar = Calendar.getInstance().apply {
                set(
                    year = year,
                    month = monthOfYear,
                    date = dayOfMonth
                )
            }
        val dateTime = simpleDateFormat.format(selectedDateCalendar.time)
        editTextDate.setText(dateTime)
    },