Search code examples
javaandroidinterfacefragmentandroid-tablayout

Implementing interface from Tablayout Fragment ( Android)


i'm not sure this is the perfect title for this but its the best i could come up with.

I have a java class ApiRequest the runs some http requests and returns the result in a callback via an interface. Example will be the authenticate method below:

public class ApiRequest {

     private Context context;
     private ApiRequestCallback api_request_callback;

    public ApiRequest ( Context context ){
       this.context = context;

       // this can either be activity or context. Neither works in fragment
       // but does in activity
       this.api_request_callback = ( ApiRequestCallback ) context;
    }

 public interface ApiRequestCallback {
    void onResponse(JSONObject response );
    void onErrorResponse(JSONObject response );
}

public JsonObject authenticate(){
   .... do stuff and when you get response from the server. This is some 
   kinda of async task usually takes a while

   // after you get the response from the server send it to the callback
   api_request_callback.onResponse( response );
}

Now i have a fragment class in a tablayout, that implements this class below

public class Home extends Fragment implements ApiRequest.ApiRequestCallback 
{

  // I have tried
  @Override
   public void onViewCreated(.........) {
      api_request = new ApiRequest( getContext() );
   }


   // and this two
   @Override
   public void onAttach(Context context) {
      super.onAttach(context);
      api_request = new ApiRequest( context );
   }

   @Override
public void onResponse(JSONObject response) {
   //I expect a response here
}

}

The response i get is that i can cannot cast: the activity context to the interface.

Java.lang.ClassCastException: com.*****.**** cannot be cast to com.*****.****ApiRequest$ApiRequestCallback

But this works with a regular activity so its really has me on the edge. A fix for this will be greatly appreciated. A teachable moment for me i'd say. Thanks


Solution

  • To construct your ApiRequest object, you are passing context. In the constructor, you are assuming that you can always cast this context to ApiRequestCallback (this is the error you are doing). Like in your fragment - fragment does not have a context of its own, when you use getContext() in a fragment, it returns the parent activity's context and this in your ApiRequest class's constructor can't be cast to ApiRequestCallback.

    Change ApiRequest constructor to below :

    public ApiRequest (Context context, ApiRequestCallback api_request_callback){
           this.context = context;
           this.api_request_callback = api_request_callback;
    }
    

    and then in your fragment use this :

    api_request = new ApiRequest(getContext(), Home .this);