1

I used a recyclerView on my app to display all files from an external storage. Until I changed it, it worked fine when it was implemented in the "MainActivity.java".

Now, I want my app to have a "BottomNavigationBar"; in order to do that, I use fragments. The problem is the app crashes when I touch the specific item from the menu (the one containing the RecyclerView).

I changed all the "this" method to ".getActivity()" but it crashed anyways. I changed it to ".getActivity().getApplicationContext()" but it still crashed.

I'm sorry, my computer does not support hardware acceleration so I can't properly show what the error is. Instead, I have attached a debugger to my connected phone and set up breakpoints. The debugger highlighted the line "RecyclerView recyclerView = getView().findViewById(R.id.recyclerview);" when the app crashed.

Here's the fragment code:

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();
    }
}

[Let me know if you need more code]

How can I fix this ?

MSpeed
  • 8,153
  • 7
  • 49
  • 61
Ricochet
  • 65
  • 1
  • 8

6 Answers6

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

Instead of getView(), you need to use the view inflated in onCreateView

So,

 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;
    }

If you want, you can then populate the RecyclerView (or make it visible, or whatever) in initRecyclerView()

MSpeed
  • 8,153
  • 7
  • 49
  • 61
0

try this getActivity() instance of getView()

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

instance of

RecyclerView recyclerView = getActivity().findViewById(R.id.recyclerview);
Android
  • 1,420
  • 4
  • 13
  • 23
Mayur Karmur
  • 2,119
  • 14
  • 35
0

Change your code to this-

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()));
    }
Prachi Singh
  • 564
  • 3
  • 8
-1

Remove the onCreate mewthod and move the logic into onCreateView

Joachim Haglund
  • 775
  • 5
  • 15
-1

Here the issue is your recyclerView initializes by calling getActivity() but the problem is that the activity does not exist until onActivityCreated() is called.

So it's crashing. Move all of that code inside onCreate() to onActivityCreated() and it should work fine.

Android
  • 1,420
  • 4
  • 13
  • 23
RootZero
  • 59
  • 5
-1

Move below code for handling permission 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();
        }
    }

In Fragment, you can initialize your view in 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);
    }

Change your initRecyclerView() like below,

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()));
    }

It will shows fragment page without blank,

Screenshot1

For more clarification about life cycle of Fragment, refer this

Android
  • 1,420
  • 4
  • 13
  • 23
  • This method works but now the fragment shows nothing. All the code concerning permission was moved to ```OnAtivityCreated```, ```PermissionExists``` does not call ```initRecyclerView``` anymore but ```onViewCreated``` does with the new ```initRecyclerView``` you provided... – Ricochet Jul 02 '19 at 12:48
  • Is it working now? Move your permission function in `onCreateView` or else do in `onViewCreated`. – Android Jul 02 '19 at 12:53
  • The application does not crash anymore when I touch the concern item. But, the RecyclerView does not show any view. It did back when ```initRecyclerView``` was defined in the main java script. I am facing a blank page right now. (What do you mean by "Permission function" ?) – Ricochet Jul 02 '19 at 13:14
  • It worked. I realized I forgot to inflate the layout. Thank you for the answer. – Ricochet Jul 02 '19 at 17:00
  • Happy to help you @Ricochet – Android Jul 03 '19 at 05:01
  • I'm sorry, this is a misclick I was trying to reach the accept answer button. Since, I'm a new user, I can't change it back to normal... Again, I'm sorry this was not intended. Your answer is great. – Ricochet Jul 03 '19 at 07:17
  • @Ricochet No issues, thanks for your comment. I tried to improve my answers. – Android Jul 03 '19 at 07:31