Giới thiệu
Trong Fragment, findViewById() phải được gọi trên View root của Fragment (trong onCreateView hoặc onViewCreated), không phải trên Activity.
Các bước đúng
1. Inflate layout trong onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate layout fragment
View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
// Tìm view TRÊN rootView
TextView textView = rootView.findViewById(R.id.myTextView);
Button button = rootView.findViewById(R.id.myButton);
// Thiết lập listener, dữ liệu...
button.setOnClickListener(v -> textView.setText("Clicked!"));
return rootView; // Trả về root view
}
2. Hoặc dùng onViewCreated (khuyên dùng)
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// view ở đây là rootView đã inflate
TextView tv = view.findViewById(R.id.myTextView);
// ...
}
3. View Binding (Hiện đại, an toàn, khuyên dùng)
// build.gradle (app)
android {
buildFeatures {
viewBinding true
}
}
// Fragment
private FragmentLayoutBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentLayoutBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.myTextView.setText("Hello ViewBinding!");
binding.myButton.setOnClickListener(v -> { ... });
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null; // QUAN TRỌNG: Giải phóng binding tránh leak
}
Sai lầm thường gặp
| Sai | Đúng |
|---|---|
findViewById(R.id.x) trong onCreate() | Dùng trong onCreateView/onViewCreated trên rootView |
getActivity().findViewById(R.id.x) | Chỉ dùng nếu view nằm trong Activity layout |
| Không check null | Dùng ViewBinding hoặc check null |
| Giữ reference View sau onDestroyView | Set null trong onDestroyView |
Ví dụ hoàn chỉnh (2 Fragment trong Activity)
Layout Activity (res/layout/activity_main.xml)
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:name="com.example.myapplication.FirstFragment"
android:id="@+id/fragment_first"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<fragment
android:name="com.example.myapplication.SecondFragment"
android:id="@+id/fragment_second"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
FirstFragment.java
package com.example.myapplication;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class FirstFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_simple, container, false);
TextView tv = root.findViewById(R.id.tvContent);
tv.setText("Fragment 1 - findViewById trên rootView");
return root;
}
}
SecondFragment.java
package com.example.myapplication;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class SecondFragment extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_simple, container, false);
TextView tv = root.findViewById(R.id.tvContent);
tv.setText("Fragment 2 - findViewById trên rootView");
return root;
}
}
Fragment Layout (res/layout/fragment_simple.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tvContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:padding="16dp" />
</LinearLayout>
MainActivity.java
package com.example.myapplication;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Chạy ứng dụng
Nhấn Run. Activity hiển thị 2 Fragment, mỗi Fragment tự tìm view trong layout của mình và set text.

Tóm tắt quy tắc vàng
- Luôn inflate layout với
container, false. - Gọi
rootView.findViewById(), không phảifindViewById()haygetActivity().findViewById(). - Dùng View Binding cho type-safe, null-safe, performance tốt hơn.
- Dọn dẹp binding trong
onDestroyView().