问题
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