0

When I attempt to start a Fragment from an Adapter, I get this exception.

I looked for similar issues, but casting to androidX is relatively new, so I couldn't find relevant solutions. I found a solution for passing a FragmentManager to the constructor when creating an Adapter object. This also required initilalizing a FragmentMAnager, and that's where I got stuck again.

The code for the process is:

AppCompatActivity activity = (AppCompatActivity) v.getContext();
    int id = currentCountry.getId();

    Fragment mdf = new DetailsFragment();

    activity.getSupportFragmentManager()
            .beginTransaction()
            .replace(R.id.fragments_container, mdf)
            .addToBackStack(null)
            .commit();

The exception message is

java.lang.ClassCastException: android.app.Application cannot be cast to androidx.appcompat.app.AppCompatActivity.

Any ideas for a solution? maybe the last option will be reverting back to android from androidX.

Is there other code that's needed to figure this issue out?

D. Joe
  • 81
  • 10
  • @d-joe is v view in adapter? how do you inflate it? It seems that you inflate your view using application context, it can lead you to problems, because theme associates with activity context. – Bracadabra Nov 12 '19 at 12:10
  • You shouldn't be performing a `FragmentTransaction` in an `Adapter`. Instead, create an `interface` to relay the click (or whatever action) back to the `Activity`, and let it do the transaction. If you really don't want to do that, for some reason, then just modify your `Adapter` to take an `AppCompatActivity` specifically in its constructor, and use that, rather than trying to cast a `View`'s `Context`. – Mike M. Nov 12 '19 at 12:11
  • @MikeM. you mean doing the transaction in an Interface? – D. Joe Nov 12 '19 at 12:17
  • I don't know what that `Adapter` is for, but I mean like the `ItemClickListener` interface demonstrated in [this answer](https://stackoverflow.com/a/40584425). Note how the `Activity` implements the interface, and a `Toast` is shown in `onItemClick()`. Instead of the `Toast`, you would do your transaction. – Mike M. Nov 12 '19 at 12:23
  • I tried implementing the Interface and methods as demonstrated in the link you added. I think it works. I also need to get the clicked position back to the ListActivity from which the list Adapter is instantiated, or, better, get the clicked item data through the Adapter method getAdapterPosition(). – D. Joe Nov 17 '19 at 14:31

2 Answers2

0

I Think its perfect in my way

Replace ((YOUR_ACTIVITY_NAME) ADAPTER_CONTEXT) to activity so you get your Current Activity

int id = currentCountry.getId();

Fragment mdf = new DetailsFragment();

((YOUR_ACTIVITY_NAME) ADAPTER_CONTEXT).getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.fragments_container, mdf)
        .addToBackStack(null)
        .commit();
Sanjay Hadiya
  • 864
  • 9
  • 21
0

View.getContext() don't have to return Context of your Activity. It basically can be any Context that was used to inflate this view. In your case Context used to inflate view in your adapter is ApplicationContext. For quick fix you can change Context used in onCreateViewHolder method of your RecyclerAdapter. I am not sure how You inflate your recyclerview but maybe consider using parent.getContext() in onCreateViewHolder.

However it is much better to create callback in your adapter and delegate that click event to owner of your RecyclerView.

Artur Szymański
  • 1,639
  • 1
  • 19
  • 22
  • I did as you suggested, but now I'm facing a new challenge: I need to pass the clicked item's data to the destination Fragment. Is there a way to make the callback you suggested return such data? – D. Joe Nov 16 '19 at 20:49
  • If you are using callback just add parameter to that function and pass your data :) – Artur Szymański Nov 17 '19 at 10:43
  • I tried. couldn't figure it out. If you think you can help, you can see my question about that [here](https://stackoverflow.com/questions/58894651/how-to-pass-the-getadapterposion-value-back-to-the-calling-activity-through-ca?noredirect). Thanks. – D. Joe Nov 17 '19 at 11:05