40

I have a fragment added using

transaction.add(R.id.content, fragment, null);

and I need to start new fragment from this one. But to do this I need to know first fragment's container view id (R.id.content in my case). How can I get this?

I can just use this id directly but I suppose fragment shouldn't know such kind of details about parent activity. For example it will be impossible to use this fragment in another activity in this case.

May be "starting" fragment from another one is a bad practice and all fragment handling logic should be handled by activity itself? But creating nice sequences of fragments starting each other seems quite useful (for example detalView->moreDetailView->evenMoreDetailView).

Renato Lochetti
  • 4,558
  • 3
  • 32
  • 49
Dmitry Ryadnenko
  • 22,222
  • 4
  • 42
  • 56

6 Answers6

85

You can access the container's id by calling

((ViewGroup)getView().getParent()).getId();
Behlül
  • 3,412
  • 2
  • 29
  • 46
  • 3
    it give me null any idea, I have main screen that contain layout that I use as parent for the fragements when try to say LinearLayout x =(LinearLayout) ((ViewGroup)getView().getParent()) ; in the Fragment class be called but it always null – AMH Jul 16 '12 at 02:02
14

I don't know if I exactly understand your question, but you get the Container in onCreateView. I suppose you could stash it in a local variable.

public View onCreateView(LayoutInflater inflater, 
  ViewGroup container,
  Bundle savedInstanceState) {
  mContainer = container;
  ...
}
peterh
  • 11,875
  • 18
  • 85
  • 108
Sparky
  • 8,437
  • 1
  • 29
  • 41
  • You understand it right. I can do it this way but it seems more like a hack to me. Container here is passed for fragment to be able to inflate it's view and I doubt it is supposed to be stored for a future use. Do some kind of more native way of getting container view id exist? – Dmitry Ryadnenko Aug 03 '11 at 12:25
  • 3
    I don't see what's wrong with this method. If you don't want to store the view, just store the id. – Tim Malseed Oct 27 '13 at 09:38
9

I think there's a more standard way of accessing the view rather than using

((ViewGroup) getView().getParent()).getId()

I will assume that you're working with a MainActivity that presents a list fragment, which can then present another list fragment upon clicking an item, and so on. I'm assuming that you've chosen to replace the main view of MainActivity with the contents of the list fragments you present.

Because each list fragment is being hosted in the MainActivity, you can always access the view of the MainActivity.

// Inside of onListItemClick...
FragmentManager fm = getFragmentManager();
Fragment fragment = new MyOtherListFragment();

FrameLayout contentView = (FrameLayout) getActivity().findViewById(R.id.content_view);

fm.beginTransaction()
        .replace(contentView.getId(), fragment)
        .addToBackStack(null)
        .commit();

The above example assumes you have an XML layout resource that you set in the MainActivity, call the XML resource R.layout.activity_main, where there is a FrameLayout with the id R.id.content_view. This is the approach I took. The example I present here is a simpler version from the one that I actually wrote in my app.

Incidentally, my version of IntelliJ (version 1.0.1) warns me that

((ViewGroup) getView().getParent)

may throw a NullPointerException.

  • 2
    Well, few weeks after this question I have understood that Fragments design is flawed beyond point of usability and never used Fragments again. – Dmitry Ryadnenko Apr 24 '15 at 16:24
5

Assuming you have Fragment instance mCurrentFragment in Activity class. You can get Fragment's container View via

int id = mCurrentFragment.getView().getParent().getId();
ViewGroup vg = (ViewGroup) findViewById(id); // Fragment's container View
macio.Jun
  • 9,647
  • 1
  • 45
  • 41
  • 2
    (If I understand correctly what you are doing) The object you got the id from **is** the object you are looking for. Those two lines can be replaced by the shorter: `ViewGroup vg = (ViewGroup) mCurrentFragment.getView().getParent();` Any situation where this would not be equivalent to what you did? – ToolmakerSteve Sep 20 '16 at 10:19
  • 1
    Yep @ToolmakerSteve, they are always equivalent. Thanks for spotting that for me. – macio.Jun Sep 20 '16 at 12:01
0

The Kotlin version

val container = view?.parent as? ViewGroup ?: return

It can be added to a "hand-dandy" extension:

fun Fragment.container(): ViewGroup? {
    return view?.parent as? ViewGroup
}

Then get the id

container.id
container().id
cutiko
  • 9,887
  • 3
  • 45
  • 59
0

Add the new class

    import androidx.navigation.NavController
    
    class Navigator {
        companion object {
            var fragment1_id: Int = 0
            var fragment2_id: Int = 0
            var navController : NavController? = null
            fun goFragment1()
            {
                navController?.navigate(fragment1_id)
            }
            fun goFragment2()
            {
                navController?.navigate(fragment2_id)
            }
        }
    }

In main activity:

        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View {
    ...
            val navController = findNavController(R.id.nav_host_fragment_content_main)
    
            Navigator.navController = navController
            Navigator.fragment1_id = R.id.nav_fragment1
            Navigator.fragment2_id = R.id.nav_fragment2
    <navigation xmlns:android...    
        <fragment
            android:id="@+id/nav_fragment1"
        ... 
        <fragment
            android:id="@+id/nav_fragment2"
        

Click Listener in any fragment:

    fun onClickButton(view: View)
    {
        Navigator.goFragment1()
    }
RusArtM
  • 1,116
  • 3
  • 15
  • 22
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 22 '23 at 03:25