Android Development
findViewById
Fragments
User Interface
Android Programming

findViewById in Fragment

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

findViewById works in a fragment, but the lookup must be performed against the fragment's current root view rather than against the fragment object itself. The important detail is lifecycle: a fragment instance can outlive its view, so view access is only valid between onCreateView and onDestroyView.

Find Views from the Inflated Root

In a fragment, the layout is usually inflated in onCreateView. The return value of that method is the root of the fragment's view hierarchy, and that root is the correct place to call findViewById.

kotlin
1class ProfileFragment : Fragment() {
2    override fun onCreateView(
3        inflater: LayoutInflater,
4        container: ViewGroup?,
5        savedInstanceState: Bundle?
6    ): View {
7        val root = inflater.inflate(R.layout.fragment_profile, container, false)
8        val nameText = root.findViewById<TextView>(R.id.nameText)
9        nameText.text = "Ada Lovelace"
10        return root
11    }
12}

This works because the lookup is scoped to the fragment layout you just inflated. It does not search the entire activity view tree unless that fragment view is part of it.

onViewCreated Is Often Cleaner

Many teams prefer to keep inflation and view setup separate. In that style, the fragment layout is inflated first, and all UI wiring happens in onViewCreated.

kotlin
1class ProfileFragment : Fragment(R.layout.fragment_profile) {
2    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
3        super.onViewCreated(view, savedInstanceState)
4
5        val nameText = view.findViewById<TextView>(R.id.nameText)
6        val refreshButton = view.findViewById<Button>(R.id.refreshButton)
7
8        nameText.text = "Ada Lovelace"
9        refreshButton.setOnClickListener {
10            nameText.text = "Refreshing..."
11        }
12    }
13}

This is often easier to read because onCreateView stays focused on view creation and onViewCreated handles listeners, adapters, and state binding.

Know When requireView() Is Safe

You may also see code such as requireView().findViewById(...). That is valid only when the fragment already has an active view. If you call it too early or after the view is destroyed, it throws.

kotlin
1override fun onResume() {
2    super.onResume()
3    val statusText = requireView().findViewById<TextView>(R.id.statusText)
4    statusText.text = "Visible"
5}

This can be convenient in lifecycle callbacks that definitely run while the view exists, but it is less explicit than using the view parameter from onViewCreated.

Avoid Holding Stale View References

A fragment can remain on the back stack after its view hierarchy is destroyed. That means storing direct view references in long-lived fields can leak the old hierarchy or crash later when code tries to use views that no longer exist.

If you cache a view reference, clear it in onDestroyView. Better yet, avoid manual caching when the lookup is cheap or when View Binding is available.

kotlin
1class ProfileFragment : Fragment() {
2    private var titleView: TextView? = null
3
4    override fun onCreateView(
5        inflater: LayoutInflater,
6        container: ViewGroup?,
7        savedInstanceState: Bundle?
8    ): View {
9        val root = inflater.inflate(R.layout.fragment_profile, container, false)
10        titleView = root.findViewById(R.id.nameText)
11        return root
12    }
13
14    override fun onDestroyView() {
15        super.onDestroyView()
16        titleView = null
17    }
18}

That pattern is safe, but modern Android code usually does even better with View Binding.

Prefer View Binding for Nontrivial Fragments

findViewById still works, but View Binding reduces boilerplate and gives compile-time types for the layout.

kotlin
1class ProfileFragment : Fragment() {
2    private var _binding: FragmentProfileBinding? = null
3    private val binding get() = _binding!!
4
5    override fun onCreateView(
6        inflater: LayoutInflater,
7        container: ViewGroup?,
8        savedInstanceState: Bundle?
9    ): View {
10        _binding = FragmentProfileBinding.inflate(inflater, container, false)
11        return binding.root
12    }
13
14    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
15        super.onViewCreated(view, savedInstanceState)
16        binding.nameText.text = "Ada Lovelace"
17    }
18
19    override fun onDestroyView() {
20        super.onDestroyView()
21        _binding = null
22    }
23}

For fragments with several controls, this is usually easier to maintain than repeated ID lookups.

Common Pitfalls

  • Calling findViewById on the fragment instead of on the fragment's root view.
  • Accessing views in onCreate, before the fragment view exists.
  • Using requireView() in code paths where the lifecycle state is uncertain.
  • Keeping view references after onDestroyView and accidentally using stale views.
  • Sticking with repeated findViewById calls in a complex fragment where View Binding would be clearer.

Summary

  • In a fragment, call findViewById on the root view or on the view passed to onViewCreated.
  • Only access fragment views while the view hierarchy exists.
  • 'onViewCreated is usually the cleanest place for UI wiring.'
  • Be careful with requireView() because it throws when no current view exists.
  • Prefer View Binding for larger fragments or long-term code maintenance.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.