0

I'm building an application that is going to support multiple device sizes as mentioned here.

To handle the views inside the Fragment one might either do the lookup with findViewById in the Activity's onCreate() or in the Fragment's onViewCreated().

They would both work because: if you do it from the Activity you will be handling the Fragment parent's and your View will still be inside it, if you do it from the Fragment it would have the normal findViewById behavior.

So...

  • What is the best place to do the View lookups?
  • Which one is faster?
  • Which one is more efficient?

They both have their advantages:

If you do them in the Activity:

  • You can control user interactions (like click listeners) right in the hosting Activity.
  • You don't need to implement interface callbacks from the Activity to the Fragment.

If you do them in the Fragment:

  • Views are instantiated right in the Context they are used.
  • Fragments can be reused in the same layout.

There is this question by the way. In which they debate about the use of getView or getActivity to call findViewById in the Fragment.

The accepted answer says:

Rather than using getActivity().findViewById(), you'll want getView().findViewById(). The reason for this is that if you use the activity for the view lookups, then you'll get into trouble when multiple fragments with the same view IDs are attached to it

But what if you will never reuse the Fragment in the same layout, would that be a good case to do the lookup in the Activity?


Example layouts:

main_activity.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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/f_main"
        class=".fragments.MainFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:layout="@layout/fragment_main" />

</FrameLayout>

fragment_main.xml

<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=".fragments.MainFragment">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/a_main_recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

You can access the RecyclerView with the id a_main_recycler either from the Activity or the Fragment.

Community
  • 1
  • 1
Evin1_
  • 12,292
  • 9
  • 45
  • 47
  • `To handle the views inside the Fragment one might either do the lookup with findViewById in the Activity's onCreate() or in the Fragment's onViewCreated().` **Wrong!** to find views inside fragment you should do it inside fragment! – Muhammad Babar Feb 12 '16 at 10:33

4 Answers4

6

Supporting multiple device sizes has nothing to do with fragments. They may be a good idea for other reasons, but that's besides the point. But an Activity should never know anything about what's inside of a fragment. If it does, you've totally missed the point of Fragments and either shouldn't have them at all or should refactor your code.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
1

findViewById involves traversing the view hierarchy tree. So it is best to start as close to the node you are looking for as possible. When you do findViewById on an activity, it delegates the call to its window which in turn delegates to its decorView which is the highest view in the hierarchy. So it is faster if you do findViewById from the fragment view rather than the activity.

greenrobo
  • 781
  • 1
  • 6
  • 9
1

TL;DR: Read Gabe's answer.

That means having multiple Fragments inside Activities.

Fragments are a technique for handling multiple screen sizes. They are not a requirement for handling multiple screen sizes.

What is the best place to do the View lookups?

If the view is part of a fragment (e.g., the fragment inflated the layout that contains the view), the fragment does the findViewById() call, and the fragment manages that view (e.g., registers event listeners).

If the view lies outside of any fragment (e.g., a ViewPager that is directly part of the activity itself), then the activity does the findViewById() call, and the activity manages that view.

Which one is faster? Which one is more efficient?

They should be roughly equivalent.

If you do them in the Activity... You can control user interactions (like click listeners) right in the hosting Activity.

The point behind using fragments for multiple screen sizes is because you want to use fragments conditionally. For example, in Google's classic master/detail UI setup, the activity either shows one fragment (the master) or two fragments (the master and the detail). Some other activity is responsible for the showing the detail. Hence, the code for managing the detail needs to be in the detail fragment; otherwise, you have code duplication between two activities.

If your UI would always show the same fragments all of the time, don't bother with fragments. Fragments are a technique. They are not a religion.

But what if you will never reuse the Fragment in the same layout, would that be a good case to do the lookup in the Activity?

No.

You can access the RecyclerView with the id a_main_recycler either from the Activity or the Fragment.

Only if the fragment is there. In this case, you are using a static fragment, so it will always be there. Not all of the fragments will be.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
0

Absolutely in Fragment, if views are related to fragment, better use instantiate those in Fragment. Thats the main purpose of Fragment to fragment views/screens/layouts.

Fragments have there on lifecycle, hence views are created and destroyed with the Fragment.

Instantiate in Activity if same view are gonna be on screen irrespective of which fragment you are showing there.

In lay man terms > Consider Activity as Headquarter of Starbucks, and fragments as different outlets of Starbucks, and your question is where should you sell your coffee!!

Edit :- Read CommonsWare's answer for detail. :)

Community
  • 1
  • 1
AAnkit
  • 27,299
  • 12
  • 60
  • 71