Search code examples
android-studiokotlinandroid-fragmentsappcompatactivity

Struggling to transition code from AppcompatActivity to Fragment. Unable to use setSupportActionBar(toolbar)


I'm trying to transition from using AppcomatActivity to Fragment, because I'm updating my app but I've run into a problem. I get a "Unresolved reference: supportFragmentManager" and "Unresolved reference: setSupportActionBar"(That's all the Logcat shows me) when I try to run my app. Now I chose to switch to using fragments, because I also want to change the apps UI, usage is quicker than the previous version. Anyway here's my code:

Recorder Fragment

    package com.khumomashapa.notes.fragments

import android.os.Build
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toolbar
import androidx.annotation.RequiresApi
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import androidx.viewpager.widget.ViewPager
import com.astuetz.PagerSlidingTabStrip
import com.khumomashapa.notes.R
import kotlinx.android.synthetic.main.toolbar3.*


class RecorderFragment : Fragment() {

    private var tabs: PagerSlidingTabStrip? = null
    private var pager: ViewPager? = null

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activity?.title = "Recorder";

        pager = pager?.findViewById<View>(R.id.pager) as ViewPager
        pager!!.adapter = MyAdapter(supportFragmentManager)
        tabs = tabs?.findViewById<View>(R.id.tabs) as PagerSlidingTabStrip
        tabs!!.setViewPager(pager)
        val toolbar = toolbar?.findViewById<View>(R.id.toolbar) as Toolbar
        toolbar.popupTheme = R.style.ThemeOverlay_AppCompat_Light
        setSupportActionBar(toolbar)




    }


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



        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_recorder, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

    }

    inner class MyAdapter(fm: FragmentManager?) : FragmentPagerAdapter(
        fm!!
    ) {
        private val titles = arrayOf(
            getString(R.string.tab_title_record),
            getString(R.string.tab_title_saved_recordings)
        )

        override fun getItem(position: Int): Fragment {
            when (position) {
                0 -> {
                    return RecordFragment.newInstance(position)
                }
                1 -> {
                    return FileViewerFragment.newInstance(position)
                }
            }
            return null!!
        }

        override fun getCount(): Int {
            return titles.size
        }

        override fun getPageTitle(position: Int): CharSequence? {
            return titles[position]

        }
    }

    companion object {
        private val LOG_TAG = RecorderFragment::class.java.simpleName
    }
}

The purpose of this class is to show a view pager that can switch between to other fragments I've already created. I was able to fix the other errors relating to this like the "Unresolved reference for findViewById" and the "MyAdapter class".


Solution

  • For a Fragment, there are actually two relevant fragment managers. Deciding which one to use depends on your use case.

    The Child Fragment Manager

    A fragment has a child fragment manager which is responsible for managing its child/nested fragments. You can obtain this with:

    Fragment.getChildFragmentManager()
    

    The Parent's Fragment Manager

    A fragment also holds reference to it's parent's fragment manager. If the fragment is a direct child of an activity then his represents the activities fragment manager. Otherwise if the fragment is a child of another fragment, it represents the child fragment manager of the parent fragment. This can be obtained with:

    Fragment.getParentFragmentManager()
    

    Note that although Fragment has the method Fragment.getFragmentManager(), this is deprecated in favour of Fragment.getParentFragmentManager() so it shouldn't be used.

    You can also technically get the activities fragment manager regardless by obtaining a reference to the fragment's activity with Fragment.getAcitivity() and then calling Activity.getSupportFragmentManager(). But generally the parent fragment manager is more useful and clear.