Home > Software design >  Dialog from extended class opens, but does not close using dialog.dismiss() Kotlin?
Dialog from extended class opens, but does not close using dialog.dismiss() Kotlin?

Time:12-06

I had seen other questions like this, but they don't apply to this specific situation.

I have RegisterActivity extend from BaseFunctions, where the dialog is created, displayed, and closed.

I can display the dialog by using the function controlProgressDialog(true), but I cannot close it by using controlProgressDialog(false).

Here is the code:

RegisterActivity.kt:

package com.toxicflame427.flowr.activities

import android.app.Dialog
import android.os.Bundle
import android.text.TextUtils
import com.google.firebase.auth.FirebaseAuth
import com.toxicflame427.flowr.R
import com.toxicflame427.flowr.databinding.ActivityRegisterBinding

class RegisterActivity : BaseFunctions(){
private lateinit var binding : ActivityRegisterBinding

override fun onCreate(savedInstanceState: Bundle?) {
    binding = ActivityRegisterBinding.inflate(layoutInflater)

    super.onCreate(savedInstanceState)
    setContentView(binding.root)

    removeToolStatusBar()
    applyEvents()
}

private fun applyEvents(){
    binding.registerButton.setOnClickListener{
        registerUser()
    }
}

private fun validateRegisterCredentials() : Boolean{
    return when{
        TextUtils.isEmpty(binding.emailRegisterInput.text.toString().trim{it <= ' '}) -> {
            controlSnackBar("Please enter your email address", true)
            false
        }
        TextUtils.isEmpty(binding.passwordRegisterInput.text.toString().trim{it <= ' '}) -> {
            controlSnackBar("Please enter your password", true)
            false
        }
        TextUtils.isEmpty(binding.passwordConfirmRegisterInput.text.toString().trim{it <= ' '}) -> {
            controlSnackBar("Please confirm your password", true)
            false
        }
        binding.passwordRegisterInput.text.toString().trim{it <= ' '} != binding.passwordConfirmRegisterInput.text.toString().trim{it <= ' '} -> {
            controlSnackBar("Password and confirmation password do not match", true)
            false
        }
        else -> {
            true
        }
    }
}

private fun registerUser(){
    if(validateRegisterCredentials()){
        //Trying to display the dialog, it works
        controlProgressDialog(true)

        val email = binding.emailRegisterInput.text.toString().trim{ it <= ' ' }
        val password = binding.passwordRegisterInput.text.toString().trim { it <= ' ' }

        FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener{ task ->
                //Trying to close the dialog, does not work
                controlProgressDialog(false)

                if (task.isSuccessful) {
                    //Just in case, in case i forget how to get the user
                    //val firebaseUser = task.result!!.user!!

                    finish()
                } else {
                    controlSnackBar(task.exception!!.message.toString(), true)
                }
            }
    }
}

And BaseFunctions.kt:

 package com.toxicflame427.flowr.activities

import android.app.Dialog
import android.content.Context
import android.os.Build
import android.view.WindowInsets
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.google.android.material.snackbar.Snackbar
import com.toxicflame427.flowr.R

open class BaseFunctions : AppCompatActivity() {
fun removeToolStatusBar(){
    //Check the API level of the device, lower api levels require a different
    // method of hiding the status bar
    @Suppress("DEPRECATION")
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
        //New way of removing status bar
        window.insetsController?.hide(WindowInsets.Type.statusBars())
    } else {
        //Old way must still be used if targeting older devices
        window.setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
        )
     }
 }

fun controlSnackBar(message : String, isError : Boolean){
    val snackBar : Snackbar = Snackbar.make(findViewById(android.R.id.content), message, Snackbar.LENGTH_LONG)
    val snackBarView = snackBar.view

    if(isError){
        snackBarView.setBackgroundColor(ContextCompat.getColor(this, android.R.color.holo_red_light))
        snackBar.show()
    } else {
        snackBarView.setBackgroundColor(ContextCompat.getColor(this, android.R.color.holo_green_dark))
        snackBar.show()
    }
}

//This is the function attempted to be used
fun controlProgressDialog(showDialog : Boolean){
    val progressDialog = Dialog(this)
    progressDialog.setCancelable(false)
    progressDialog.setCanceledOnTouchOutside(false)
    progressDialog.setContentView(R.layout.progress_dialog)

    if(showDialog){
        progressDialog.show()
    } else {
        progressDialog.dismiss()
    }
}

}

I marked comments in the code what function is being used and where I am trying it.

I had tried using different contexts. applicationContext causes the whole app to crash, base context does the same thing, 'this' works but does not let me close the dialog, this@RegisterActivity works but also wont let me close the dialog, I had tried changing the condition under the controlProgressDialog() and that did not work either.

Users can register to the app by entering their credentials to be used in Firebase Authentication. I want the dialog to display while the users data is being authenticated and it to close when the users data is done being authenticated. So far, opening the dialog works, but closing it does not. The app does not crash or anything, just just the dialog does not want to dismiss.

The only thing the dialog displays is a spinning wheel and the text "Please wait..."

Any help will be greatly appreciated!

CodePudding user response:

The problem is, when you call controlProgressDialog(false),
it creates a new instance of Dialog which is why the older dialog is not dismissed.

There are 2 solution to this:

  1. First is to return an instance of Dialog when calling calling controlProgressDialog.
    For example:
fun getProgressDialog(): Dialog {
    val progressDialog = Dialog(this)
    progressDialog.setCancelable(false)
    progressDialog.setCanceledOnTouchOutside(false)
    progressDialog.setContentView(R.layout.progress_dialog)
    return progressDialog
}


// Show the dialog.
val dialog = getProgressDialog()
dialog.show()

// dismiss the dialog.
if(dialog.isShowing) dialog.dismiss()

  1. Second is to hold a global reference to a Dialog variable in the Activity & then handle show / dismiss.
  • Related