Populate ListView on Fragment after Async done from Activity

巧了我就是萌 提交于 2019-12-04 05:04:30

Since you only have two fragments, you can keep track of them saving the instances. Using callbacks as suggested it's not the best option.

So, in your pager adapter:

public class TabsPagerAdapter extends FragmentPagerAdapter {

    SermonsFragment mSermonsFragment;
    MoreFragment mMoreFragment;

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
        this.mSermonsFragment = new SermonsFragment();
        this.mMoreFragment = new MoreFragment();
    }

    @Override
    public Fragment getItem(int index) {
        switch (index) {
            case 0:
                //Sermons fragment activity
                return mSermonsFragment;
            case 1:
                //More fragment activity
                return mMoreFragment;

        }

        return null;
    }

    @Override
    public int getCount() {
        //get item count - equal to number of tabs
        return 2;
    }

    public updateSermonsFragment(String[] data) {
         mSermonsFragment.updateData(data);
    }

    //i don't know what's the data type managed by MoreFragment
    public updateMoreFragment(Object data) {
         mMoreFragment.updateData(data)
    }
}

Create a method to update your adapter in your fragment:

public void updateData(String[] newData) {
    this.listAdapter.clear();
    for(int i = 0; i < newData.length; i++) {
        this.listAdapter.add(newData[i]);
    }
    this.listAdapter.notifyDataSetChanged();
}

Then you can call this method from the onPostExecute of your AsyncTask trought your adapter method:

protected void onPostExecute(JSONObject jsonObject) {
    sermonListJSONObject = jsonObject;
    sermonListJSONArray = 
            parseJSONObjToJSONArray(sermonListJSONObject, JSON_KEY_SERMONS);

    String[] sermonsList;

    .... // here you need set an array with the strings you parsed

    //here you call the new method on the adapter to update your data.
    mAdapter.updateSermonsFragment(sermonsList);
 }

Another best practice it's to define a static newInstace(String[] data) method in your fragment, so you can initialize the fragment data at the very first network call, to be sure your fragment has a dataset to work with then update as described above.

Why do you not call/execute

sermonsList = ((MainActivity)getActivity()).getSermonsList();

in onPostExecute() of the AsyncJob?

onPostExecute is running on UI-Thread - so it should be no problem

There lots of options:

  1. Pass reference of your fragment into AsyncTask and update adapter in the onPostExecute.
  2. Create method in your activity and call it after AsyncTask finished. Inside this method update your fragment.
  3. Execute AsyncTask inside your fragment.

Sample of updating data in your fragment:

public class SermonsFragment extends ListFragment {
  public void update(String[] sermonsList){
    listAdapter.addAll(sermonsList);
    listAdapter.notifyDataSetChanged();
  }
}

This might be of the the topic, but I just ran into a similar handshake error using volley and https urls. Check here for further informations.

Simple check if your connection is refused is to trust all SSL-Certificates. (This should only be used for testing!!).

Run this before your first call (f.e. extend Application and call the following in onCreate)

//trust all SSL
SSLCertificateHandler.nuke();

The Trust-everything-class:

public class SSLCertificateHandler {

protected static final String TAG = "NukeSSLCerts";

public static void nuke() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                X509Certificate[] myTrustedAnchors = new X509Certificate[0];
                return myTrustedAnchors;
            }

            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        } };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception e) {
    }
}

}

onResume() the method that you are populating the listview

It would be nice if i can help you because i have also faced the problem like that...

you want to set adapter which includes the string array provided by your asynctask.

create constructor in TabsPagerAdapter.class .........

  ArrayList<String> arrayList_Tab = new ArrayList<String>();
   ** Constructor of the class */
   public TabsPagerAdapter(FragmentManager fm,
        ArrayList<String> arrayList1) {
    super(fm);
    this.arrayList = arrayList1;
  ................
   @Override
   public Fragment getItem(int index) {
    Bundle data = new Bundle();
    switch (index) {

        case 0:
              SermonsFragment ment = new SermonsFragment ();
        data.putStringArrayList("data", arrayList);
        ment.setArguments(data);
        return ment;

        case 1:
            //More fragment activity
            return new MoreFragment();

    }

    return null;
}

I have done with this arraylist but you can do this with passing array as parameters. in your MainActivity.. add your asynctask data to an arraylist and then pass to TabsPagerAdapter class

  mAdapter = new TabsPagerAdapter(getFragmentManager());

change above to

  mAdapter = new TabsPagerAdapter(getFragmentManager(),ArrayLListgotfromAsyctask);

now get your arraylist at SermonsFragment class as :-

ArrayList<String> arrayList = new ArrayList<String>();

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    arrayList = getArguments().getStringArrayList("data");
}

now you can set arraylist to adapter.

Good luck !!!

public void updateData(String[] newData) {

 this.listAdapter.clear();
 for(int i = 0; i < newData.length; i++) {
    this.listAdapter.add(newData[i]);
 }
 this.listAdapter.notifyDataSetChanged();
}

// call this method in  onPostExecute() method . By calling listAdapter.notifyDataSetChanged(); this adapter is updated with the data which comes from JSON object . 

hope it ll help u :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!