好的,到目前为止,这个简单应用程序的MainActivity如下所示:
public class MainActivity extends AppCompatActivity {
ListView moviesListView;
ArrayList <Movie> moviesList;
MoviesAdapter moviesAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
moviesListView = (ListView) findViewById(R.id.moviesListView);
moviesList = new ArrayList<Movie>();
runProgram();
moviesAdapter = new MoviesAdapter(getApplicationContext(), R.layout.movies_layout, moviesList);
moviesListView.setAdapter(moviesAdapter);
}
private void runProgram() {
String url = "https://api.themoviedb.org/3/" +
"discover/movie?primary_release_date.gte=2016-02-01&primary_release_date.lte=2016-02-18" +
"&api_key=...............................";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
getMovies(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
}
private void getMovies(JSONObject response) {
JSONArray jsonArray = null;
String imageBaseURL = "http://image.tmdb.org/t/p/w500";
try {
jsonArray = response.getJSONArray("results");
for (int i = 0; i < 5; i++){
Movie movie = new Movie(jsonArray.getJSONObject(i).getString("title"),
jsonArray.getJSONObject(i).getString("overview"),
imageBaseURL + jsonArray.getJSONObject(i).getString("poster_path")
+ "?&api_key=6b54bd769063ac68b99fac57aa334eae");
moviesList.add(movie);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
我在这里尝试做的是从TMDB请求电影,并在ListView中显示它们。但我的问题是,第一次运行该应用程序时,它不显示任何内容,您只会看到白屏。现在,如果您尝试再次运行它,它将在列表视图中显示电影。但是,如果您清除应用程序的缓存并尝试再次运行它,您将再次看到白屏......我真的很困惑这里发生了什么。我试过调试它,似乎它获取数据的速度非常快,所以之后发生的一切都会发生。
另外,这是我的适配器的代码,以防万一:
public class MoviesAdapter extends ArrayAdapter<Movie> {
ArrayList<Movie> moviesList;
int adapterResource;
Context adapterContext;
LayoutInflater layoutInflator;
public MoviesAdapter(Context context, int resource, ArrayList<Movie> objects) {
super(context, resource, objects);
moviesList = objects;
adapterResource = resource;
adapterContext = context;
layoutInflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null){
convertView = layoutInflator.inflate(adapterResource, null);
viewHolder = new ViewHolder();
viewHolder.movieImage = (ImageView) convertView.findViewById(R.id.movieImage);
viewHolder.movieName = (TextView) convertView.findViewById(R.id.movieName);
viewHolder.movieOverview = (TextView) convertView.findViewById(R.id.movieOverview);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
new DownloadImageTask(viewHolder.movieImage).execute(moviesList.get(position).getImageURL());
viewHolder.movieName.setText(moviesList.get(position).getName());
viewHolder.movieOverview.setText(moviesList.get(position).getOverview());
return convertView;
}
public static class ViewHolder{
public ImageView movieImage;
public TextView movieName;
public TextView movieOverview;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception ex) {
Log.e("Error", ex.getMessage());
ex.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
任何帮助将不胜感激。
每次调用getView()
时,您都会启动一个新的 DownloadTask。这是完全错误的,因为相同的图像可能已经下载/正在下载
使用通用图像加载器或毕加索:
取而代之的是:
new DownloadImageTask(viewHolder.movieImage).execute(moviesList.get(position).getImageURL());
用:
Picasso.with(context)
.load(moviesList.get(position).getImageURL())
.into(viewHolder.movieImage);
此外,您的getMovies()
函数似乎在主线程上执行。由于您在此处解析 JSON,因此请使用AsyncTask
将其移动到后台线程
第三,做完getMovies(response);
后,需要打电话给notifyDataSetChange()
moviesAdapter