I have an error about switching between fragments

63 views Asked by At

So I have a fragment that contains CameraX. I want to move the photos to the fragment that contains ImageView. When I press the button for photos on the Camera Fragment

binding.ivCamCapture.setOnClickListener { takePhoto() }

There always an error:

FATAL EXCEPTION: main
Process: com.dicoding.geotaggingjbg, PID: 23794
java.lang.IllegalArgumentException: No view found for id 0x7f090154 (com.dicoding.geotaggingjbg:id/save_fragment) for fragment SaveFragment{b82c6bd} (df466273-fc83-4df0-8853-dda8508bc87b id=0x7f090154)
androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:547)
androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:272)
androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1943)
androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1839)
androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1782)
androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:565)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

This is a method for taking pictures:

private fun takePhoto() {
        val imageCapture = imageCapture ?: return
        val photoFile = createCustomTempFile(requireActivity())
        val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()

        imageCapture.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(requireActivity()),
            object : ImageCapture.OnImageSavedCallback {
                override fun onImageSaved(output: ImageCapture.OutputFileResults) {

                    val imageUri = output.savedUri.toString()
                    val bundle = Bundle().apply {
                        putString(SaveFragment.EXTRA_FILE, imageUri)
                    }
                    showFragment(bundle)
                }

                override fun onError(exc: ImageCaptureException) {
                    Toast.makeText(
                        requireActivity(),
                        "Failed to take a picture.",
                        Toast.LENGTH_SHORT
                    ).show()
                    Log.e(TAG, "onError: ${exc.message}")
                }
            }
        )
    }

And this is the method for fragment displacement

fun showFragment(bundle: Bundle) {
        val saveFragment = SaveFragment()
        saveFragment.arguments = bundle

        val fragmentManager = childFragmentManager
        fragmentManager.beginTransaction().apply {
            replace(R.id.save_fragment, saveFragment)
            addToBackStack(null)
            commit()
        }
    }

I have tried changing the id in the .xml and the navigation. But I still get the same error.

<FrameLayout
    android:id="@+id/save_fragment"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ui.save.SaveFragment">
2

There are 2 answers

1
Ravi Bhadodiya On

Check this id/navigation_save proper

2
NNA On

android:id="@+id/save_fragment" is an id inside SaveFragment, it's not the id of container.

If you want to close CameraFragment and show SaveFragment, you should use id_of_container instead. Just like:

fun showFragment(bundle: Bundle) {
    val saveFragment = SaveFragment()
    saveFragment.arguments = bundle

    val fragmentManager = requireActivity().supportFragmentManager
    fragmentManager.beginTransaction().apply {
        replace(R.id.id_of_container, saveFragment)
        addToBackStack(null)
        commit()
    }
}