Adapter ListView not refreshing from Activity

298 views Asked by At

I am trying to refresh the contents of my Fragment's ListView ... based on the results I receive in my Activity.

  • What I want - To load contents of 'artistsName' List (present in my Activity) into the ListView of my Fragment
  • What is the problem - Despite calling notifyDataSetChanged() on my fragment's reference.... list view does NOT reload/ refresh. Note call to Fragment in the 'queryArtists' method
  • Steps followed - I have tried verifying the fragment reference. It is NOT null.

Any help is really appreciated !

Following is the code:

MainActivity: package com.example.deep.musico;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;

import kaaes.spotify.webapi.android.SpotifyApi;
import kaaes.spotify.webapi.android.SpotifyService;
import kaaes.spotify.webapi.android.models.Artist;
import kaaes.spotify.webapi.android.models.ArtistsPager;
import kaaes.spotify.webapi.android.models.Pager;


public class MainActivity extends ActionBarActivity {

    Intent intent;
    private static final String MAINFRAGMENT_TAG = "MFTAG";
    private static final String LOGTAG = "MainActivity";
    MainActivityFragment mainActivityFragment;

    List<String> artistsName = new ArrayList<String>();
    List<String> spotifyId = new ArrayList<String>();
    List<String> artistImageURL = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

//        mainActivityFragment = new MainActivityFragment();
        getSupportFragmentManager().beginTransaction().replace(R.id.artists_detail_container, new MainActivityFragment(), MAINFRAGMENT_TAG).commit();

        queryArtists(getIntent());
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        queryArtists(intent);
    }

    private void queryArtists(Intent intent){

        this.intent = intent;

        if(Intent.ACTION_SEARCH.equals(intent.getAction())) {

            String queryString = intent.getStringExtra(SearchManager.QUERY).replace(" ", "+");

            QueryArtistsFromSpotify queryArtistsFromSpotify = new QueryArtistsFromSpotify(this);
            queryArtistsFromSpotify.execute(queryString);

            Log.v(LOGTAG, "Getting fragment reference");
            mainActivityFragment = (MainActivityFragment) getSupportFragmentManager().findFragmentByTag(MAINFRAGMENT_TAG);
            if(mainActivityFragment == null) { Log.v(LOGTAG, "Fragment reference is null"); }
            else {
                Log.v(LOGTAG, "Fragment reference is NOT null");
//            mainActivityFragment.artists = artistsName.toArray(new String[artistsName.size()]);
                ((ArrayAdapter<String>) mainActivityFragment.getListAdapter()).clear();
                ((ArrayAdapter<String>) mainActivityFragment.getListAdapter()).addAll(artistsName);
                ((ArrayAdapter<String>) mainActivityFragment.getListAdapter()).notifyDataSetChanged();
//            mainActivityFragment.artistsAdapter.addAll(artistsName);
//            mainActivityFragment.artistsAdapter.notifyDataSetChanged();
            }
        }
    }

    private class QueryArtistsFromSpotify extends AsyncTask<String, Void, ArtistsPager> {

        Context context;

        public QueryArtistsFromSpotify(Context context) {
            this.context = context;
        }

        @Override
        protected ArtistsPager doInBackground(String... params) {

            SpotifyApi spotifyApi = new SpotifyApi();
            SpotifyService spotifyService = spotifyApi.getService();
            ArtistsPager artistsPager = spotifyService.searchArtists(params[0]);

            return artistsPager;

        }

        @Override
        protected void onPostExecute(ArtistsPager artistsPager) {
            //super.onPostExecute(artistsPager);

            List<Artist> artistsList = artistsPager.artists.items;
            Iterator<Artist> iterator = artistsList.iterator();

            while(iterator.hasNext()){

                Artist artist = iterator.next();

                artistsName.add(artist.id);
                spotifyId.add(artist.id);

                Log.v(LOGTAG, artist.id);
                Log.v(LOGTAG, artist.name);

                if(artist.images.size() == 0 ) {

                    artistImageURL.add("");

                } else if(artist.images.size() > 0 ) {

                    artistImageURL.add(artist.images.get(artist.images.size() - 1).toString());
                    Log.v(LOGTAG, artist.images.get(artist.images.size() - 1).toString());
                }
            }
        }
    }
}

MainActivityFragment: package com.example.deep.musico;

import android.app.Fragment;

import android.app.SearchManager;
import android.content.Context;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * A placeholder fragment containing a simple view.
 */
public class MainActivityFragment extends ListFragment {

    SearchView searchView;
    ListView listView;
    ArtistsAdapter artistsAdapter;

/*    String[] items = new String[]{"Today - Sunny - 88/63", "Tomorrow - Foggy - 88/63",
            "Wednesday - Cloudy - 88/63", "Thursday - Rainy - 88/63", "Friday - Sunny - 88/63"};*/

    String[] artists  = new String[]{};


    public MainActivityFragment() {
    }

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

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) rootView.findViewById(R.id.artistsSearchView);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));

        /*ArrayAdapter<String> artistsAdapter = new ArrayAdapter<String>(getActivity(),
                R.layout.artists_view, R.id.artistNameTextView, items);*/

        artistsAdapter = new ArtistsAdapter(getActivity(), R.layout.artists_view, R.id.artistNameTextView, new ArrayList<String>(Arrays.asList(artists)));

        setListAdapter(artistsAdapter);

        return rootView;
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {

        Intent intent = new Intent(getActivity(), SongsActivity.class);
        startActivity(intent);
//        super.onListItemClick(l, v, position, id);
    }

    class ArtistsAdapter extends ArrayAdapter<String> {

        Context context;

        public ArtistsAdapter(Context context, int resource, int textViewResource, ArrayList<String> items) {

            super(context, resource, textViewResource, items);
            this.context = context;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

//            return super.getView(position, convertView, parent);
//            View view = LayoutInflater.from(context).inflate(R.layout.artists_view, parent, false);

            LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View view = layoutInflater.inflate(R.layout.artists_view, parent, false);
            ImageView imageView = (ImageView) view.findViewById(R.id.artistsNameImageView);
            TextView textView = (TextView) view.findViewById(R.id.artistNameTextView);

            imageView.setImageResource(R.drawable.button_blank_blue_01);

            if(artists.length > 0) {
                textView.setText(artists[position]);
            }

            return view;
        }
    }
}
1

There are 1 answers

1
Kingfisher Phuoc On BEST ANSWER

Yeah, look at your code, of course, the data in your fragment is empty. Why?

QueryArtistsFromSpotify queryArtistsFromSpotify = new QueryArtistsFromSpotify(this);
queryArtistsFromSpotify.execute(queryString);

--> this 2 lines will be run off UI thread which means that it runs on another thread. We can see that you change data right after the thread started --> the result is empty data. If you want to show data retrieved in QueryArtistsFromSpotify you must show after the thread finished! --> you must notify in onPostExecute.