Masterofawesome
Masterofawesome

Reputation: 69

Updating/Creating Custom Listview on PostExecute inside a Fragment

So I have a Sections Pager Application in Android. On my fourth fragment, I run an asynctask that connects to a device via bluetooth and updates a custom list that I created (supposedly) However, the list either updates late or doesn't update at all. I'm not exactly sure what to do on the postexecute to allow update so I updated it outside of the asynctask.

Code is below:

     public class FourthFragment extends Fragment {
    private WeakReference<getBeacons> getBeaconTaskWeakRef;
    ArrayList<ArtInfo> ArtList = new ArrayList<>();
    ;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        startNewBeaconsAsyncTask();
    }

    ArrayList<String> titles = new ArrayList<>();
    ArrayList<String> artists = new ArrayList<>();
    ArrayList<String> years = new ArrayList<>();
    ArrayList<Integer> images = new ArrayList<>();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        for (int i = 0; i < ArtList.size(); i++) {
            titles.add(ArtList.get(i).getArtTitle());
            artists.add(ArtList.get(i).getArtistName());
            years.add(ArtList.get(i).getYear());
            int resID = getResources().getIdentifier(ArtList.get(i).getImageFilename(), "drawable", "com.acuart.acumen.acuart");
            images.add(resID);
        }
        View v = inflater.inflate(R.layout.frag_list, container, false);
        ListView byTitleList = (ListView) v.findViewById(R.id.byTitleList);
        byTitleList.setAdapter(new titleList(getActivity(), R.layout.custom_list, titles));
        return v;
    }

    private void startNewBeaconsAsyncTask() {
        getBeacons newbeacons = new getBeacons(this);
        this.getBeaconTaskWeakRef = new WeakReference<getBeacons>(newbeacons);
        newbeacons.execute();
    }

    class titleList extends ArrayAdapter<String> {
        public titleList(Context context, int resource, ArrayList<String> objects) {
            super(context, resource, objects);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = ((Activity) getContext()).getLayoutInflater().inflate(R.layout.custom_list, null);
            TextView title = (TextView) v.findViewById(R.id.row_title);
            TextView artist = (TextView) v.findViewById(R.id.row_artist);
            TextView year = (TextView) v.findViewById(R.id.row_year);
            ImageView image = (ImageView) v.findViewById(R.id.row_image);

            title.setText(titles.get(position));
            artist.setText(artists.get(position));
            year.setText(years.get(position));
            image.setBackgroundResource(images.get(position));
            return v;
        }
    }

    private class getBeacons extends AsyncTask<Void, Void, Void> {
        private WeakReference<FourthFragment> fragmentWeakReference;

        private getBeacons(FourthFragment fragment) {
            this.fragmentWeakReference = new WeakReference<FourthFragment>(fragment);
        }

        ProgressDialog dialog = new ProgressDialog(getActivity());
        Context context = getApplicationContext();
        int artCount = 0;
        SQLHelper markerDBHelper = new SQLHelper(context);

        @Override
        protected void onPreExecute() {
            dialog.setMessage("Loading, please wait...");
            dialog.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            checkBluetooth();
        }

        @Override
        protected void onPostExecute(Void v) {
            dialog.dismiss();
        }
    }       //processing bluetooth data and creating a query for database return.
}

Any help/comments/ideas are appreciated.

Upvotes: 0

Views: 187

Answers (3)

App Crazy
App Crazy

Reputation: 46

At First set the ListView adapter as follows:

titleList adapter=new titleList(getActivity(), R.layout.custom_list, titles));
byTitleList.setAdapter(adapter);

After doing the background task if you get an List of "titles", then in "onPostExecute" method you can do the following:-

private class getBeacons extends AsyncTask<Void, Void, ArrayList<String> > {

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

    private getBeacons() {

    }



    @Override
    protected void onPreExecute() {

    }

    @Override
    protected ArrayList<String> doInBackground(Void... params) {

        //call a method for assigning values to titles
        return titles;

    }

    @Override
    protected void onPostExecute(ArrayList<String> titles) {

        //Now assign this arraylist referrence to your actual titles arraylist 

        adapter.notifyDataSetChanged();

    }
}  

Upvotes: 1

markreed49
markreed49

Reputation: 41

Code in onPostExecute() runs on the UI thread, so you should be able to update your list adapter there.

I'm a bit confused by your question, are you saying that it takes a long time for onPostExecute() to run? Did you have your code in there to update the list, and then moved it out because onPostExecute() took too long to be called?

Do you have a bunch of other async tasks running?

I didn't have time to test compile/test this, so there could very well be some syntax mistakes, but this is just to give you an idea

In titleList add a method to update the data backing the adapter list so:

public void updateAdapterData(ArrayList<String> newData) {
    clear();
    addAll(newData);
    notifyDataSetChanged();
}

And the async task could do something like this

private titleList mTitleList; //Set this in your onCreateView

private class getBeacons extends AsyncTask<Void, Void, ArrayList<String>> {

    @Override
    protected void onPreExecute() {
        dialog.setMessage("Loading, please wait...");
        dialog.show();
    }

    @Override
    protected ArrayList<Object> doInBackground(Void... params) {
        //If checkbluetooth returns a list..
        return checkBluetooth();
    }

    @Override
    protected void onPostExecute(ArrayList<String> newList) {
        mTitleList.updateAdapterData(newList)
        dialog.dismiss();
    }
}

Upvotes: 1

Code-Apprentice
Code-Apprentice

Reputation: 83527

You just need to update the ArrayList in your titleList adapter and call notifyDataSetChanged() on the adapter. I suggest doing this with a setList() method in the titleList class. You also need to keep a reference of the adapter where it is accessible by your AsyncTask.

Upvotes: 0

Related Questions