如何使用 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 被调用时被销毁。

因此,片段的视图仅存在于 onCreateViewonDestroyView 之间的中间时间。如果在调用 onCreateView 之前调用 getView,或者在调用 onDestroyView 之后,您将得到 null。

因此,如果您想在视图上设置侦听器,请在 onCreateViewonViewCreated 中执行此操作,然后在 onDestroyView 中将其删除。

此外,如果您想通过成员变量保留您的视图,请在 onCreateView 中设置它并在 onDestroyView 和任何您引用它的地方将其置空,确保检查首先为空。

我还可以建议您使用 ViewBinding。它简化了语法。

https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc

但一定要了解基本的 Android 生命周期以及在 onCreateView 之前无法访问视图的原因。