findViewById in Fragment

720,071

Solution 1

Use getView() or the View parameter from implementing the onViewCreated method. It returns the root view for the fragment (the one returned by onCreateView() method). With this you can call findViewById().

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    ImageView imageView = (ImageView) getView().findViewById(R.id.foo);
    // or  (ImageView) view.findViewById(R.id.foo); 

As getView() works only after onCreateView(), you can't use it inside onCreate() or onCreateView() methods of the fragment .

Solution 2

You need to inflate the Fragment's view and call findViewById() on the View it returns.

public View onCreateView(LayoutInflater inflater, 
                         ViewGroup container, 
                         Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.testclassfragment, container, false);
     ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
     return view;
}

Solution 3

Inside Fragment class you will get onViewCreated() override method where you should always initialize your views as in this method you get view object using which you can find your views like :

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    view.findViewById(R.id.yourId).setOnClickListener(this);

    // or
    getActivity().findViewById(R.id.yourId).setOnClickListener(this);
}

Always remember in case of Fragment that onViewCreated() method will not called automatically if you are returning null or super.onCreateView() from onCreateView() method. It will be called by default in case of ListFragment as ListFragment return FrameLayout by default.

Note: you can get the fragment view anywhere in the class by using getView() once onCreateView() has been executed successfully. i.e.

getView().findViewById("your view id");

Solution 4

I realise this is an old question, but the prevailing answer leaves something to be desired.

The question is not clear what is required of imageView - are we passing it back as the view, or merely saving a reference for later?

Either way, if the ImageView is coming from the inflated layout, the correct way to do this would be:

public class TestClass extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.testclassfragment, container, false);
        ImageView imageView = (ImageView)v.findViewById(R.id.my_image);
        return v;
    }
}

Solution 5

Get first the fragment view and then get from this view your ImageView.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.testclassfragment, container, false);
    ImageView imageView = (ImageView) view.findViewById(R.id.my_image);
    return view;
}
Share:
720,071
simplified.
Author by

simplified.

Updated on January 29, 2022

