【发布时间】:2020-04-28 05:00:23
【问题描述】:
我正在制作一个简单的应用程序,它必须调用一个 API,该 API 返回一个具有某些属性的对象并显示在 RecyclerView 中。
正在呼叫https://jsonplaceholder.typicode.com/photos?_start=0&_limit=5
应用程序没有崩溃,正在生成 recyclerview 但它是空的。使用调试器,看到recyclerview的adapter中的list是空的(大小为0)。
我认为问题出在我创建的 java 对象的结构上,但我无法确定,而且我似乎无法修改我的对象结构以匹配返回对象的结构。我没有看到一个包含其他对象的对象,就像我使用过的其他 api 一样(当我使用 json 在线阅读器检查上述链接时)。
我通常制作我的对象和另一个对象容器(其中包含第一个对象的列表)。我的怀疑是问题在那里,请帮助我找到问题。 下面主要是activity、object、object container、adapter、retrofit object、object dao和object controller。
活动:
public class PhotoActivity extends AppCompatActivity implements AdapterPhotoRecyclerView.SelectedPhotoListener {
private AdapterPhotoRecyclerView adapterPhotoRecyclerView;
private RecyclerView recyclerView;
private ProgressBar progressBar;
private LinearLayoutManager linearLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo);
linearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
progressBar = findViewById(R.id.photo_activity_progress_bar);
makeCall("photos?_start=0&_limit=5");
adapterPhotoRecyclerView = new AdapterPhotoRecyclerView(this);
recyclerView = findViewById(R.id.photo_activity_recyclerview);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapterPhotoRecyclerView);
}
public void makeCall(String fixedUrl) {
MyPhotoController myPhotoController = new MyPhotoController();
myPhotoController.getPhotos(fixedUrl, new ResultListener<MyPhotoContainer>() {
@Override
public void finish(MyPhotoContainer result) {
progressBar.setVisibility(View.VISIBLE);
adapterPhotoRecyclerView.setMyPhotoList(result.getmPhotoList());
progressBar.setVisibility(View.GONE);
}
});
}
@Override
public void selectePhoto(Integer position, List<MyPhoto> myPhotoList) {
MyPhoto clickedPhoto = myPhotoList.get(position);
Toast.makeText(this, clickedPhoto.getTitle(), Toast.LENGTH_SHORT).show();
}
}
RecyclerView 的适配器
public class AdapterPhotoRecyclerView extends RecyclerView.Adapter<AdapterPhotoRecyclerView.PhotoViewHolder> {
private List<MyPhoto> myPhotoList;
private SelectedPhotoListener selectedPhotoListener;
public AdapterPhotoRecyclerView(SelectedPhotoListener selectedPhotoListener) {
myPhotoList = new ArrayList<>();
this.selectedPhotoListener = selectedPhotoListener;
}
public void setMyPhotoList(List<MyPhoto> myPhotoList) {
this.myPhotoList = myPhotoList;
notifyDataSetChanged();
}
public List<MyPhoto> getMyPhotoList() {
return myPhotoList;
}
@NonNull
@Override
public PhotoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_cell_photo, parent, false);
PhotoViewHolder photoViewHolder = new PhotoViewHolder(view);
return photoViewHolder;
}
@Override
public void onBindViewHolder(@NonNull PhotoViewHolder holder, int position) {
MyPhoto myPhoto = myPhotoList.get(position);
holder.bindPhoto(myPhoto);
}
@Override
public int getItemCount() {
if (myPhotoList == null){
return 0;
} else {
return myPhotoList.size();
}
}
public class PhotoViewHolder extends RecyclerView.ViewHolder {
private ImageView thumbnail;
private TextView title;
public PhotoViewHolder(@NonNull View itemView) {
super(itemView);
this.thumbnail = itemView.findViewById(R.id.recyclerview_cell_photo_thumbnail);
this.title = itemView.findViewById(R.id.recyclerview_cell_photo_title);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
selectedPhotoListener.selectePhoto(getAdapterPosition(), myPhotoList);
}
});
}
public void bindPhoto(MyPhoto myPhoto) {
Glide.with(itemView).load(myPhoto.getThumbnailUrl()).placeholder(R.mipmap.ic_launcher).into(thumbnail);
title.setText(myPhoto.getTitle());
}
}
public interface SelectedPhotoListener {
public void selectePhoto(Integer position, List<MyPhoto> myPhotoList);
}
}
对象道
public class MyPhotoDao extends MyRetrofit {
private JsonPlaceholderService service;
public MyPhotoDao() {
super("https://jsonplaceholder.typicode.com/");
service = retrofit.create(JsonPlaceholderService.class);
}
public void getPhotos(String fixedUrl, final ResultListener<MyPhotoContainer> listenerOfTheController) {
Call<MyPhotoContainer> call = service.jsonPlaceholderPhoto(fixedUrl);
call.enqueue(new Callback<MyPhotoContainer>() {
@Override
public void onResponse(Call<MyPhotoContainer> call, Response<MyPhotoContainer> response) {
MyPhotoContainer myPhotoContainer = response.body();
listenerOfTheController.finish(myPhotoContainer);
}
@Override
public void onFailure(Call<MyPhotoContainer> call, Throwable t) {
}
});
}
public void getAlbum(String fixedUrl, final ResultListener<List<Album>> listenerOfTheController){
Call<List<Album>> call = service.jsonPlaceholderAlbum(fixedUrl);
call.enqueue(new Callback<List<Album>>() {
@Override
public void onResponse(Call<List<Album>> call, Response<List<Album>> response) {
List<Album> albumList = response.body();
listenerOfTheController.finish(albumList);
}
@Override
public void onFailure(Call<List<Album>> call, Throwable t) {
}
});
}
}
对象控制器
public class MyPhotoController {
public void getPhotos(String fixedUrl, final ResultListener<MyPhotoContainer> listenerOfTheView) {
MyPhotoDao myPhotoDao = new MyPhotoDao();
myPhotoDao.getPhotos(fixedUrl, new ResultListener<MyPhotoContainer>() {
@Override
public void finish(MyPhotoContainer result) {
listenerOfTheView.finish(result);
}
});
}
public void getAlbums(String fixedUrl, final ResultListener<List<Album>> listenerOfTheView){
MyPhotoDao myPhotoDao = new MyPhotoDao();
myPhotoDao.getAlbum(fixedUrl, new ResultListener<List<Album>>() {
@Override
public void finish(List<Album> result) {
listenerOfTheView.finish(result);
}
});
}
}
改造对象
public abstract class MyRetrofit {
protected Retrofit retrofit;
public MyRetrofit(String baseUrl) {
OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient.build())
.addConverterFactory(GsonConverterFactory.create());
retrofit = builder.build();
}
}
我正在尝试获取的对象
public class MyPhoto implements Serializable {
@SerializedName("AlbumId")
private Integer albumNumber;
@SerializedName("id")
private Integer photoId;
private String title;
@SerializedName("url")
private String photoUrl;
private String thumbnailUrl;
public Integer getAlbumNumber() {
return albumNumber;
}
public Integer getPhotoId() {
return photoId;
}
public String getTitle() {
return title;
}
public String getPhotoUrl() {
return photoUrl;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
}
对象容器
public class MyPhotoContainer implements Serializable {
@SerializedName("array")
private List<MyPhoto> mPhotoList;
public List<MyPhoto> getmPhotoList() {
return mPhotoList;
}
}
如果有任何遗漏,请告诉我。 任何帮助和 cmets 都非常感谢!
【问题讨论】:
-
您不需要使用
MyPhotoContainer。响应JSON是JSON Array和JSON Objects。getPhotos方法应该类似于getAlbum方法:public void getPhotos(String fixedUrl, final ResultListener<List<MyPhoto>> listenerOfTheView) -
获取相册的调用也不起作用,所以我认为这不是问题。
-
当然,URL 后面的
JSON不适合POJO类。那里没有array属性。 -
所以我应该用
array代替属性List? @MichałZiober -
@MichałZiober 很好..您的答案有效,因此将其添加为响应,以便我将其标记为正确。非常感谢您的帮助!
标签: java android gson retrofit2