如何使用 findViewById 在 Fragment 的 OnCreateView 之外获取 ViewGroup?
How do I use findViewById to get a ViewGroup outside OnCreateView in a Fragment?
我有一个 ConstraintLayout
(child)嵌套在另一个 ConstraintLayout
(parent)中。我希望能够从 Fragment
class 内部但在 onCreateView
外部调用 child。这是我目前所拥有的:
public class HomeFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
HomeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
return root;
}
ConstraintLayout MyLayout = (ConstraintLayout) getView().findViewById(R.id.my_layout);
}
结果是 NullPointerException
:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
我什至尝试在 Fragment
class 中声明一个全局 root
变量并将膨胀的视图结果分配给它,但问题仍然存在。
我无法将 myLayout
放在 OnCreateView
中,所以我需要一个可以在其外部使用它的解决方案。
您可以为视图声明全局变量并使用方法进行初始化。
public class HomeFragment extends Fragment {
private ConstraintLayout MyLayout;
private void init(View v) {
MyLayout = v.findViewById(R.id.my_layout);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
init(root);
return root;
}
}
或者你可以声明你的根,你可以用根变量找到你的视图:
public class HomeFragment extends Fragment {
private View root;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_home, container, false);
init()
return root;
}
private void init(){
ConstraintLayout MyLayout = root.findViewById(R.id.my_layout);
.
.
.
}
}
您的问题源于对片段视图存在的时间和持续时间的误解。
目前,您正在构建片段期间分配 MyLayout 变量。
根据 the Android documentation on a Fragment's lifecycle 片段在调用 onCreateView
之前不会有与之关联的视图。稍后在片段的生命周期中,视图在 onDestroyView
被调用时被销毁。
因此,片段的视图仅存在于 onCreateView
和 onDestroyView
之间的中间时间。如果在调用 onCreateView
之前调用 getView
,或者在调用 onDestroyView
之后,您将得到 null。
因此,如果您想在视图上设置侦听器,请在 onCreateView
或 onViewCreated
中执行此操作,然后在 onDestroyView
中将其删除。
此外,如果您想通过成员变量保留您的视图,请在 onCreateView
中设置它并在 onDestroyView
和任何您引用它的地方将其置空,确保检查首先为空。
我还可以建议您使用 ViewBinding。它简化了语法。
https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc
但一定要了解基本的 Android 生命周期以及在 onCreateView 之前无法访问视图的原因。
我有一个 ConstraintLayout
(child)嵌套在另一个 ConstraintLayout
(parent)中。我希望能够从 Fragment
class 内部但在 onCreateView
外部调用 child。这是我目前所拥有的:
public class HomeFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
HomeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
return root;
}
ConstraintLayout MyLayout = (ConstraintLayout) getView().findViewById(R.id.my_layout);
}
结果是 NullPointerException
:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
我什至尝试在 Fragment
class 中声明一个全局 root
变量并将膨胀的视图结果分配给它,但问题仍然存在。
我无法将 myLayout
放在 OnCreateView
中,所以我需要一个可以在其外部使用它的解决方案。
您可以为视图声明全局变量并使用方法进行初始化。
public class HomeFragment extends Fragment {
private ConstraintLayout MyLayout;
private void init(View v) {
MyLayout = v.findViewById(R.id.my_layout);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
init(root);
return root;
}
}
或者你可以声明你的根,你可以用根变量找到你的视图:
public class HomeFragment extends Fragment {
private View root;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_home, container, false);
init()
return root;
}
private void init(){
ConstraintLayout MyLayout = root.findViewById(R.id.my_layout);
.
.
.
}
}
您的问题源于对片段视图存在的时间和持续时间的误解。
目前,您正在构建片段期间分配 MyLayout 变量。
根据 the Android documentation on a Fragment's lifecycle 片段在调用 onCreateView
之前不会有与之关联的视图。稍后在片段的生命周期中,视图在 onDestroyView
被调用时被销毁。
因此,片段的视图仅存在于 onCreateView
和 onDestroyView
之间的中间时间。如果在调用 onCreateView
之前调用 getView
,或者在调用 onDestroyView
之后,您将得到 null。
因此,如果您想在视图上设置侦听器,请在 onCreateView
或 onViewCreated
中执行此操作,然后在 onDestroyView
中将其删除。
此外,如果您想通过成员变量保留您的视图,请在 onCreateView
中设置它并在 onDestroyView
和任何您引用它的地方将其置空,确保检查首先为空。
我还可以建议您使用 ViewBinding。它简化了语法。
https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc
但一定要了解基本的 Android 生命周期以及在 onCreateView 之前无法访问视图的原因。