RecyclerView doesn't load data on first launch after Permission Check inside fragment

China☆狼群 提交于 2019-12-24 10:15:34

问题


RecyclerView adapter doesn't load data on first launch after Permission check. I have to re-tap the tab to get the data.

I have already visited/tried these links -

-- RecyclerView doesn't load data in first launch using FirebaseRecyclerAdapter

-- RecyclerView doesn't load items on first start of activity

-- recyclerview not loading adapter values in a fragment

But nothing works yet. Tried to set global adapter, So I can call notifyDataSetChanged() from onResume(). Still It didn't worked.

Here's code -

onCreateView() -

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_third, container, false);

    recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);

    if (checkAndRequestPermissions()) {
        loadSongList();
    }

    return view;
}

onRequestPermissionResult -

loadSongList();  // method

loadSongList() -

private void loadSongList() {
    loadAudio();
    initRecyclerView();
}

loadAudio() -

loadAudio() // accessing data from content resolver

initRecyclerView()-

private void initRecyclerView() {
    if (mAudioList != null && mAudioList.size() > 0) {
        AudioAdapter adapter = new AudioAdapter(mAudioList, getActivity());
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(linearLayoutManager);
        DIviderItemDecoration dividerItemDecoration = new DIviderItemDecoration(getContext(), linearLayoutManager.getOrientation());
        recyclerView.addItemDecoration(dividerItemDecoration);
        recyclerView.setAdapter(adapter);

        RecyclerViewItemClick.addTo(recyclerView).setOnItemClickListener(new RecyclerViewItemClick.OnItemClickListener() {
            @Override
            public void onItemClicked(RecyclerView recyclerView, int position, View v) {
                // life sucks
            }
        });
    }
}

EDIT :

loadAudio() -

private void loadAudio() {
    ContentResolver contentResolver = getActivity().getContentResolver();
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
    String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
    Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);

    if (cursor != null && cursor.getCount() > 0) {
        mAudioList = new ArrayList<>();
        while (cursor.moveToNext()) {
            String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
            String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
            String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
            String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));

            Long albumId = cursor.getLong(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
            Long artWorkId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

            int duration = cursor.getInt(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));

            Uri sArtworkUri = Uri
                    .parse("content://media/external/audio/albumart");
            Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, artWorkId);

            // Save to audioList
            mAudioList.add(new Audio(albumId, data, title, album, artist, albumArtUri, duration));
        }
    }
    if (cursor != null) {
        cursor.close();
    }

}

AudioAdapter -

public class AudioAdapter extends RecyclerView.Adapter<AudioAdapter.CustomViewHolder> {

List<Audio> mList = Collections.emptyList();
Context mContext;

public AudioAdapter(List<Audio> list, Context context) {
    mList = list;
    mContext = context;
}


@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.custom_row, parent, false);
    return new CustomViewHolder(v);
}

@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
    Audio audio = mList.get(position);

    holder.title.setText(audio.getTitle());
    holder.description.setText(audio.getArtist());

    Glide.with(mContext).load(audio.imageId).asBitmap()
            .centerCrop()
            .diskCacheStrategy(DiskCacheStrategy.RESULT)
            .skipMemoryCache(true)
            .placeholder(R.drawable.headset_2)
            .into(holder.imageView);

}

@Override
public int getItemCount() {
    return mList.size();
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

public void insert(int position, Audio list) {
    mList.add(position, list);
    notifyItemChanged(position);
}

public void remove(Audio list) {
    int position = mList.indexOf(list);
    mList.remove(position);
    notifyItemRemoved(position);
}


static class CustomViewHolder extends RecyclerView.ViewHolder {

    CardView cv;
    TextView title;
    TextView description;
    ImageView imageView;

    public CustomViewHolder(View itemView) {
        super(itemView);

        cv = (CardView) itemView.findViewById(R.id.cardView);
        title = (TextView) itemView.findViewById(R.id.playList_name);
        description = (TextView) itemView.findViewById(R.id.album_artist);
        imageView = (ImageView) itemView.findViewById(R.id.imageView1);
    }
}}

UDPATE : checkAndRequestPermission -

private boolean checkAndRequestPermissions() {
    if (SDK_INT >= Build.VERSION_CODES.M) {
        int permissionReadPhoneState = ContextCompat.checkSelfPermission(getContext(), (Manifest.permission.READ_PHONE_STATE));
        int permissionStorage = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE);
        List<String> listPermissionsNeeded = new ArrayList<>();

        if (permissionReadPhoneState != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.READ_PHONE_STATE);
        }

        if (permissionStorage != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }

        if (!listPermissionsNeeded.isEmpty()) {
            requestPermissions(listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
            return false;
        } else {
            return true;
        }
    }
    return false;
}

After removing ActivityCompat and just calling requestPermission, the fragment is receiving callback, But now I'm getting error. logcat below -

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.util.ArrayList.get(int)' on a null object reference
                                                                                          at com.example.ansh.sharedpreferencessimple.service.MusicService.playSong(MusicService.java:167)
                                                                                          at com.example.ansh.sharedpreferencessimple.ThirdFragment$2.onItemClicked(ThirdFragment.java:196)
                                                                                          at com.example.ansh.sharedpreferencessimple.helper.RecyclerViewItemClick$1.onClick(RecyclerViewItemClick.java:21)
                                                                                          at android.view.View.performClick(View.java:6205)
                                                                                          at android.view.View$PerformClick.run(View.java:23653)
                                                                                          at android.os.Handler.handleCallback(Handler.java:751)
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                          at android.os.Looper.loop(Looper.java:154)
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:6682)
                                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

Any help would be appreciated, Thanks.


回答1:


Here is the answer of your problem.

Your loadAudio() method fill up your mAudioList which is your arraylist or list whatever it was.

So, main problem is that when you call loadAudio() and then initRecyclerView() inside your initRecyclerView() the mAudioList is still null because at that time your mAudioList is not fill up inside your loadAudio().

So, the problem of your answer is to call initRecyclerView() at the end of loadAudio() function and this will resolve your issue.

For E.g.

private void loadAudio()
{
     // Get your arraylist of audio and all the stuff
     if (cursor != null)
     {
         cursor.close();
     }
    // Call init function here.
       initRecyclerView();
}


来源:https://stackoverflow.com/questions/44411581/recyclerview-doesnt-load-data-on-first-launch-after-permission-check-inside-fra

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!