androidkotlinandroid-fragmentsfragment-oncreateview

OnCreateView is called but fragment is not visible


I used logs to see if onCreateView and onViewCreated are called. Everything seems fine on that side. However, for some reason, it is not showing the layout of the fragment. Nothing is visible except the main_actvity layout. P.S. please don't mind the indentations, it's my first question here so I'm not that familiar with question editing.

Main Activity:

class MainActivity: AppCompatActivity() {
private lateinit var viewBinding: ActivityMainBinding

private var imageCapture: ImageCapture? = null


private lateinit var cameraExecutor: ExecutorService
private lateinit var db: FirebaseFirestore

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    Log.d("TAG", "onCreate: ")

    viewBinding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(viewBinding.root)
    Log.d("TAG", "onCreate: ")


    // Request camera permissions
    if (allPermissionsGranted()) {
        Log.d(TAG, "onCreate: ")

        startCamera()
    } else {
        Log.d(TAG, "onCreate: ")
        ActivityCompat.requestPermissions(
            this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
        )
    }

    // Set up the listeners for take photo and video capture buttons
    viewBinding.imageCaptureButton.setOnClickListener { takePhoto() }

    cameraExecutor = Executors.newSingleThreadExecutor()

    val historyBtn = viewBinding.historyBtn

    historyBtn.setOnClickListener {
        if (savedInstanceState == null) {
            supportFragmentManager.commit {
                Log.d("bla", "onCreate: sdfsdfsd")

                setReorderingAllowed(true)
                add<HistoryFragment>(R.id.root_layout)
            }
        }
    }
}

History Fragment:

class HistoryFragment : Fragment() {

private lateinit var db: FirebaseFirestore

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)


}


companion object{
    fun newInstance(): HistoryFragment{
        return HistoryFragment()
    }
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    db = Firebase.firestore

    val docRef = db.collection("Products")
    Log.d("frTag", "onCreateView: sdasda")

    docRef.get()
        .addOnSuccessListener { documents ->
            for (document in documents){
                val objects = documents.toObjects(ProductModel::class.java)

                val productArrayList: ArrayList<ProductModel> = objects as ArrayList<ProductModel>
               
            }
        }

}
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    Log.d("kalla", "onCreateView: called")
    return inflater.inflate(R.layout.fragment_history, container, false)
}


}

Main Activity xml:

<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">

<fragment
    class="com.sanjarbek.mlkitfunproject.HistoryFragment"
    android:id="@+id/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.sanjarbek.mlkitfunproject.HistoryFragment" />

<androidx.camera.view.PreviewView
    android:id="@+id/viewFinder"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<Button
    android:id="@+id/image_capture_button"
    android:layout_width="110dp"
    android:layout_height="110dp"
    android:layout_marginBottom="50dp"
    android:layout_marginEnd="50dp"
    android:elevation="2dp"
    android:text="take photo"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintEnd_toStartOf="@id/vertical_centerline" />

<Button
    android:id="@+id/video_capture_button"
    android:layout_width="110dp"
    android:layout_height="110dp"
    android:layout_marginBottom="50dp"
    android:layout_marginStart="50dp"
    android:elevation="2dp"
    android:text="start capture"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintStart_toEndOf="@id/vertical_centerline" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/vertical_centerline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent=".50" />

<Button
    android:id="@+id/history_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:text="History"
    android:layout_margin="10dp"/>

 </androidx.constraintlayout.widget.ConstraintLayout>

History Fragment xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HistoryFragment">

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="adfdasdfafa"/>

Solution

  • Hey don't worry about the formatting, it's way better than what a lot of people post! I can see a couple of issues that might be causing this (can't test it right now though).

    First, your HistoryFragment in your main Activity layout is behind a PreviewView that fills the layout:

    <fragment
        class="com.sanjarbek.mlkitfunproject.HistoryFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
    <androidx.camera.view.PreviewView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    

    Because the PreviewView is declared later, it's drawn over the Fragment here (unless you provide an elevation or change its Z-order). I don't know if that view renders transparent until you do something with it or not, but if not it'll obscure your Fragment.


    Your other issue is that you're adding a HistoryFragment as a child of the one that's already in your layout (declared in the XML):

    // activity_main.xml
    <fragment
        class="com.sanjarbek.mlkitfunproject.HistoryFragment"
        android:id="@+id/root_layout"
        ...
    />
    
    // MainActivity
    supportFragmentManager.commit {
        add<HistoryFragment>(R.id.root_layout)
    }
    

    You're embedding a HistoryFragment in your layout - and then, since root_layout is that Fragment's id, you add another instance of your HistoryFragment within it. Run your app and open the Layout Inspector and take a look at the hierarchy.

    Generally you don't embed Fragments in the XML like this, it's less flexible than being able to add and remove them with a FragmentTransaction. And it seems like you want to add that Fragment in code anyway. You should make root_layout some kind of container instead - a FrameLayout is the classic way, but now it's recommended you use a FragmentContainerView instead. Size and position it how you like, and add your Fragments to that.


    I don't know if either of those will fix your Fragment not being visible, but they need doing anyway. Remember the Layout Inspector will help you see what's going on, it can be really useful for layout problems