Comments

  • simplified.
    simplified. over 2 years

    I am trying to create an ImageView in a Fragment which will refer to the ImageView element which I have created in the XML for the Fragment. However, the findViewById method only works if I extend an Activity class. Is there anyway of which I can use it in Fragment as well?

    public class TestClass extends Fragment {
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            ImageView imageView = (ImageView)findViewById(R.id.my_image);
            return inflater.inflate(R.layout.testclassfragment, container, false);
        }
    }
    

    The findViewById method has an error on it which states that the method is undefined.

    • Shomu
      Shomu over 5 years
      Use ButterKnife viewbinding library for android. Also demonstrate how it’s work, how to integrate and use in your android app development to make your development faster.
    • David3103
      David3103 about 5 years
      'Some' time has passed but you still haven't accepted an answer. Can you select the answer that helped you most so this can be marked as answered?
    • mochadwi
      mochadwi over 4 years
      It is encourages to use Data Binding orang View Binding instead manual findViewById
  • Tsunaze
    Tsunaze almost 13 years
    So, does onCreate method is useful in a Fragment ?
  • xevincent
    xevincent almost 13 years
    onCreateView creates and returns the view hierarchy associated with the fragment.onCreate is called to do initial creation of the fragment. Indeed, it depends on what you write in these methods.
  • Tsunaze
    Tsunaze almost 13 years
    Okay, but how can i declare variable in the onCreate ? Because the View is inside the onCreateView method .
  • Raunak
    Raunak over 12 years
    When you do V.findViewById(R.id.someid),surely that will only work for all the widgets that are in the inflated view. What if the imageView he is trying to inflate is outside the inflated view?
  • LeffelMania
    LeffelMania over 12 years
    Then the class that "owns" and inflated the imageView needs to provide public access to it. That is very bad practice though. Fragments should only have access to the UI elements present in their layout.
  • Dmitry Zaytsev
    Dmitry Zaytsev over 12 years
    Note: it's works only after onCreateView(). So, you can't use this in onCreate()
  • StuStirling
    StuStirling almost 12 years
    @Tsunaze did you ever find out how to do this from the onCreate method?
  • Nico AD
    Nico AD almost 12 years
    so what is the function I can override to implement this if onCreate is not the right place ?
  • MattJenko
    MattJenko about 11 years
    This doesn't help if the ImageView is coming from the inflated layout - see my answer for details. Otherwise, onCreateView is the right place to do this @N-AccessDev
  • whyoz
    whyoz about 11 years
    How then would you update imageView from ListFragment? Would this require FragmentManager? In other words, how can you update the imageView in a detail fragment from a separate class's onListItemClick?
  • advantej
    advantej almost 11 years
    The best place to do this the onViewCreated method
  • Steve M
    Steve M over 10 years
    the view is not the activity
  • MattJenko
    MattJenko over 10 years
    You would either save a reference to the imageView somewhere handy, or fragment.getView().findViewById(R.id.my_image) when you need it. In a ListFragment, assuming the image is in a list item, you would generally create a reference holder with the setTag/getTag methods of the list view item in your Adapter's getView method - there are many examples of how to do this.
  • Jon
    Jon over 10 years
    you can't use getActivity and findViewById there in onCreate() or onCreateView either because they both come before onActivityCreated() which is when you are guaranteed that the activity view heirarchy has been created.
  • fransre
    fransre about 10 years
    Note that findViewById has to be called on the view that is inflated, not on getView()
  • Monstieur
    Monstieur almost 10 years
    The documentation states that onActivityCreated() is the recommended place to find and store references to your views. You must clean up these stored references by setting them back to null in onDestroyView() or you will leak the Activity.
  • MrAsterisco
    MrAsterisco over 9 years
    For future readers: this method does not work. It just raises a android.view.ViewRootImpl$CalledFromWrongThreadException.
  • LeffelMania
    LeffelMania over 9 years
    Looks like there's something wrong in your code (updating UI from a background thread), not mine.
  • Sonny
    Sonny over 9 years
    I am surprised not a lot of people have upvoted this response--this is the correct way to setup listeners on fragments... Perhaps this was a new development in the API.
  • altumano
    altumano over 9 years
    Thanks, it was useful. As unrelated comment: try to stick to Java naming conventions in your code. "V" does not look like a variable name in Java.
  • Mike Brian Olivera
    Mike Brian Olivera over 9 years
    i thinked this could be posiible, but , it didn't work
  • Redoman
    Redoman over 9 years
    It works but I don't get why: I understand that findViewById() works in the scope of an Activity object because it is defined in the Activity class. As explained in this answer, in order to use it in a fragment we need to call it on getView() but... why? Isn't getView() just going to return a View as opposed to an Activity? ... I understand getActivity.findViewById() but getView.findViewById() ???
  • Machado
    Machado about 9 years
    This should be the right answer. The accepted one leaves you with NullPointerException.
  • Confuse
    Confuse almost 9 years
    getView might return null. LeffelMania has a better solution.
  • Dmitry
    Dmitry over 8 years
    Using view passed to onViewCreated still causes NullPointerException but using getActivity() is fine. Any ideas why?
  • Ankur Chaudhary
    Ankur Chaudhary over 8 years
    @dVaffection It may be that you are not returning a non null view in onCreateView() lifecycle method of fragment. Now in case of getActivity you are getting views from your activity rather than fragment main view depends upon what id you are passing. Please check are you returning a non null view from onCreateView or not? Then let me know.
  • Dmitry
    Dmitry over 8 years
    @AnkurChaudhary I return view from onCreateView method. I've just debugged and it turns out there is a layout (in my case FrameLayout). That being said when I try to find an element it returns null. Why is it happening?
  • Ankur Chaudhary
    Ankur Chaudhary over 8 years
    @dVaffection can you please share your class of fragment and corresponding layout.
  • Dmitry
    Dmitry over 8 years
  • Dmitry
    Dmitry over 8 years
    In particular ListActivityFragment.java line 63 (FloatingActionButton) getActivity().findViewById(R.id.floating_new_item);
  • Ankur Chaudhary
    Ankur Chaudhary over 8 years
    @dVaffection i have gone through your code and as you are returning super.oncreateView() which returns null. Another point is when you return null from onCreateView, onViewCreated() method will not be called automatically. Yes you can call it manually. Means onViewCreated will not be called if you are returning null or super method calling. That's why when you are trying to get any view from fragment it's returning null to you.
  • Dmitry
    Dmitry over 8 years
    @AnkurChaudhary What you're saying is valid if you inherit from Fragment, in my case I extend ListFragment which actually returns FrameLayout.
  • Ankur Chaudhary
    Ankur Chaudhary over 8 years
    @dVaffection I checked the layout that ListFragment is using and there is no such view with the id 'floating_new_item'. So it's pretty clear that if you will try to access such field which is not in your layout then it'll return null. Now let me know that is your activity having this id field or not as you are using fragment_list layout in your activity.
  • George
    George over 8 years
    This should be the most voted, since is the correct answer. The one by advantej is wrong, since the layout hasn't been inflated before the getView()
  • Reti43
    Reti43 over 8 years
    This is identical to LeffelMania's answer.
  • Aleksey Khivrenko
    Aleksey Khivrenko about 8 years
    @Raunak You are correct inflater.inflate(R.layout.yourdialogfragment, null).findViewById(R.id.someidfromfragmentdialog) will only return widgets that are in the fragment. If you want to get widgets from the host activity (the activity that spawned the DialogFragment) you have to use getActivity().findViewById(R.id.someidfromhostlayout)
  • Muhammad Babar
    Muhammad Babar almost 8 years
    @Locutus You must clean up these stored references by setting them back to null in onDestroyView() or you will leak the Activity reference please?
  • Amit
    Amit over 7 years
    Why down voted, if you use this, you can use multiple onclicks also in on statement.
  • Boris Karloff
    Boris Karloff about 7 years
    I agree. This answer should be marked as the solution.
  • KMC
    KMC about 7 years
    @Raunak Thanks for the comment. I was wondering out aloud why the accepted answer does not use the view returned by the inflater. This discussion has clarified my doubt.
  • OneCricketeer
    OneCricketeer almost 7 years
    1) What does this add to other answers? 2) You seem to have answered twice
  • OneCricketeer
    OneCricketeer almost 7 years
    There's no reason for the field. You can always call getView() later
  • Bipin Bharti
    Bipin Bharti almost 7 years
    @cricket_007 getview work in onCreateview() in fragment
  • OneCricketeer
    OneCricketeer almost 7 years
    @RobbyPatel There's no possible way it can. It will return null.
  • Bipin Bharti
    Bipin Bharti almost 7 years
    @cricket_007 here is another issue my code is completely good
  • OneCricketeer
    OneCricketeer almost 7 years
    Yes, this code here is okay. Your edits to the other are not.
  • Bipin Bharti
    Bipin Bharti almost 7 years
    @cricket_007 ok which one can you saw me?
  • OneCricketeer
    OneCricketeer almost 7 years
    I'm sorry I can't quite understand your English, but everything is fixed now. I have nothing to show you.
  • Pulak
    Pulak almost 7 years
    Actually you can make it work inside onCreateView() if you capture the view instance as View rootView = inflater.inflate(R.layout.your_fragment_layout, container, false); and do rootView.findViewById() after that
  • OneCricketeer
    OneCricketeer almost 7 years
    @NoLuck, Yes, but that's what the other answers are for
  • Shaurya Uppal
    Shaurya Uppal over 6 years
    Without casting thing explained helped me.
  • Hendy Irawan
    Hendy Irawan over 6 years
  • user3294126
    user3294126 about 6 years
    What if part of creating my Activity (onCreate()) that contains my Fragment depends on the UI elements of the Fragment? Where can I initialize my Fragment's views so that they are initialized after the Fragment has been committed but before the Activity's onCreate() is finished? Or instead should I be initializing my Activity's UI in a method after onCreate(), like onResume()?
  • pintergabor
    pintergabor about 5 years
    Casting to ImageView is redundant.
  • Benjamin Kershner
    Benjamin Kershner over 4 years
    Good information on the difference between onViewCreated and onCreateView here: stackoverflow.com/a/38718205/7715734
  • Pranav Kasetti
    Pranav Kasetti almost 4 years
    I would recommend using view.findViewById since this has a built-in NonNull annotation, thus no warnings to handle null pointer exceptions
  • Moeez
    Moeez about 3 years
    mine giving null. I have posted a new question
  • HX_unbanned
    HX_unbanned about 2 years
    @MattJenko, can you share more details or sample how to do have working solution when the inflated layout is used? for instance, i have an viewpager2 with tablayout (4 tabs ) mediated, and I am inflating the edittext views in fragment, and I need to access the editext for each viewpager2's view from main activity. How to do it exactly?
  • HX_unbanned
    HX_unbanned about 2 years
    Note that API 28 introduces requiereActivity(), requireView(), requireViewById().
  • HX_unbanned
    HX_unbanned about 2 years
    I suggest to combine this answer with one mentioning deprecation of getView() in API 28.