I am getting movie data to my list of movies.
I need to get genres in my DetailActivity with list of movie Genres.
Here is endpoint and docs.
http://docs.themoviedb.apiary.io/#reference/genres/genremovielist/get
I have the right POJO and interface for rest client,as well as MainActivity where i called RestAdapter.
Problem is in my DetailsActivity.I have ListView of genres, and I dont know how to setText to array and call getGenres().
Thank you.
Bellow is my POJO model class:
public class Genres {
private Integer id;
private String name;
/**
*
* #return
* The id
*/
public Integer getId() {
return id;
}
/**
*
* #param id
* The id
*/
public void setId(Integer id) {
this.id = id;
}
/**
*
* #return
* The name
*/
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
public void setName(String name) {
this.name = name;
}
}
Here is my interface:
public interface MoviesApiService {
**#GET("/genre/movie/list")
void getGenreMovies (Callback<Genres> cb);**
}
I called Restadapter in my MainActivity:
private void getGenres() {
RestAdapter.getMovieService().getGenreMovies(new Callback<Genres>() {
#Override
public void success(Genres genres, Response response) {
}
#Override
public void failure(RetrofitError error) {
error.printStackTrace();
}
});
}
And DetailsActiviy:
private Movie mMovie;
private Reviews mReviews;
ImageView backdrop;
ImageView poster;
TextView title;
TextView description;
TextView releaseDate;
TextView voteAverage;
ListView genres;
TextView author;
TextView content;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_detail);
if (getIntent().hasExtra(EXTRA_MOVIE)) {
mMovie = getIntent().getParcelableExtra(EXTRA_MOVIE);
} else {
throw new IllegalArgumentException("Detail activity must receive a movie parcelable");
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
CollapsingToolbarLayout toolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbar_layout);
toolbarLayout.setTitle(mMovie.getTitle());
backdrop = (ImageView) findViewById(R.id.backdrop);
title = (TextView) findViewById(R.id.movie_title);
description = (TextView) findViewById(R.id.movie_description);
releaseDate = (TextView) findViewById(R.id.movie_date);
voteAverage = (TextView) findViewById(R.id.movie_rating);
author = (TextView) findViewById(R.id.username_review);
content = (TextView) findViewById(R.id.review_comment);
**genres = (ListView) findViewById(R.id.genresArray);**
title.setText(mMovie.getTitle());
description.setText(mMovie.getDescription());
voteAverage.setText(mMovie.getVoteAverage());
releaseDate.setText(mMovie.getReleaseDate());
You would need to provide more details on what you are trying to accomplish.
for a start try getting an instance of your Genre class.
then getting the id or what ever method you need from there.
you'll need to create a custom adapter and pass the names gotten from the Genre class to the adapter.
The problem is that the callback returns Genres POJO. It is a list of containing Genre POJOs.
Rename your Genres POJO to Genre and you need to create an additional POJO
public class Genres{
public List<Genre> genres;
}
and in your success call use this code snippet.
final List<Genre> resultGenres = response.body().genres;
There you have your returned genres and I guess you would pass this list to the DetailActivity.
Related
I asked a question about parsing a JSON array a couple of days ago:
How do you parse a JSON Array w/o a defined array?
I'm downloading a list of 11 items(displayed in a vertical layout in an activity by a RecyclerView LinearLayoutManager). For some reason, two identical lists are being downloaded. I double checked the JSON data tested the Url in Postman and there are no duplicate values. Also, the API doesn't have a pagination parameter.
To moderator. I found a few threads on here about duplicate values in JSON. Again, there are no duplicate values in mine. Thank you in advance.
Remove Duplicate objects from JSON Array
remove duplicate values from json data
JSONUtils class from the above mentioned thread:
public class JSONUtils
{
/**
* Tag for the log messages
*/
private static final String LOG_TAG = JSONUtils.class.getSimpleName();
private static final String KEY_LINE_ID = "id";
private static final String KEY_LINE_NAME = "name";
public JSONUtils()
{
}
public static Lines extractFeatureFromJson (String linesJSON)
{
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(linesJSON)) {
return null;
}
Lines line = null;
try
{
// Create a JSONObject from the JSON file
JSONObject jsonObject = new JSONObject(linesJSON);
String id = "";
if (jsonObject.has("id"))
{
id = jsonObject.optString(KEY_LINE_ID);
}
String name = "";
if (jsonObject.has("name"))
{
name= jsonObject.optString(KEY_LINE_NAME);
}
line = new Lines(id, name);
}
catch (JSONException e)
{
// If an error is thrown when executing any of the above statements in the "try" block,
// catch the exception here, so the app doesn't crash. Print a log message
// with the message from the exception.
Log.e("QueryUtils", "Problem parsing lines JSON results", e);
}
// Return the list of lines
return line;
}
}
RecyclerViewAdapter class:
public class LinesAdapter extends RecyclerView.Adapter<LinesAdapter.LinesAdapterViewHolder>
{
private static final String TAG = LinesAdapter.class.getSimpleName();
private ArrayList<Lines> linesList = new ArrayList<Lines>();
private Context context;
private LinesAdapterOnClickHandler mLineClickHandler;
/**
* The interface that receives onClick messages.
*/
public interface LinesAdapterOnClickHandler
{
void onClick(Lines textLineClick);
}
/**
* Creates a Lines Adapter.
*
* #param lineClickHandler The on-click handler for this adapter. This single handler is called
* * when an item is clicked.
*/
public LinesAdapter(LinesAdapterOnClickHandler lineClickHandler, ArrayList<Lines> linesList, Context context)
{
mLineClickHandler = lineClickHandler;
this.linesList = linesList;
this.context = context;
}
/**
* Cache of the children views for a line list item.
*/
public class LinesAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
#BindView(R.id.line_name)
public TextView lineName;
public LinesAdapterViewHolder(View view)
{
super(view);
ButterKnife.bind(this, view);
view.setOnClickListener(this);
}
/**
* This gets called by the child views during a click.
*
* #param v The View that was clicked
*/
#Override
public void onClick(View v)
{
int adapterPosition = getAdapterPosition();
Lines textLineClick = linesList.get(adapterPosition);
mLineClickHandler.onClick(textLineClick);
}
}
#Override
public LinesAdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
{
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.line_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new LinesAdapterViewHolder(view);
}
/**
* Cache of the children views for a line list item.
*/
#Override
public void onBindViewHolder(LinesAdapterViewHolder holder, int position)
{
//Binding data
final Lines lineView = linesList.get(position);
holder.lineName.setText(lineView.getLineName());
}
#Override
public int getItemCount()
{
return linesList.size();
}
public void setLinesList(ArrayList<Lines> mLinesList)
{
this.linesList.addAll(mLinesList);
notifyDataSetChanged();
}
}
This method look suspicious:
public void setLinesList(ArrayList<Lines> mLinesList)
{
this.linesList.addAll(mLinesList);
notifyDataSetChanged();
}
It has a name like a "setter", but it's not actually setting lines, it is adding lines. If you had code that called this twice with the same arguments, you'd wind up with duplicates.
Here are two ways to write this method so that it actually overwrites the list every time:
public void setLinesList(ArrayList<Lines> mLinesList)
{
this.linesList.clear();
this.linesList.addAll(mLinesList);
notifyDataSetChanged();
}
public void setLinesList(ArrayList<Lines> mLinesList)
{
this.linesList = new ArrayList<>(mLinesList);
notifyDataSetChanged();
}
I've been researching Firebase for a while and decided to give it a try.
I can't seem to figure out why my ListView is not populating.
I can't seem to understand how the adapter looks for our query, for example, I want the string "Artist" and "Title" from my firebase database.
My POJO:
public class Song {
private String mTitle;
private String mArtist;
public Song(String title, String artist) {
mTitle = title;
mArtist = artist;
}
public Song(){
//Needed for firebase
}
public String getTitle() {
return mTitle;
}
public String getArtist() {
return mArtist;
}
public void setTitle(String title) {
mTitle = title;
}
public void setArtist(String artist) {
mArtist = artist;
}
My Activity
public class player extends AppCompatActivity {
FirebaseListAdapter<Song> myAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player2);
ListView songListView = (ListView) findViewById(R.id.songListView);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
myAdapter = new FirebaseListAdapter<Song>(player.this, Song.class, R.layout.song_item, ref) {
#Override
protected void populateView(View view, Song song, int position) {
TextView textView = (TextView) view.findViewById(android.R.id.text1);
((TextView)view.findViewById(R.id.titleItem)).setText(song.getTitle());
((TextView)view.findViewById(R.id.artistItem)).setText(song.getArtist());
}
};
songListView.setAdapter(myAdapter);
}
}
My database:
Any help would be appreciated!
When you create an adapter at a location, it will be populated with the direct child nodes under that location.
You attach the adapter to the root of the database, so your child node is issue_1. And in your data model issue_1 does not have artist and title properties.
Simplest way to get the code working is to attach the adapter one level lower in the tree:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
DatabaseReference issue1 = ref.child("issue_1");
myAdapter = new FirebaseListAdapter<Song>(player.this, Song.class,
R.layout.song_item, issue1) {
I want something like below image. Image is of autocomplete search from firebase website itself.
I've seen many post about this, but those posts does not seem to work with firebase above 3.0.
I want to search in an autcomplete textview either with entering name or number. Here's an entry from my database
In short, it should suggest entries from my firebase database as I start typing.
One solution for achieving this would be loading your data from the realtime database into an ArrayList before you start searching.
So to do this first you'll need to check when the Firebase Listener
is done retrieving your data from the database. Firebase Listeners are not executed in sequence and the ValueListener is always executed last. So you can do something like retrieve your data through a ChildListener and then execute to ValueListener to make sure the data is completely retrieved rootRef.addListenerForSingleValueEvent()
Later when your data is retrieved and stored in a arraylist you can follow this to add the search functionality
Hope it helps!
First of all add the required dependencies of firebase and glide or other dependency for image view in build.gradle .
Create a reference for the tree as follows
mUserDatabase = FirebaseDatabase.getInstance().getReference("YourTreeRootNameHere");
Pass the string in the text field with a onTextChanged method to the following function firebaseUserSearch. Make necessary changes in the following function according to your code.
private void firebaseUserSearch(String searchText) {
Query firebaseSearchQuery = mUserDatabase.orderByChild("sName").startAt(searchText).endAt(searchText + "\uf8ff");
FirebaseRecyclerAdapter<Users, SearchActivity.UsersViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, SearchActivity.UsersViewHolder>(
Users.class,
R.layout.list_layout,
SearchActivity.UsersViewHolder.class,
firebaseSearchQuery
) {
#Override
protected void populateViewHolder(SearchActivity.UsersViewHolder viewHolder, final Users model, final int position) {
viewHolder.setDetails(getApplicationContext(), model.getName(), model.getPlace(), model.getImage());
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
// View Holder Class
public static class UsersViewHolder extends RecyclerView.ViewHolder {
View mView;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDetails(Context ctx, String userName, String userStatus, String userImage){
TextView user_name = (TextView) mView.findViewById(R.id.name_text);
TextView user_status = (TextView) mView.findViewById(R.id.status_text);
ImageView user_image = (ImageView) mView.findViewById(R.id.profile_image);
user_name.setText(userName);
user_status.setText(userStatus);
Glide.with(ctx).load(userImage).into(user_image);
}
}
Create your layout for recyclerView and define the data model class. For example this function uses a Users.class that is shown below.
public class Users {
public String name, image, place;
public Users(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getPlace() {
return place;
}
public void setPlace(String status) {
this.place = status;
}
public Users(String name, String image, String place) {
this.name = name;
this.image = image;
this.place = place;
}
}
This question already has answers here:
Why does Gson fromJson throw a JsonSyntaxException: Expected BEGIN_OBJECT but was BEGIN_ARRAY?
(2 answers)
Closed 6 years ago.
good evening everyone, Ive been searching for a solution to an error android studio's log is sending using RecyclerView to show a JSON "product" list with retrofit.
I have already read the questions related to this error but im not able to find the right answer to my needs.
Android: RecyclerView: No adapter attached; skipping layout
No adapter attached; skipping layout recyclerview error
recyclerview No adapter attached; skipping layout
No adapter attached; skipping layout onCreateView()
This is de error log showed by android studio
RecyclerView: No adapter attached; skipping layout
RecyclerView: No adapter attached; skipping layout
Surface: getSlotFromBufferLocked: unknown buffer: 0xa3d9a700
OpenGLRenderer: endAllStagingAnimators on 0xa2b6bb00 (RippleDrawable) with handle 0xa200a310
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
For this proyect are been used this Classes and Layout files
"Producto" Class
public class Producto {
#SerializedName("id")
#Expose
private int id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("status")
#Expose
private String status;
#SerializedName("price")
#Expose
private String price;
#SerializedName("regular_price")
#Expose
private String regularPrice;
#SerializedName("sale_price")
#Expose
private String salePrice;
#SerializedName("price_html")
#Expose
private String priceHtml;
#SerializedName("on_sale")
#Expose
private boolean onSale;
#SerializedName("total_sales")
#Expose
private int totalSales;
#SerializedName("purchase_note")
#Expose
private String purchaseNote;
#SerializedName("categories")
#Expose
private List<Category> categories;
#SerializedName("menu_order")
#Expose
private int menuOrder;
/**
*
* #return
* The id
*/
public int getId() {
return id;
}
/**
*
* #param id
* The id
*/
public void setId(int id) {
this.id = id;
}
/**
*
* #return
* The name
*/
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The status
*/
public String getStatus() {
return status;
}
/**
*
* #param status
* The status
*/
public void setStatus(String status) {
this.status = status;
}
/**
*
* #return
* The price
*/
public String getPrice() {
return price;
}
/**
*
* #param price
* The price
*/
public void setPrice(String price) {
this.price = price;
}
/**
*
* #return
* The regularPrice
*/
public String getRegularPrice() {
return regularPrice;
}
/**
*
* #param regularPrice
* The regular_price
*/
public void setRegularPrice(String regularPrice) {
this.regularPrice = regularPrice;
}
/**
*
* #return
* The salePrice
*/
public String getSalePrice() {
return salePrice;
}
/**
*
* #param salePrice
* The sale_price
*/
public void setSalePrice(String salePrice) {
this.salePrice = salePrice;
}
/**
*
* #return
* The priceHtml
*/
public String getPriceHtml() {
return priceHtml;
}
/**
*
* #param priceHtml
* The price_html
*/
public void setPriceHtml(String priceHtml) {
this.priceHtml = priceHtml;
}
/**
*
* #return
* The onSale
*/
public boolean isOnSale() {
return onSale;
}
/**
*
* #param onSale
* The on_sale
*/
public void setOnSale(boolean onSale) {
this.onSale = onSale;
}
/**
*
* #return
* The totalSales
*/
public int getTotalSales() {
return totalSales;
}
/**
*
* #param totalSales
* The total_sales
*/
public void setTotalSales(int totalSales) {
this.totalSales = totalSales;
}
/**
*
* #return
* The purchaseNote
*/
public String getPurchaseNote() {
return purchaseNote;
}
/**
*
* #param purchaseNote
* The purchase_note
*/
public void setPurchaseNote(String purchaseNote) {
this.purchaseNote = purchaseNote;
}
/**
*
* #return
* The categories
*/
public List<Category> getCategories() {
return categories;
}
/**
*
* #param categories
* The categories
*/
public void setCategories(List<Category> categories) {
this.categories = categories;
}
/**
*
* #return
* The menuOrder
*/
public int getMenuOrder() {
return menuOrder;
}
/**
*
* #param menuOrder
* The menu_order
*/
public void setMenuOrder(int menuOrder) {
this.menuOrder = menuOrder;
}
}
"Category" Class (which matches with the private List<Category> categories; property)
public class Category {
#SerializedName("id")
#Expose
private int id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("slug")
#Expose
private String slug;
/**
*
* #return
* The id
*/
public int getId() {
return id;
}
/**
*
* #param id
* The id
*/
public void setId(int id) {
this.id = id;
}
/**
*
* #return
* The name
*/
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The slug
*/
public String getSlug() {
return slug;
}
/**
*
* #param slug
* The slug
*/
public void setSlug(String slug) {
this.slug = slug;
}
}
Both Containanied as Arrays in this class called "JSONproducts"
public class JSONproducts {
private Producto[] products;
private Category[] categories;
public Producto[] getProducts(){
return products;
}
public Category[] getCategories(){
return categories;
}
}
Then The Request Interface called "LecturaProductos"
public interface LecturaProductos {
#GET("Products")
Call<JSONproducts> ListarProductos();
}
The data Adapter for the Recycler View called "Adaptador"
public class Adaptador extends RecyclerView.Adapter<Adaptador.ViewHolder> {
private ArrayList<Producto> productos;
private ArrayList<Category> categoria;
public Adaptador(ArrayList<Producto> productos, ArrayList<Category> categoria){
this.productos = productos;
this.categoria = categoria;
}
#Override
public Adaptador.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.product_view, parent, false );
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(Adaptador.ViewHolder holder, int position) {
holder.nom_pro_tv.setText(productos.get(position).getName());
holder.id_pro_tv.setText(productos.get(position).getId());
holder.cat_pro.setText(categoria.get(position).getName());
}
#Override
public int getItemCount() {
return productos.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView nom_pro_tv, id_pro_tv, cat_pro;
public ViewHolder(View itemView) {
super(itemView);
nom_pro_tv = (TextView)itemView.findViewById(R.id.nom_pro_tv);
id_pro_tv = (TextView)itemView.findViewById(R.id.id_pro_tv);
cat_pro = (TextView)itemView.findViewById(R.id.cat_pro_tv);
}
}
}
And the Activity Class "ListaProductos"
public class ListaProductos extends AppCompatActivity {
private RecyclerView recyclerView;
private ArrayList<Producto> product;
private ArrayList<Category> category;
private Adaptador adaptador;
public static final String BASE_URL= "https://mydomain.com.mx/wp-json/wc/v1/";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lista_productos);
showView();
}
private void showView(){
recyclerView = (RecyclerView)findViewById(R.id.prod_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
cargarJSON();
}
private void cargarJSON(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
final LecturaProductos producto = retrofit.create(LecturaProductos.class);
Call<JSONproducts> productoCall = producto.ListarProductos();
productoCall.enqueue(new Callback<JSONproducts>() {
#Override
public void onResponse(Call<JSONproducts> call, Response<JSONproducts> response) {
JSONproducts jsonproducts = response.body();
product = new ArrayList<>(Arrays.asList(jsonproducts.getProducts()));
category = new ArrayList<>(Arrays.asList(jsonproducts.getCategories()));
adaptador = new Adaptador(product, category);
recyclerView.setAdapter(adaptador);
}
#Override
public void onFailure(Call<JSONproducts> call, Throwable t) {
Log.d("Error", t.getMessage());
}
});
}
}
And the Layout XML files that are been used
RecyclerView Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_lista_productos"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mx.com.corpcap.elrollorepartidor.ListaProductos">
<android.support.v7.widget.RecyclerView
android:id="#+id/prod_recycler_view"
android:layout_height="match_parent"
android:layout_width="match_parent"/></LinearLayout>
CardView Layout for the product list
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/nom_pro_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16sp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>
<TextView
android:id="#+id/id_pro_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/cat_pro_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v7.widget.CardView>
Everything complies great and launches the app without an issue but when the information is tried to be accessed it sends the log messages quoted in the beginning of this question.
Thanks a Lot
A RecyclerView is not much use on it's own without an adapter providing the data it must display. So when a RecyclerView is initialized and placed in the layout but .setAdapter has not yet been called, the problem you're experiencing occurs. How about you take an empty list and use that to initialize the adapter and set it to your RecyclerView before you even send the network request. When you make the network request and get a response, simply clear the old values in the list, add new values and notify your adapter that the data in the list has changed. This should avoid the skipping layout problem, Alex.
Something like this:
private ArrayList<YourObjectClass> listOfYourObjects = new ArrayList<>();
.
.
.
SomeAdapter yourAdapter = new SomeAdapter(listOfYourObjects , context);
yourRecyclerView.setAdapter(yourAdapter);
.
.
.
onResponse:
list.clear();
//Let the adapter know the list is empty now
yourAdapter.notifyDataSetChanged();
//Fill in your list with values from server using a for/while loop etc.
//Again notify your adapter that the list has changed:
yourAdapter.notifyDataSetChanged();
Hope that helps.
I'm trying to populate a layout of mine by looping through some requested JSON (I use Retrofit).
When I try to populate the layout manually (like below), it displays fine:
Post post1 = new Post("1", "1", "This is a message.");
But if I try to populate it with the requested JSON data, the layout doesn't get populated nor does it display on my screen. Only the layout with "This is a message." is displayed.
Here is the code within my onCreateView() for my fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
ListView listView = (ListView) view.findViewById(R.id.listview_posts);
final ArrayList<Post> arrayOfUsers = new ArrayList<Post>();
// This works fine. It populates the layout as it should.
Post post1 = new Post("1", "1", "This is a message.");
arrayOfUsers.add(post1);
final RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(BASE_URL)
.build();
final ApiEndpointInterface apiService = restAdapter.create(ApiEndpointInterface.class);
apiService.getJsonStuff(1, new Callback<PostData>() {
#Override
public void success(PostData postData, Response response) {
// This doesn't work either
Post post2 = new Post("1", "1", "This is a message2.");
arrayOfUsers.add(post2);
for (Post p : postData.data) {
// This does not work. The layout isn't populated nor does it display.
Post posty = new Post(p.getId(), p.getUserId(), p.getContent());
arrayOfUsers.add(posty);
// The JSON is being read correctly, since this prints out the right values.
Log.d("MESSAGE", p.getMessage());
}
}
#Override
public void failure(RetrofitError retrofitError) {
retrofitError.printStackTrace();
}
});
PostAdapter adapter = new PostAdapter(getActivity(), arrayOfUsers);
listView.setAdapter(adapter);
return view;
}
The callback:
void getJsonStuff(#Path("user_id") int userId, Callback<PostData> response);
Post model:
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Post {
#Expose
private String id;
#SerializedName("user_id")
#Expose
private String userId;
#Expose
private String content;
public Post(String id, String userId, String content) {
this.id = id;
this.userId = userId;
this.content = content;
}
/**
*
* #return
* The id
*/
public String getId() {
return id;
}
/**
*
* #param id
* The id
*/
public void setId(String id) {
this.id = id;
}
/**
*
* #return
* The userId
*/
public String getUserId() {
return userId;
}
/**
*
* #param userId
* The user_id
*/
public void setUserId(String userId) {
this.userId = userId;
}
/**
*
* #return
* The content
*/
public String getContent() {
return content;
}
/**
*
* #param content
* The content
*/
public void setContent(String content) {
this.content= content;
}
}
PostData model:
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
public class PostData {
#Expose
public Boolean success;
#Expose
public List<Post> data = new ArrayList<Post>();
/**
*
* #return
* The success
*/
public Boolean getSuccess() {
return success;
}
/**
*
* #param success
* The success
*/
public void setSuccess(Boolean success) {
this.success = success;
}
/**
*
* #return
* The data
*/
public List<Post> getData() {
return data;
}
/**
*
* #param data
* The data
*/
public void setData(List<Post> data) {
this.data = data;
}
}
In the scenario that works for you -> you are doing the things sequentially: create the Post object - add it to the list - create the adapter based on the non-empty list - set the adapter on the list.
In the scenario that doesn't work, you are doing them asynchronously: create empty list - trigger request for data (but no data yet) - create adapter - set the adapter on the list - at some undetermined moment in the future data arrives. The problem is that in this case the adapter doesn't know that anything changed, so you need to notify it (at the end of your success callback):
adapter.notifyDataSetChanged()
Your getJsonStuff method should be declared something like...
getJsonStuff(int id, Callback<List<Post>> callback)