I am facing a problem with parsing JSON using Retrofit.
This is my JSON:
{
"page": 1,
"limit": 10,
"explicit": false,
"has_more": true,
"list": [
{
"id": "x4wqlq6",
"title": "Xavier Mignot : « Il nous manque toujours des points »",
"created_time": 1476019523,
"thumbnail_medium_url": "http://s2.dmcdn.net/c2Vct/160x120-gDr.jpg"
},
{
"id": "x4wq5k7",
"title": "David Mélé : « Cette victoire fait du bien dans les têtes de tout le monde »",
"created_time": 1476001049,
"thumbnail_medium_url": "http://s1.dmcdn.net/c2CqJ/160x120-Aj4.jpg"
},
…
]
}
I would like to display the title, the id, and the link.
My Video model:
public class Video {
@SerializedName("list")
@Expose
private List list;
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public class List {
@SerializedName("id")
@Expose
private String id;
@SerializedName("title")
@Expose
private String title;
@SerializedName("created_time")
@Expose
private String created_time;
@SerializedName("thumbnail_medium_url")
@Expose
private String thumbnail_medium_url;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title; }
public String getCreated_time() {
return created_time;
}
public void setCreated_time(String created_time) {
this.created_time = created_time;
}
public String getThumbnail_medium_url() {
return thumbnail_medium_url;
}
public void setThumbnail_medium_url(String thumbnail_medium_url) {
this.thumbnail_medium_url = thumbnail_medium_url;
}
}
}
Here is the main class:
public class Videos extends MainActivity{
private ListView listView;
private View parentView;
private ArrayList<Video> videoList;
private CustomListViewAdapterV adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_videos);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
videoList = new ArrayList<>();
parentView = findViewById(R.id.parentLayout);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
listView = (ListView) findViewById(R.id.list1);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Snackbar.make(parentView, videoList.get(position) + " => " + videoList.get(position), Snackbar.LENGTH_LONG).show();
// a revoirr
/*String url = alist.get(position).getThumbnail_medium_url();
Intent i = new Intent(Videos.this, daylimotion.class);
i.putExtra("url", url);
startActivity(i);*/
}
});
Toast toast = Toast.makeText(getApplicationContext(), R.string.string_click_to_load, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
assert fab != null;
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(@NonNull final View view) {
/**
* Checking Internet Connection
*/
if (InternetConnection.isNetworkAvailable(getApplicationContext())) {
final ProgressDialog dialog;
/**
* Progress Dialog for User Interaction
*/
dialog = new ProgressDialog(Videos.this);
dialog.setTitle(getString(R.string.string_getting_json_title));
dialog.setMessage(getString(R.string.string_getting_json_message));
dialog.show();
//Creating an object of our api interface
ApiInterface api = ApiClientV.getApiInterface();
/**
* Calling JSON
*/
Call<VideoList> call = api.getJsn();
/**
* Enqueue Callback will be call when get response...
*/
call.enqueue(new Callback<VideoList>() {
@Override
public void onResponse(Call<VideoList> call, Response<VideoList> response) {
//Dismiss Dialog
dialog.dismiss();
if(response.isSuccessful()) {
/**
* Got Successfully
*/
videoList = response.body().getList();
/**
* Binding that List to Adapter
*/
adapter = new CustomListViewAdapterV(Videos.this, videoList);
listView.setAdapter(adapter);
} else {
Snackbar.make(parentView, R.string.string_some_thing_wrong, Snackbar.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<VideoList> call, Throwable t) {
dialog.dismiss();
}
});
} else {
Snackbar.make(parentView, R.string.string_internet_connection_not_available, Snackbar.LENGTH_LONG).show();
}
}
});
This is the VideoList
class. It's for calling JSON. It's using in the videos ( the main):
public class VideoList {
@SerializedName("list")
@Expose
private ArrayList<Video> list = new ArrayList<>();
public ArrayList<Video> getList() {
return list;
}
}
After we found the adapter, the application hung in this part of codes. Exactly in vh.textViewTitle.setText(item.getList().getTitle())
this variable still null :(
public class CustomListViewAdapterV extends ArrayAdapter<Video> {
List<Video> videoList;
Context context;
private LayoutInflater mInflater;
// Constructors
public CustomListViewAdapterV(Context context, ArrayList<Video> objects) {
super(context, 0, objects);
this.context = context;
this.mInflater = LayoutInflater.from(context);
videoList = objects;
}
@Override
public Video getItem(int position) {
return videoList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder vh;
if (convertView == null) {
View view = mInflater.inflate(R.layout.list_item_videos, parent, false);
vh = ViewHolder.create((RelativeLayout) view);
view.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
Video item = getItem(position);
vh.textViewTitle.setText(item.getList().getTitle());
vh.textViewCreated_time.setText(item.getList().getCreated_time());
vh.textViewId.setText(item.getList().getId());
Picasso.with(context).load(item.getList().getThumbnail_medium_url()).placeholder(R.mipmap.ic_launcher).error(R.mipmap.ic_launcher).into(vh.imageView);
return vh.rootView;
}
private static class ViewHolder {
public final RelativeLayout rootView;
public final ImageView imageView;
public final TextView textViewTitle;
public final TextView textViewCreated_time;
public final TextView textViewId;
private ViewHolder(RelativeLayout rootView, ImageView imageView, TextView textViewTitle, TextView textViewCreated_time, TextView textViewId) {
this.rootView = rootView;
this.imageView = imageView;
this.textViewTitle = textViewTitle;
this.textViewCreated_time = textViewCreated_time;
this.textViewId = textViewId;
}
public static ViewHolder create(RelativeLayout rootView) {
ImageView imageView = (ImageView) rootView.findViewById(R.id.imageView);
TextView textViewTitle = (TextView) rootView.findViewById(R.id.textViewTitle);
TextView textViewCreated_time = (TextView) rootView.findViewById(R.id.textViewCreated_time);
TextView textViewId = (TextView) rootView.findViewById(R.id.textViewId);
return new ViewHolder(rootView, imageView, textViewCreated_time, textViewTitle, textViewId);
}
}
}
Could someone please help explain why the application is hanging?
Your JSON object is not correct. The Video class should not have a list, that should represent the items within the list only.
Video.class
public class Video {
@SerializedName("id")
@Expose
private String id;
@SerializedName("title")
@Expose
private String title;
@SerializedName("created_time")
@Expose
private String created_time;
@SerializedName("thumbnail_medium_url")
@Expose
private String thumbnail_medium_url;
}
VideoList.class
public class VideoList {
// TODO: Add "page", "limit", "explicit", "hasMore"
@SerializedName("list")
@Expose
private ArrayList<Video> list = new ArrayList<>();
public ArrayList<Video> getList() {
return list;
}
}
I don't see anything obvious that would cause it to hang, You'll need to set some breakpoints and step through the code.
One suggestion, that has nothing to do with your problem. I'd move the adapter creation and assignment to the ListView outside of the callback.
Put it directly under the listView assignment and inside the callback, just set the data in the already defined arrayList and call notifyDataSetChanged on the adapter. This is much more efficient than recreating the adapter each time you get a new dataset.
listView = (ListView) findViewById(R.id.list1);
// Move the two lines below under this line.
adapter = new CustomListViewAdapterV(Videos.this, videoList);
listView.setAdapter(adapter);
And inside the callback, add this:
// Puts the data in the array, this is already there..
videoList = response.body().getList();
// Notify that the list has changed and redraw the screen.
adapter.notifiyDataSetChanged();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.