Reputation: 250
I have been trying to call a new fragment from a Recycler View, but I keep getting a Attempt to invoke virtual method androidx.fragment.app.FragmentManager androidx.appcompat.app.AppCompatActivity.getSupportFragmentManager() on a null object reference
I have tried the code in the following Stackoverflow articles:
How to pass Bundle from Fragment to Fragment
how to move from one fragment to another fragment on button click
I am not sure what I am doing wrong. I am hoping someone can help me with this.
Adapter Code to Call New Fragment:
@Override
public void onClick(View v) {
String albumId = String.valueOf(albumList.get(getAdapterPosition()).safeGetFirstSong().albumId);
Log.i(TAG,"INFO - ALBUMADAPTER is passing albumId: "+albumId);
FragmentManager fragmentManager = ((AppCompatActivity)context).getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment fragment = null;
Bundle bundle = new Bundle();
bundle.putInt(EXTRA_ALBUM_ID, Math.toIntExact(albumList.get(getAdapterPosition()).safeGetFirstSong().albumId));
fragment.setArguments(bundle);
transaction.setCustomAnimations(R.anim.layout_fad_in,R.anim.layout_fad_out,
R.anim.layout_fad_in,R.anim.layout_fad_out);
transaction.hide(Objects.requireNonNull(((AppCompatActivity) context).getSupportFragmentManager()
.findFragmentById(R.id.main_container)));
transaction.add(R.id.main_container, fragment);
transaction.addToBackStack(null).commit();
//Intent intent = new Intent(context, AlbumDetails.class);
//intent.putExtra("albumId", albumList.get(getAdapterPosition()).safeGetFirstSong().albumId);
//context.startActivity(intent);
}
Fragment Code:
public class AlbumDetailsFragment extends Fragment{
Bundle bundle = getArguments();
int s = bundle.getInt("album_id");
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.album_details_fragment, null);
return root;
}
}
Logcat:
2020-11-09 07:43:49.428 13172-13172/com.example.audioplayer E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.audioplayer, PID: 13172
java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.fragment.app.FragmentManager androidx.appcompat.app.AppCompatActivity.getSupportFragmentManager()' on a null object reference
at com.example.audioplayer.adapters.AlbumAdapter$AlbumViewHolder.onClick(AlbumAdapter.java:95)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
AlbumAdapter:
public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.AlbumViewHolder> {
private List<Album> albumList;
//private Context context;
private AppCompatActivity context;
private static final String EXTRA_ALBUM_ID = "album_id";
public AlbumAdapter(List<Album> albumList) {
this.albumList = albumList;
this.context = context;
}
@NonNull
@Override
public AlbumViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new AlbumViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.single_album_gride_item, parent, false));
}
protected String getAlbumTitle(Album album) {
return album.getTitle();
}
@Override
public void onBindViewHolder(@NonNull AlbumViewHolder holder, int position) {
Album album = albumList.get(position);
if(album!=null) {
holder.albumName.setText(getAlbumTitle(album));
holder.albumArtist.setText(album.getArtistName());
Picasso.get().load("content://media/external/audio/albumart/"+album.safeGetFirstSong().albumId).placeholder(R.drawable.album).error(R.drawable.album)
.into(holder.albumArt);
}
}
@Override
public int getItemCount() {
return albumList!=null?albumList.size():0;
}
public class AlbumViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private ImageView albumArt;
private TextView albumName, albumArtist;
public AlbumViewHolder(@NonNull View itemView) {
super(itemView);
albumArt = (ImageView)itemView.findViewById(R.id.albumArt);
albumName = (TextView)itemView.findViewById(R.id.albumName);
albumArtist = (TextView)itemView.findViewById(R.id.artistName);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
String albumId = String.valueOf(albumList.get(getAdapterPosition()).safeGetFirstSong().albumId);
Log.i(TAG,"INFO - ALBUMADAPTER is passing albumId: "+albumId);
FragmentManager fragmentManager = context.getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment fragment = null;
Bundle bundle = new Bundle();
bundle.putInt(EXTRA_ALBUM_ID, Math.toIntExact(albumList.get(getAdapterPosition()).safeGetFirstSong().albumId));
fragment.setArguments(bundle);
transaction.setCustomAnimations(R.anim.layout_fad_in,R.anim.layout_fad_out,
R.anim.layout_fad_in,R.anim.layout_fad_out);
transaction.hide(Objects.requireNonNull(((AppCompatActivity) context).getSupportFragmentManager()
.findFragmentById(R.id.main_container)));
transaction.add(R.id.main_container, fragment);
transaction.addToBackStack(null).commit();
}
}
}
UPDATE _ TWO ADDITIONAL ERRORS CREATED BY CHANGE
AlbumFragment Code
public class AlbumFragment extends Fragment {
private RecyclerView recyclerView;
private AlbumAdapter albumAdapter;
int spanCount = 3; // 3 columns
int spacing = 20; // 50px
boolean includeEdge = true;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.album_fragment, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), spanCount));
new LoadData().execute("");
return view;
}
public class LoadData extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
if (getActivity() != null) {
albumAdapter = new AlbumAdapter(new AudioLoader().getAllAlbums(getActivity()));
}
return "Executed";
}
@Override
protected void onPostExecute(String s) {
recyclerView.setAdapter(albumAdapter);
if(getActivity()!=null) {
recyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, includeEdge));
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
}
}
Error
Task :app:compileDebugJavaWithJavac FAILED C:\Users\rvogl\Desktop\audioPlayer\app\src\main\java\com\example\audioplayer\fragments\AlbumFragment.java:42: error: constructor AlbumAdapter in class AlbumAdapter cannot be applied to given types; albumAdapter = new AlbumAdapter(new AudioLoader().getAllAlbums(getActivity())); ^ required: AppCompatActivity,List found: List reason: actual and formal argument lists differ in length
AlbumSongFragment Code:
public class AlbumSongsFragment extends Fragment {
private long albumId;
private AlbumAdapter albumAdapter;
private RecyclerView recyclerView;
private CollapsingToolbarLayout collapsingToolbarLayout;
private Album album;
private ImageView smallAlbumArt, bigAlbumArt;
private TextView albumName, artistName, albumDetails;
public static AlbumSongsFragment newInstance(long id) {
Bundle args = new Bundle();
args.putLong("_ID", id);
AlbumSongsFragment fragment = new AlbumSongsFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@NonNull Bundle savedInstanceState) {
albumId = getArguments().getLong("_ID");
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.album_details_fragment, container, false);
recyclerView = (RecyclerView)view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext().getApplicationContext()));
recyclerView.setHasFixedSize(true);
new LoadData().execute("");
return view;
}
public class LoadData extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
if(getActivity()!=null) {
albumAdapter=new AlbumAdapter(Collections.singletonList(new AudioLoader().getAlbum(getActivity(), albumId)));
}
return "Executed";
}
@Override
protected void onPostExecute(String s) {
if(getActivity()!=null) {
recyclerView.setAdapter(albumAdapter);
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
}
}
Error
C:\Users\rvogl\Desktop\audioPlayer\app\src\main\java\com\example\audioplayer\fragments\AlbumSongsFragment.java:76: error: constructor AlbumAdapter in class AlbumAdapter cannot be applied to given types; albumAdapter=new AlbumAdapter(Collections.singletonList(new AudioLoader().getAlbum(getActivity(), albumId))); ^ required: AppCompatActivity,List found: List reason: actual and formal argument lists differ in length Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details.
As Rquested here is the code snipit that is causing an issue:
public class LoadData extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
if (getActivity() != null) {
albumAdapter = new AlbumAdapter(this,new AudioLoader().getAllAlbums(getActivity()));
}
return "Executed";
}
@Override
protected void onPostExecute(String s) {
recyclerView.setAdapter(albumAdapter);
if(getActivity()!=null) {
recyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, includeEdge));
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
}
Upvotes: 1
Views: 266
Reputation: 66
In AlbumAdapter use :
private AppCompatActivity context;
and give the activity context in arguments of AlbumAdapter constructor like:
public AlbumAdapter(AppCompatActivity ctx,List<Album> albumList) {
this.albumList = albumList;
this.context = ctx;
}
and then you can use
context.getSupportFragmentManagger();
Upvotes: 1