AsyncTask не обновляет интерфейс - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть приложение, в котором я получаю плакаты mov ie из API в AsyncTask . Мне нужно отобразить top_rated и популярные фильмы. Таким образом, в моем меню опций популярно и с самым высоким рейтингом . При открытии приложения оно загружает (20) популярных фильмов через AsyncTask. Теперь проблема в том, чтобы выбрать один из популярных или самых популярных в моем меню опций, он добавляет вновь извлеченные (20) постеры к уже (20) в пользовательском интерфейсе (теперь это 40 фильмов) вместо того, чтобы убрать те, что на экран и замена на новые извлеченные 20 плакатов mov ie.

Я попытался вызвать notifyDataSetChanged() на адаптере. Кроме того, я попытался вызвать новый AsyncTask для каждого выбранного параметра, ни один не работал. Я пробовал опции в этой теме , но безрезультатно.

Вот мой код:

package com.quwaysim.popularmovies.ui;

import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.quwaysim.popularmovies.MovieAdapter;
import com.quwaysim.popularmovies.R;
import com.quwaysim.popularmovies.model.MovieDetails;
import com.quwaysim.popularmovies.utils.NetworkUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    RecyclerView mRecyclerView;
    MovieAdapter mAdapter;
    ArrayList<MovieDetails> mMovieList = new ArrayList<>();

    ProgressBar mProgressBar;
    String api = "popular";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mProgressBar = findViewById(R.id.progressBar);
        mRecyclerView = findViewById(R.id.movies_rv);

        fetchMovies(api);
    }

    public void fetchMovies(String api) {
        URL apiURL = NetworkUtils.buildUrl(api);
        new FetchMovie().execute(apiURL);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.sort_menu, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.popular:
                Toast.makeText(this, "Popular", Toast.LENGTH_SHORT).show();

                // Trying my options here
                URL popular = NetworkUtils.buildUrl("popular");
                new FetchMovie().execute(popular);
                mAdapter.notifyDataSetChanged();
                return true;
            case R.id.top_rated:
                Toast.makeText(this, "Top Rated", Toast.LENGTH_SHORT).show();

                // Trying my options here
                URL topRated = NetworkUtils.buildUrl("top_rated");
                new FetchMovie().execute(topRated);
                mAdapter.notifyDataSetChanged();
                return true;
            default:
                return super.onOptionsItemSelected(item);

        }
    }



    public class FetchMovie extends AsyncTask<URL, Void, String> {
        private final String TAG = "FetchMovieAsyncTask";

        private int mNoOfMovies;

        @Override
        protected void onPreExecute() {
            mProgressBar.setVisibility(View.VISIBLE);
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(URL... urls) {
            URL url = urls[0];
            String movieResults = null;
            try {
                movieResults = NetworkUtils.getResponseFromUrl(url);
            } catch (IOException e) {
                Log.d(TAG, "doInBackground: " + e);
            }
            return movieResults;
        }

        @Override
        protected void onPostExecute(String s) {
            if (s != null && !s.equals("")) {
                mProgressBar.setVisibility(View.INVISIBLE);
                try {
                    JSONObject parsedMoviesJSON = new JSONObject(s);
                    JSONArray moviesArray = parsedMoviesJSON.getJSONArray("results");

                    mNoOfMovies = moviesArray.length();
                    moviesArray.getString(1);
                    for (int i = 0; i < mNoOfMovies; i++) {
                        MovieDetails mMovDetails = new MovieDetails();
                        String details = moviesArray.get(i).toString();
                        JSONObject detailsParsed = new JSONObject(details);
                        mMovDetails.setMoviePoster("http://image.tmdb.org/t/p/w185/"
                                + detailsParsed.getString("poster_path"));
                        mMovieList.add(mMovDetails);

                        Log.d(TAG, "onPostExecute: forLoop" + mMovDetails.getMoviePoster());
                    }
                } catch (JSONException e) {
                    Log.d(TAG, "onPostExecute: error => " + e);
                    e.printStackTrace();
                }
                Log.d("TAG", "onPostExecute: movieList" + mMovieList);
                mAdapter = new MovieAdapter(mMovieList);
                mRecyclerView.setLayoutManager(new GridLayoutManager(MainActivity.this, 2));
                mRecyclerView.setAdapter(mAdapter);

                Log.d(TAG, "onPostExecute: it's a success " + mNoOfMovies);
            }
        }
    }
}

Класс NetworkUtils предназначен только для Открытие соединения и создание полного URL API. Я не включил это здесь, потому что я хочу сделать этот пост максимально коротким. Пожалуйста, дайте мне знать, если вам что-нибудь нужно. Заранее спасибо.

1 Ответ

1 голос
/ 16 апреля 2020

Да, это происходит потому, что вы используете и включаете один и тот же объект списка, вы должны создать новый список, прежде чем использовать его в onPostExecute (). Добавьте это:

mMovieList = new ArrayList<>();

непосредственно над для l * 1008. * вот так:

//create a new list for each query
mMovieList = new ArrayList<>();

for (int i = 0; i < mNoOfMovies; i++) {

MovieDetails mMovDetails = new MovieDetails();
String details = moviesArray.get(i).toString();
....
....
....

GoodLuck.

...