我正在尝试将从网络服务获得的数据放入自定义适配器以显示在我的网格中,问题是下载需要一些时间才能完成异步调用,所以当我尝试设置适配器数组时数据(本例中为电影)为空。
继承我的活动:
package com.movieposter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.GridView;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private final String API = "***";
private Movie[] movies;
private GridView grid;
private ImageAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
grid = (GridView) findViewById(R.id.grid_view);
getMovies();
ImageAdapter adapter = new ImageAdapter(this, movies);
grid.setAdapter(adapter);
}
public void getMovies(){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=**")
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
String json = response.body().string();
if (response.isSuccessful()) {
try {
Log.i("teste", response.body().string());
movies = parseMovie(json);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
private Movie[] parseMovie(String json) throws JSONException {
JSONObject jsonMovie = new JSONObject(json);
JSONArray data = jsonMovie.getJSONArray("results");
Movie[] movies = new Movie[data.length()];
for(int i = 0; i < data.length(); i++ ){
JSONObject jsonObject = data.getJSONObject(i);
Movie movie = new Movie();
movie.setOverview(jsonObject.getString("overview"));
movie.setRating(jsonObject.getDouble("vote_average"));
movie.setReleaseDate(jsonObject.getString("release_date"));
movie.setTitle(jsonObject.getString("title"));
movie.setThumbnail("http://image.tmdb.org/t/p/w185/" + jsonObject.getString("poster_path"));
movies[i] = movie;
}
return movies;
}
}
我的适配器
package com.movieposter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
public class ImageAdapter extends BaseAdapter {
private Context mContext;
Movie[] movies;
public ImageAdapter(Context c, Movie[] movies) {
mContext = c;
this.movies = movies;
}
public int getCount() {
return movies.length;
}
public Object getItem(int position) {
return movies[position];
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
Picasso.with(mContext).load(movies[position].getThumbnail()).into(imageView);
return imageView;
}
}
我尝试在onResponse方法中设置适配器,但这不起作用,如果您不知道数据何时完成,那么将数据从webservices加载到apater中的最佳方法是什么?是否可以设置空适配器,然后在数据准备好后更换内容?是这样,怎么样?
答案 0 :(得分:1)
是否可以设置空适配器,然后在数据准备好后更换内容?是这样,怎么样?
你自己回答了你的问题。对的,这是可能的。首先,您应该考虑使用List<Movie>
而不是数组Movie[]
,因为您可能不知道将要获得的电影数量。
这有两种方法
您可以使用空List<Movies> movies
初始化适配器,只显示列表,然后在onResponse中附加List<Movies> movies
您获得的新数据,然后全部{{1}你的适配器。
如果您只需要在最初隐藏notifyDataSetChanged()
后拨打该服务,并在ListView
中使用数据初始化onResponse
,请将其附加到适配器并使列表可见。在此之前,您可以显示加载微调器或其他东西。
要进行快速测试,请在adaptor
:
onResponse
答案 1 :(得分:1)
您必须使用List而不是数组来存储Objects。因为数据结构应该是动态的(你永远不知道有多少电影......)。
List<Movie> movies = new ArrayList<Movie>();// First keep this empty.
然后,
if (response.isSuccessful()) {
try {
Log.i("teste", response.body().string());
movies.clear();// Do not re assign
movies.addAll(parseMovie(json)); // just clear and add new movies
adapter.notifyDataSetChanged(); //add this
} catch (Exception e) {
e.printStackTrace();
}
}