'RecyclerView' 的初始化方法在与片段一起使用时会导致应用程序崩溃

Initialization Method for 'RecyclerView' crashes app when used with fragments

我在我的应用程序上使用了一个 recyclerView 来显示来自外部存储的所有文件。在我更改它之前,它在 "MainActivity.java" 中实现时运行良好。

现在,我希望我的应用程序有一个 "BottomNavigationBar";为此,我使用片段。问题是当我触摸菜单中的特定项目(包含 RecyclerView 的项目)时应用程序崩溃。

我将所有 "this" 方法更改为“.getActivity()”,但它还是崩溃了。我将其更改为“.getActivity().getApplicationContext()”,但它仍然崩溃。

对不起,我的电脑不支持硬件加速,所以我无法正确显示错误是什么。相反,我已将调试器附加到我连接的 phone 并设置断点。当应用程序崩溃时,调试器会突出显示 "RecyclerView recyclerView = getView().findViewById(R.id.recyclerview);" 行。

这是片段代码:

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_records, container, false);
    }

    private static final int PERMISSION_REQUEST = 1000;
    private ArrayList<String> mNames = new ArrayList<>();
    public static ArrayList<String> NbFiles = new ArrayList<>();
    public ArrayList<String> PathFiles = new ArrayList<>();

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Check if we have the permission to read storage
        if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            //We don't have the permission, so request it.
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST);
        }
        //We already have permission
        else {
            permissionExists();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == PERMISSION_REQUEST) {
            if (resultCode == RESULT_OK) {
                permissionExists();
            } else {
                //handle error
            }
        }
    }

    private void initRecyclerView() {
        RecyclerView recyclerView = getView().findViewById(R.id.recyclerview);
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(mNames, getActivity().getApplicationContext(), (RecyclerViewAdapter.OnNoteListener) this);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
    }

    private void permissionExists() {
        String path = Environment.getExternalStorageDirectory().toString() + "/Rapture";
        File directory = new File(path);
        boolean success = true;
        if (!directory.exists()) {
            success = directory.mkdirs();
        }
        if (success) {
            File[] arrayFiles = directory.listFiles();
            for (File file : arrayFiles) {
                mNames.add(file.getName());
                PathFiles.add(file.getPath());
                NbFiles.add(file.getName());
            }
        }
        initRecyclerView();
    }
}

[如果您需要更多代码,请告诉我]

我该如何解决这个问题?

移除onCreate方法并将逻辑移至onCreateView

RecyclerView recyclerView = getView().findViewById(R.id.recyclerview);

而不是getView(),您需要使用在onCreateView

中膨胀的视图

所以,

 RecyclerView recyclerView;

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_records, container, false);
        recyclerView = v.findViewById(R.id.recyclerview);
        return v;
    }

如果需要,您可以在 initRecyclerView()

中填充 RecyclerView(或使其可见,或其他)

试试这个 getActivity() getView()

实例
RecyclerView recyclerView = getView().findViewById(R.id.recyclerview);  

的实例
RecyclerView recyclerView = getActivity().findViewById(R.id.recyclerview);

这里的问题是您的 recyclerView 通过调用 getActivity() 进行初始化,但问题是 activity 在调用 onActivityCreated() 之前不存在。

所以它崩溃了。将 onCreate() 内的所有代码移动到 onActivityCreated() ,它应该可以正常工作。

将处理权限的代码移至下方onActivityCreated

@Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            //We don't have the permission, so request it.
            ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST);
        }
        //We already have permission
        else {
            permissionExists();
        }
    }

在 Fragment 中,您可以在 onViewCreated

中初始化您的视图
    // This event is triggered soon after onCreateView().
    // Any view setup should occur here.  E.g., view lookups and attaching view listeners.
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // Setup any handles to view objects here
         initRecyclerView(view);
    }

像下面这样更改您的 initRecyclerView()

private void initRecyclerView(View v) {
        RecyclerView recyclerView = v.findViewById(R.id.recyclerview);
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(mNames, getActivity().getApplicationContext(), (RecyclerViewAdapter.OnNoteListener) this);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
    }

它会显示 fragment 页没有空白,

有关 Fragment 生命周期的更多说明,请参阅

将您的代码更改为此-

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_records, container, false);
    initRecyclerView(view);
    return view;
}



private void initRecyclerView(View view) {
        RecyclerView recyclerView = view.findViewById(R.id.recyclerview);
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(mNames, getActivity().getApplicationContext(), (RecyclerViewAdapter.OnNoteListener) this);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
    }