1

I have a dialog fragment that displays an image whose bytecode is passed to the constructor.

When the dialog is appeared and I am in dark mode and try to change the mode to light one and I come back to my screen, the screen appears all white and I get the error below :

 Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment *.*.*.PictureLoaderDialogFragment: could not find Fragment constructor 

I instantiate my fragment dialog as below:

class PictureLoaderDialogFragment( private var bitmapByteArray: ByteArray? ) : DialogFragment(){ companion object { @JvmStatic fun newInstance( bitmapByteArray: ByteArray? = null ) = PictureLoaderDialogFragment(bitmapByteArray) } } 

Any idea how it should be fixed ?

2 Answers 2

1
+25

This error is caused by passing an argument to your fragment's constructor.

This has to do with the life cycle of fragments and their interaction with the activity. Fragments in Android are designed to be reusable and can be created and destroyed at different points in time depending on the activity's lifecycle. When creating fragments, the Android system uses an empty constructor with no arguments to create a new instance of the fragment after the device configuration changes (in this case, the device theme changes).

In order to solve this problem, there are 3 solutions:

  1. Save arguments in a Bundle
  2. Use FragmentFactory
  3. Use Dependency Injection (DI)

Since you used the newInstance method in your code, the following example shows how to use it, following the first way and saving arguments in a Bundle:

class PictureLoaderDialogFragment : DialogFragment() { //... companion object { fun newInstance(bitmapByteArray: ByteArray? = null): PictureLoaderDialogFragment { val fragment = PictureLoaderDialogFragment() val args = Bundle() args.putByteArray("bitmap", bitmapByteArray) fragment.arguments = args return fragment } } } 

You can access the passed arguments inside the PictureLoaderDialogFragment:

val bitmapByteArray = arguments?.getByteArray("bitmap") bitmapByteArray?.let { val image = BitmapFactory.decodeByteArray(it, 0, it.size) imageView.setImageBitmap(image) } 

You can show your DialogFragment:

PictureLoaderDialogFragment.newInstance(bitmapByteArray).show(manager, tag) 

This article explains how you can use FragmentFactory by following the second solution way

The third way to solvehere, you can learn how to use dependency injection using Hilt

Sign up to request clarification or add additional context in comments.

Comments

1

The error message suggests that there is an issue with the constructor of your PictureLoaderDialogFragment. The newInstance method you've implemented is correct for passing arguments to a DialogFragment. However, the issue might lie in the constructor itself.

To fix the problem, make sure that your PictureLoaderDialogFragment class has a constructor that takes no arguments. The code can be like this:

class PictureLoaderDialogFragment : DialogFragment() { private var bitmapByteArray: ByteArray? = null companion object { @JvmStatic fun newInstance(bitmapByteArray: ByteArray? = null): PictureLoaderDialogFragment { val fragment = PictureLoaderDialogFragment() fragment.bitmapByteArray = bitmapByteArray return fragment } } // Rest of your fragment implementation... } 

I just have removed the constructor parameter from the PictureLoaderDialogFragment class and instead assign the bitmapByteArray value through a separate setter method. The newInstance factory method is responsible for creating a new instance of the fragment and setting the argument value appropriately.

Make sure to update the rest of your fragment implementation to access the bitmapByteArray variable correctly.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.