0

How to call a method from my activity in to my fragment adapter? I use a RecyclerView on my fragment and there is intent inside this fragment adapter. I already make a method in my Main Activity but I'm unable to call it from my Fragment Adapter.

Method in Main Activity

public void showInterstitial() {
  if(interstitialAd != null && interstitialAd.isLoaded()) {
     interstitialAd.show();
     loadingIklan=true;
  }
}

and I want put that method inside intent switch case on fragment adapter

    public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.ViewHolder> {


    public static class ViewHolder extends RecyclerView.ViewHolder {

        private TextView homeTitle;

        private Context context;

        public ViewHolder(View itemView) {
            super(itemView);
            context = itemView.getContext();
            homeTitle = (TextView)itemView.findViewById(R.id.homeTitle);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    final Intent intent;
                    switch (getAdapterPosition()) {
                        case 0:
                            ((MainActivity) getActivity()).showInterstitial();
                            intent = new Intent(context, AllBlock.class);
                            break;
                        case 1:
                            intent = new Intent(context, BasicBlock.class);
                            break;

                        default:
                            intent = new Intent(context, AllBlock.class);
                            break;
                    }
                    context.startActivity(intent);
                }
            });
        }
    }


    public List<HomeData> homeList;

    public HomeAdapter(List<HomeData> homeList) {

        this.homeList = homeList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.homeTitle.setText(homeList.get(position).getHomeTitle());
    }

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

my main fragment

public class Home extends Fragment {


    public Home() {
        // Required empty public constructor
    }


    private RecyclerView recyclerView;
    private HomeAdapter homeAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.home, container, false);

        recyclerView = (RecyclerView)view.findViewById(R.id.recyclerview);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);

        homeAdapter = new HomeAdapter(homeDataList());
        recyclerView.setAdapter(homeAdapter);

        return view;
    }
}

anyone can help me with a right code? Thank you.

user9056633
  • 51
  • 1
  • 9
  • use interface. Make a global interface and define in the activity and call it in recyclerview adapter – Ankur_009 Dec 09 '17 at 09:44
  • @Ankur_009 how to do it? Show me example code – user9056633 Dec 09 '17 at 09:46
  • Possible duplicate of [Call an activity method from a fragment](https://stackoverflow.com/questions/12659747/call-an-activity-method-from-a-fragment) – Bharat Dec 09 '17 at 10:02
  • @bharath i already try that. Seems not work for me – user9056633 Dec 09 '17 at 10:04
  • It works. I'm still using the same thing instead of interfaces.Probably you might have made a mistake. Check it once – Bharat Dec 09 '17 at 10:05
  • @bharath which one correct answer based my question that i have to try in that answer ? – user9056633 Dec 09 '17 at 10:07
  • ((MainActivity) getActivity()).showInterstitial(); this should work. – Bharat Dec 09 '17 at 10:09
  • @bharath doesnt work dude. It show red code at getActivity. Also it crash when i open the apps. – user9056633 Dec 09 '17 at 10:10
  • If it is showing red means you are doing a mistake.If that getActivity() is not working try to pass the MainActivity context to this fragment and cast this context which you obtained from main activity. Now it must work – Bharat Dec 09 '17 at 10:13
  • The reason why you are getting error at getActivity() is you are trying to get the context from an inner class which doesn't have one super class. So you are getting that error. What you can do is take a context variable in the fragment class and do this : Context ctx = getActivity() and pass this ctx variable to your inner class. Now it must work – Bharat Dec 09 '17 at 10:15
  • @bharath i already add Context ctx = getActivity() in my MainFragment. What must i write to pass this on this adapter – user9056633 Dec 09 '17 at 10:20

2 Answers2

1

You should not call activity from RecyclerView adapter. Adapter should only handling the data presentation. Hence, you need to you a Listener/Callback pattern. Because your adapter is called from fragment where the fragment is attached to the activity, then you need to create a nested Listener/Callback.

First, create the listener interface in RecyclerView adapter. The purpose of the interface is to tell the listener (which is Fragment) to do something.

public class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {

  ...
  private AdapterListener listener;

  // define the listener
  public interface AdapterListener {
    void onItemClicked(int position);
  }

  // register the listener with this method
  public setListener(AdapterListener listener) {
    this.listener = listener;
  }

  ...

  public ViewHolder(View itemView) {
    itemView.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {

         // tell the listener about the click
         if(listener != null) {
           listener.onItemClicked(getAdapterPosition());
         }

       }
  }

}

Second, register the Fragment as the listener:

public class YourFragment extends Fragment {
  ...
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    ...
    // This is an example, you can register the listener in any method

    // sample
    YourAdapter adapter = new YourAdapter(...);

    YourAdapter.AdapterListener listener = new YourAdapter.AdapterListener {
       @Override
       public void onItemClicked(int position) {

         // handle the item click here.
       }
    }
  }
}

Third, create listener to communicate between Fragment and Activity (Read more at Communicating with Other Fragments:

public class YourFragment extends Fragment {
  private FragmentListener mListener;

  public interface FragmentListener {
    onRecyclerViewItemClicked(int position);
  }

  @Override
  public void onAttach(Context context) {
    super.onAttach(context);

    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try {
        mCallback = (FragmentListener) context;
    } catch (ClassCastException e) {
        throw new ClassCastException(context.toString()
                + " must implement FragmentListener");
    }
  }

}

Fourth, execute the fragment listener to tell the activity about the recyclerView item click. Add the code in the previous Adapter listener:

public class YourFragment extends Fragment {
  ...
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    ...
    // This is an example, you can register the listener in any method

    YourAdapter adapter = new YourAdapter(...);

    YourAdapter.AdapterListener listener = new YourAdapter.AdapterListener {
       @Override
       public void onItemClicked(int position) {
         mListener.onRecyclerViewItemClicked(position);
       }
    }
  }
}

Fifth, register the activity as the listener receiver. Hence you do the actual logic:

public class YourActivity extends Activity
        implements YourFragment.FragmentListener {

  ...

  @Ovveride
  public void onRecyclerViewItemClicked(int position) {
    // Handle the RecyclerView item click here
    switch(position) {
      case 0:
        showInterstitial();
        break;
     default:
       intent = new Intent(this, AllBlock.class);
       startActivity(intent);
    }
  }
}

Note:

I tend to use Event Bus mechanism with EventBus because it simplify all the listener code. You could try EventBus after you've mastering the Listener/Callback pattern. Horas!

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
0

interfacesample.java

public interface sample{
      function onclick();
}

activity.java

class activity extends appcombatactivity implements sample{
         override onclick(){
//do whatever you want to do
}

}

//adapter.java

switch (getAdapterPosition()) {
                            case 0:
                            //getActivity show red code//
                               (context as activity).onclick()

                                break;
                            default:
                                intent = new Intent(context, AllBlock.class);
                                break;
                        }

something like that. Hope you able to understand. Let me know if have any doubt.

Ankur_009
  • 3,823
  • 4
  • 31
  • 47