AsyncTask not refreshing UI



我有一个应用程序,在AsyncTask中从API检索电影海报。我需要显示顶级流行电影。因此,我的选项菜单中有热门最受欢迎。打开应用程序后,它会通过AsyncTask加载(20(部热门电影。现在的问题是点击我的选项菜单中的热门或热门海报,它将新获取的(20(张海报添加到UI上已经获取的(40部电影(上,而不是清除屏幕上的海报并替换为新获取的20张电影海报。

我已尝试在适配器上调用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类仅用于打开连接并构建完整的api URL。我没有把它包括在这里,因为我想保持这个帖子尽可能短。如果你需要什么,请告诉我。提前谢谢。

是的,之所以会发生这种情况,是因为您在和上使用相同的列表对象,在onPostExecute((中使用它之前,必须创建一个新列表。添加此:

mMovieList = new ArrayList<>();

在for循环的正上方,如下图所示:

//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();
....
....
....

好运。

最新更新