Search code examples
javaandroidandroid-listviewandroid-asynctasksearchview

Update ListView on SearchView.onQueryTextSubmit() and AsyncTask


So when I search summonerName then submit it I create new FetchMatchListTask extends AsyncTask where I send summonerName and then load all his matches to ListView and it works, but when user search different name I want to reload ListView. This is my code:

public class MatchListActivity extends MenuActivity {

    private TextView numOfGamesText;
    int matchLimitCounter = 0;
    CircularImageView circularImageView;
    TextView summNameTv;
    TextView soloDuoQue;
    TextView summLvl;
    SearchView mySearchView;

    MatchListAdapter adapter;
    ListView matchList;
    ArrayList<MatchDetails> matchArrayList = new ArrayList<>();

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

        matchLimitCounter = 0;
        numOfGamesText = findViewById(R.id.txtNumOfGames);
        matchList = findViewById(R.id.matchListView);
        circularImageView = findViewById(R.id.summonerProfileIcon);
        summNameTv = findViewById(R.id.summonerName);
        soloDuoQue = findViewById(R.id.soloDuoQue);
        summLvl = findViewById(R.id.summLevel);
        mySearchView = findViewById(R.id.searchView);

        adapter = new MatchListAdapter(this, R.layout.match_adapter, matchArrayList);
        matchList.setAdapter(adapter);

        mySearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String summName) {
                Toast toast = Toast.makeText(MatchListActivity.this, "Wait a few seconds for loading...", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
                if(summName.isEmpty()){
                    Toast.makeText(MatchListActivity.this, "Enter summoner name!", Toast.LENGTH_LONG);
                }else {
                    FetchMatchListTask summonerTask = new FetchMatchListTask();
                    summonerTask.execute(summName);
                }
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                return false;
            }
        });

    }

    class Wrapper
    {
        Summoner summoner;
        RiotApi api;
        MatchList matchList;
        Match match;
        Participant participant;
        ParticipantStats stats;
    }

    @SuppressLint("StaticFieldLeak")
    public class FetchMatchListTask extends AsyncTask<String, Void, Wrapper> {

        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected Wrapper doInBackground(String... params) {

            ApiConfig config = new ApiConfig().setKey("API-KEY");
            Wrapper w = new Wrapper();
            w.api = new RiotApi(config);
            Platform platform;

            try {
                w.summoner = w.api.getSummonerByName(Platform.EUNE, params[0]);
                w.matchList = w.api.getMatchListByAccountId(platform, w.summoner.getAccountId());

                if (w.matchList.getMatches() != null) {
                    for (MatchReference matchRef: w.matchList.getMatches()) {
                        if(matchLimitCounter == 10) break;
                        else{
                            matchLimitCounter++;

                            long gameID = matchRef.getGameId();
                            w.match = w.api.getMatch(platform, gameID);
                            long gameDuration = w.match.getGameDuration();
                            int champKey = matchRef.getChampion();

                            MatchDetails matchDetails = new MatchDetails(champKey);
                            matchArrayList.add(matchDetails);
                        }
                    }
                }

                return w;
            } catch (RiotApiException e) {
                Log.d("RiotMSG", "Error: "+ RiotApiException.getMessage(e.getErrorCode()));
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Wrapper wrapp) {
            super.onPostExecute(wrapp);
            if(wrapp != null) {
                numOfGamesText.setText(String.valueOf(wrapp.matchList.getTotalGames()));
                summNameTv.setText(wrapp.summoner.getName());
                summLvl.setText(String.valueOf(wrapp.summoner.getSummonerLevel())+" LvL");

            }

            //Not working
            //((MatchListAdapter) matchList.getAdapter()).notifyDataSetChanged();

            if (wrapp == null) { throw new NullPointerException("wrapp object is null, means smth go wrong doInBack"); }
        }
    }
}

I tried to use this in onPostExecute, nothing works:

MatchListActivity.this.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        adapter.notifyDataSetChanged();
    }
});

adapter.notifyDataSetChanged();

((MatchListAdapter) matchList.getAdapter()).notifyDataSetChanged();

ADDED MatchListAdapter

public class MatchListAdapter extends ArrayAdapter<MatchDetails> {

private Context mContext;
private int mResource;
private ArrayList<MatchDetails> myMatchList; // added with updateMyMatchList

MatchListAdapter(Context context, int resource, ArrayList<MatchDetails> objects){
    super(context, resource, objects);
    mContext = context;
    mResource = resource;
    myMatchList = objects;  // added with updateMyMatchList
}

//Method to change list but not working
 public void updateMyMatchList(ArrayList<MatchDetails> objects){
    myMatchList.clear();
    myMatchList.addAll(objects);
    this.notifyDataSetChanged();
}

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

    LayoutInflater inflater = LayoutInflater.from(mContext);
    convertView = inflater.inflate(mResource, parent, false);

    //Get the champion information and other stuff...
    int champKey = getItem(position).getChampionKey();
    chamKeyTextView.setText(champKey);
}}

Solution

  • So what i have to do is: add matchLimitCounter = 0; matchArrayList.clear(); before execution of AsynTask excatly like "i_A_mok" asnwered. Then i use in onPostExecute():

    adapter.updateMyMatchList(matchArrayList);
    

    and in in MatchListAdapter i declare ArrayList myMatchList and:

    updateMyMatchList(ArrayList<MatchDetails> objects){
         myMatchList.addAll(objects);
         this.notifyDataSetChanged();
    }
    

    and in getView():

    MatchDetails d = myMatchList.get(position);
    int champKey = d.getChampionKey();
    ...