[FIXED] Countdowntimer in Fragment starting from DialogFragment crashing

Issue

I would like to create countdowntimer, its ok. Normally its working. But i have one Dragment, this fragment opens Dialogfragment, if i click "Yes" button in Dialogfragment, the dialogfragment should be closed and countdowntimer should start in fragment. But it crashing. I don’t know why. If i start the countdowntimer directly from fragment, it works, but if i start from Dialogfragment, it crash.

Log:
2022-09-08 19:30:43.470 20162-20162/com.thedgames.rickclicker2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.thedgames.rickclicker2, PID: 20162
java.lang.NullPointerException
at com.thedgames.rickclicker2.ui.bank.BankFragment.getBinding(BankFragment.kt:18)
at com.thedgames.rickclicker2.ui.bank.BankFragment.access$getBinding(BankFragment.kt:15)
at com.thedgames.rickclicker2.ui.bank.BankFragment$timerFun$1.onTick(BankFragment.kt:94)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:130)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

Can somebody help me?

Here is my code:

BankFragment:

package com.thedgames.rickclicker2.ui.bank

import android.os.Bundle
import android.os.CountDownTimer
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.thedgames.rickclicker2.data.Variables
import com.thedgames.rickclicker2.databinding.FragmentBankBinding
import com.thedgames.rickclicker2.dialogs.ExchangeDialog
import com.thedgames.rickclicker2.dialogs.InvestDialog


class BankFragment : Fragment() {

private var _binding: FragmentBankBinding? = null
private val binding get() = _binding!!

companion object {
    val KEY_PERCENT = "KEY_PERCENT"
    val KEY_ENOUGH = "KEY_ENOUGH"
    var enough: Boolean = false
}

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?,
): View {

    _binding = FragmentBankBinding.inflate(inflater, container, false)
    val root: View = binding.root

    binding.textExchangeRate.text = "Rate: ${Variables.userObject.bankExchange}:1"
    binding.textInvestRate.text = "${Variables.userObject.bankInvest}% / Minute"

    binding.btn50Exchange.setOnClickListener {
        openExchangeDialog(50)
    }

    binding.btn100Exchange.setOnClickListener {
        openExchangeDialog(100)
    }

    binding.btn50Invest.setOnClickListener {
        openInvestDialog(50)
    }

    binding.btn100Invest.setOnClickListener {
        openInvestDialog(100)
    }

    return root
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}


fun openInvestDialog(percent: Int) {
    val invest = InvestDialog()
    invest.isCancelable = false
    val bundle = Bundle()
    bundle.putInt(KEY_PERCENT, percent)
    if (Variables.userObject.coins > 999.0){
        enough = true
    }
    bundle.putBoolean(KEY_ENOUGH, enough)
    invest.arguments = bundle
    invest.show(requireActivity().supportFragmentManager, "InvestDialog")
}

fun openExchangeDialog(percent: Int) {
    val exchangeDialog = ExchangeDialog()
    exchangeDialog.isCancelable = false
    val bundle = Bundle()
    bundle.putInt(KEY_PERCENT, percent)
    if (Variables.userObject.coins > 999.0){
        enough = true
    }
    bundle.putBoolean(KEY_ENOUGH, enough)
    exchangeDialog.arguments = bundle
    exchangeDialog.show(requireActivity().supportFragmentManager, "ExchangeDialog")
}

fun timerFun() {
    object: CountDownTimer(20000, 1000) {
        override fun onTick(remaining: Long) {
            binding.textInvestRate.text = (remaining/1000).toString()
        }

        override fun onFinish() {
            binding.textInvestRate.text = "Claim"
        }
    }.start()
}
}

InvestDialog:

package com.thedgames.rickclicker2.dialogs

import android.app.Dialog
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.thedgames.rickclicker2.MainActivity
import com.thedgames.rickclicker2.R
import com.thedgames.rickclicker2.data.Variables
import com.thedgames.rickclicker2.databinding.LayoutDialoginvestBinding
import com.thedgames.rickclicker2.databinding.LayoutDialoginvestnotenoughBinding

import com.thedgames.rickclicker2.ui.bank.BankFragment
import com.thedgames.rickclicker2.utils.DataManager


class InvestDialog : DialogFragment() {

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {

    val percent = arguments?.getInt(BankFragment.KEY_PERCENT)
    var enough = arguments?.getBoolean(BankFragment.KEY_ENOUGH)

    val mainActivity = activity as MainActivity

    val alertDialogBuilder = AlertDialog.Builder(requireActivity(), R.style.DialogTheme)
    val view = LayoutDialoginvestBinding.inflate(requireActivity().layoutInflater)
    val view2 = LayoutDialoginvestnotenoughBinding.inflate(requireActivity().layoutInflater)

    if (enough == true){
        alertDialogBuilder.setView(view.root)
    } else {
        alertDialogBuilder.setView(view2.root)
    }


    view.btnYes.setOnClickListener {

        Variables.userObject.coins -= Variables.userObject.coins * percent!! / 100

        mainActivity.updateCoin()

        DataManager().saveData(requireContext())

        BankFragment.enough = false

        BankFragment().timerFun()

        this.dismiss()
    }

    view.btnNo.setOnClickListener {
        this.dismiss()
    }

    view2.btnInvestNotEnoughOk.setOnClickListener {
        this.dismiss()
    }

    return alertDialogBuilder.create()
}
}

Solution

Best way is to using callback interface or higher order function.
or
if you want to do it as above try below code

InvestDialog dialogFragment = new InvestDialog();
dialogFragment.show(getChildFragmentManager());

In a DialogFragment:

((BankFragment) getParentFragment()). timerFun();

Answered By – Ashutosh Ojha

Answer Checked By – Mary Flores (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published