0

I organize all the API calling method of my app inside a separate class.So when I get the response from the server,I insert it into a Model class.But the problem is,I cant notifyDataSetChanged()(from the class I parsing the JSON) after I parsing all the JSON. Therefore,my adapter's getItemCount() value is always be 0.Ended up the recyclerView never have data.

Here is my Fragment.class

RecyclerView recyclerView;
LatestAdapter latestAdapter;
List<PostItem> latestItems;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 

     // Inflate the layout for this fragment
    View view =  inflater.inflate(R.layout.fragment_latest, container, false);

    // Initilize the RecyclerView and Adapter  
    recyclerView =(RecyclerView)view.findViewById(R.id.recycler_view);
    latestAdapter = new LatestAdapter(getContext(),latestItems);
    final LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setAdapter(latestAdapter);

    fetchIntialPost();
} 

private void fetchIntialPost() {
    //here I make API call in another class,which is all API calling method in that class 
    ApiHelper apiHelper = new ApiHelper();
    apiHelper.fetchIntialPost();
}

Here my ApiHelper (This class contains all the API calling method using Volley )

public class ApiHelper {
   public void fetchIntialPost(){
        JsonObjectRequest jsonReq = new JsonObjectRequest(Request.Method.GET, MY_URL ,null, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Log.d("Volley response 123",response.toString()); 

                //here I parse the response in another class
                //this class only doing JSON parsing operation 

                ItemHelper itemHelper = new ItemHelper();
                itemHelper.parseItemJsonFeed(response);
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                //  VolleyLog.d(AppController.TAG, "Error: " + error.getMessage());
            }
        }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {

                Map<String,String> headers = new HashMap<>();
                Context applicationContext = MainActivity.getContextOfApplication();

                SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext);
                String apiKey = preferences.getString("apiKey","");
                headers.put("Content-Type", "application/json");
                headers.put("authorization",apiKey);
                return  headers;
            }
        };

        // Adding request to volley request queue
        AppController.getInstance().addToRequestQueue(jsonReq);
}


}

Here is my ItemHelper class (The class only using to JSON parsing)

public class ItemHelper {
private List<Item> items = new ArrayList<>();

public List<tItem> getList() {
    return items;
}

public void parseItemJsonFeed (JSONObject response){

    try {

        JSONObject jObj = response.getJSONObject("return_data");

        //here parsing all the data from the response 
        ******      

        //After all the parsing,I save it to the model 
        //here set all the data to the model
        setItemToFeedArrayList(id);

        //****** here is the problem,I can `notifyDataSetChanged()` 
        //*****For the adapter in Fragment Class
        //I cant access from this class here 

        Fragment fragment = new Fragment();
        fragment.getLatestAdapter().notifyDataSetChanged();


    } catch (JSONException e) {
        e.printStackTrace();
    }

}

private void setItemToFeedArrayList(int id ) {
    Item item = new Item();
    item.setId(id);

    //add item to the list
    items.add(item);
}

Problems:

My problems now is,I cant access the LatestAdapter object in my Fragment.class .Therefore I cant call notifyDataSetChanged() after I parsing response Json.

What I tried

I tried to make a method like below in ItemHelper Class :

public List<tItem> getList() {
    return items;
}

In LatestAdapter,I also create a method like this:

public void setItem(List<Item> item) {
  this.latestItems = item;
  notifyDataSetChanged();
}

And then in Fragment.class I access it like this

ItemHelper itemHelper = new ItemHelper();
latestItems = itemHelper.getList();
latestAdapter.setPosts(latestItems);

With what I tried above,the getItemCount() of LatestAdapter still 0,after the API call.

So somebody please give me a hint to solve this problem

,or a better solution for organize all API calling method in 1 class,all JSON parsing operation in 1 class.At the same time can notifyDataSetChanged() for the adapter as well.

Phantômaxx
  • 36,442
  • 21
  • 78
  • 108
ken
  • 1,406
  • 2
  • 25
  • 63
  • Possible duplicate of [Set notifyDataSetChanged() on Recyclerview adapter](https://stackoverflow.com/questions/35147466/set-notifydatasetchanged-on-recyclerview-adapter) – InsaneCat Jun 20 '18 at 07:32
  • @InsaneCat this question I already look at it before I asked my question.I tried the solution,but still didnt solve my problem – ken Jun 20 '18 at 07:33

3 Answers3

1

You should use callbacks like this. I will show you an example :

First you need is a callback interface like this :

public interface CallBackPresenter {
  public void success(DataModel model);

  public void showError(String error);

  public void showLoader();

  public void hideLoader();

}

Now in the Api class where you are calling the api use it like this and pass this interface as a parameter and you can call interface methods like this:

public void apiCall(Parameter parameter,CallBackPresenter callBackPresenter){
  //success method
  callBackPresenter.success(datamodelObject);
  //error
  callBackPresenter.success(error);
}

Now when you will call this method it will look like this:

     //Call the method using the apihelper object
     apiHelper.apiCall(Parameter parameter,new CallBackPresenter() {
        @Override
        public void success(DataModel model) {
            //update recycler view here.
        }

        @Override
        public void showError(String error) {
            //show error here.
        }

        @Override
        public void showLoader() {

        }

        @Override
        public void hideLoader() {

        }
    });

Hope this helps.

Sarthak Gandhi
  • 1,966
  • 1
  • 12
  • 22
  • the third part is it what I should do in Fragment.class?? – ken Jun 20 '18 at 07:51
  • Yes where you are calling the ApiHelperMethod. Plus you can call the interface methods when you feel you have parsed the data successfully. – Sarthak Gandhi Jun 20 '18 at 07:53
  • hey so in third part,how can I set the parameter for the function??can u show me??cause I really no idea on this – ken Jun 20 '18 at 08:03
  • and also,how can I use the `getInstance` ya? cause I tried,it become unresolved in IDE. – ken Jun 20 '18 at 08:05
  • Hi i have edited the answer and you can call the method using the apiHelper object. And regarding parameters you can pass as many parameters in the method but make sure your interface object is the last parameter. – Sarthak Gandhi Jun 20 '18 at 08:09
  • ah..okok..let me try 1st..I let u know again..thanks a lot – ken Jun 20 '18 at 08:11
0

Change your architecture it is not correct. Or else if you don't want to change .you can try this way:

public void setDataList(List<RealmSave_Data> dataList) {
        this.dataList = dataList;
    }

This method in adapter and call the method from where you want to call, also pass this list in constructor as it will be initialized in getCount() it will return the value.

0

You can use callbacks as everyone mentioned. You can also use RxAndroid to do the job with ore control.

If you found Rx abnormal or hard to understand, you can use an event bus (in fact event buses are somehow known as an anti-pattern but still you can use them).

A good implementation of event bus is RxBus, also you can use SimpleEventBus which is another event bus based on Rx that generates meaningful methods which might be so easy to understand.

Amin
  • 2,169
  • 1
  • 14
  • 27