Picasso only loading single image but the size is 20 - android

I am trying to make a service call with Retrofit and RxJava. I am using Picasso 2.5.2 to upload image from the API call. I am getting the image displayed, but i am getting single image only. When I debug, I get size as 20 but the displayed is single. Any help on that would be great.
The Adapter class:
public class PopularMoviesAdapter extends RecyclerView.Adapter<PopularMoviesAdapter.MoviesViewHolder> {
private final String TAG = PopularMoviesAdapter.class.getSimpleName();
private Context context;
private List<MoviesResponse> movieItems = new ArrayList<>();
public PopularMoviesAdapter(Context context, List<MoviesResponse> movieItems) {
this.context = context;
this.movieItems = movieItems;
}
#Override
public MoviesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.movies_grid_item, parent, false);
return new MoviesViewHolder(view);
}
#Override
public void onBindViewHolder(MoviesViewHolder holder, int position) {
List<Movies> movies = movieItems.get(position).getResults();
String imageUrl = IntentKeys.MOVIES_POSTER_ENDPOINT + movies.get(position).getPosterPath();
Log.d(TAG, "Poster URL from the API call: " + imageUrl);
Picasso.with(context).load(imageUrl).into(holder.imageView);
Glide.with(context).load(imageUrl).into(holder.imageView);
}
#Override
public int getItemCount() {
return movieItems.size();
}
class MoviesViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public MoviesViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.movies_grid_item_image);
}
}}
The fragment class:
public class PopularMoviesFragment extends Fragment {
private static final int COLUMN_COUNT = 2;
private List<MoviesResponse> responses;
private RecyclerView recyclerView;
private PopularMoviesAdapter popularMoviesAdapter;
private Subscription subscription;
private MoviesService service = RetrofitManager.getMoviesClient().create(MoviesService.class);
public PopularMoviesFragment() {
responses = new ArrayList<>();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_popular_movies, container, false);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(
getActivity(),
COLUMN_COUNT,
LinearLayoutManager.VERTICAL,
false);
recyclerView = (RecyclerView) view.findViewById(R.id.popular_movies_recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new GridSpacingItemDecoration(COLUMN_COUNT, dpToPx(10), true));
recyclerView.setItemAnimator(new DefaultItemAnimator());
return view;
}
private int dpToPx(int dp) {
Resources r = getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onStart() {
super.onStart();
getMoviesSubscription();
}
private void getMoviesSubscription() {
subscription = service.getPopularMovies(IntentKeys.POPULAR_MOVIES_API_KEY)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new Action1<MoviesResponse>() {
#Override
public void call(MoviesResponse movies) {
responses.add(movies);
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
}
}, new Action0() {
#Override
public void call() {
displayPosters();
}
}
);
}
private void displayPosters() {
popularMoviesAdapter = new PopularMoviesAdapter(getContext(), responses);
recyclerView.setAdapter(popularMoviesAdapter);
recyclerView.invalidate();
}
#Override
public void onDestroyView() {
super.onDestroyView();
if (subscription != null && subscription.isUnsubscribed()) {
subscription.unsubscribe();
}
}
}
Finally the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/movies_grid_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/movies_grid_item_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"/>
</LinearLayout>
POJO:
public class Movies implements Serializable {
private String posterPath;
private Boolean adult;
private String overview;
private String releaseDate;
private List<Integer> genreIds = new ArrayList<Integer>();
private Integer id;
private String originalTitle;
private String originalLanguage;
private String title;
private String backdropPath;
private Float popularity;
private Integer voteCount;
private Boolean video;
private Float voteAverage;
// getters and setters ommitted and constructor
}
public class MoviesResponse implements Serializable {
private Integer page;
private List<Movies> results = new ArrayList<Movies>();
private Integer totalResults;
private Integer totalPages;
// getters and setters ommitted and constructor
}
Thanks!

Try
Context context = holder.itemView.getContext();
in your onBindViewHolder, so that you don't pass context around.
Also try adding popularMoviesAdapter.notifyDataSetChanged() in your fragment. Do you mind uploading your POJO?
in your adapter
public PopularMoviesAdapter(List<Movie> movies) {
this.movies = movies;
}
in your fragment
.subscribe(
new Action1<MoviesResponse>() {
#Override
public void call(MoviesResponse movies) {
responses.add(movies.getResults());
popularMoviesAdapter.notifyDataSetChanged()
}
}
Change
#Override
public void onBindViewHolder(MoviesViewHolder holder, int position) {
List<Movies> movies = movieItems.get(position);
String imageUrl = IntentKeys.MOVIES_POSTER_ENDPOINT + movies.get(position).getPosterPath();
Log.d(TAG, "Poster URL from the API call: " + imageUrl);
Picasso.with(context).load(imageUrl).into(holder.imageView);
Glide.with(context).load(imageUrl).into(holder.imageView);
}

This is your code to set adapter
popularMoviesAdapter = new PopularMoviesAdapter(getContext(), responses); recyclerView.setAdapter(popularMoviesAdapter);
your ArrayList responses = new ArrayList() // this is your arraylist which you are providing to adapter
debug and check size of responses that how many records will return i think it has on one object
i think your array is somewhat like this
responses [{
0,{
}
}];
so passs
popularMoviesAdapter = new PopularMoviesAdapter(getContext(), responses.get(0).getResults
); recyclerView.setAdapter(popularMoviesAdapter);

Related

How to Show GridView Image In Android Fragments Using Json (categories and subcategories)

Those are categories and subcategories. There can be subcategory or not.
JsonCode to be used is as below.
categoryId is what will change to call subcategories.
E.g. If you want to see subcategories of cars
Json Code
[{"Id":1,"TitleEN":"Cars","TitleAR":"سيارات","Photo":"http://souq.hardtask.co//Files/CategoryPhotos/ce686544-9f51-4213-b5db-7c015b788e8d.png","ProductCount":"3","HaveModel":"0","SubCategories":[{"Id":6,"TitleEN":"Cat6","TitleAR":"قسم6","Photo":"http://souq.hardtask.co//Files/CategoryPhotos/ce686544-9f51-4213-b5db-7c015b788e8d.png","ProductCount":"3","HaveModel":"0","SubCategories":[]}]},{"Id":2,"TitleEN":"Cat2","TitleAR":"قسم2","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"8","HaveModel":"0","SubCategories":[{"Id":13,"TitleEN":"cat1 -1 ","TitleAR":"cat1 - 1","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"8","HaveModel":"0","SubCategories":[]}]},{"Id":3,"TitleEN":"Cat3","TitleAR":"قسم3","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"2","HaveModel":"0","SubCategories":[]},{"Id":4,"TitleEN":"Cat4","TitleAR":"قسم4","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"1","HaveModel":"0","SubCategories":[]},{"Id":5,"TitleEN":"Cat5","TitleAR":"قسم5","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"0","HaveModel":"0","SubCategories":[]},{"Id":8,"TitleEN":"Cat8","TitleAR":"قسم8","Photo":"http://souq.hardtask.co//Images/no_image.png","ProductCount":"0","HaveModel":"0","SubCategories":[]},{"Id":9,"TitleEN":"Slide01","TitleAR":"Slide02","Photo":"http://souq.hardtask.co//Files/CategoryPhotos/2ba07cb2-49a0-47e4-aba6-ef10a916fb12.png","ProductCount":"0","HaveModel":"0","SubCategories":[]}]
ImageAdapter
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c){
mContext = c;
}
#Override
public int getCount(){
return images.size();
}
#Override
public Object getItem(int position){
return images.get(position);
}
public long getItemId(int position){
return 0;
}
public View getView(int position, View convertView, ViewGroup parent){
ImageView imageview;
if (convertView == null){
imageview = new ImageView(mContext);
imageview.setPadding(0, 0, 0, 0);
//imageview.setLayoutParams(new GridLayout.MarginLayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
imageview.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageview.setAdjustViewBounds(true);
} else {
imageview = (ImageView) convertView;
}
Picasso.with(mContext).load(images.get(position)).placeholder(R.mipmap.ic_launcher).into(imageview);
return imageview;
}
/*
Custom methods
*/
public void addItem(String url){
images.add(url);
}
public void clearItems() {
images.clear();
}
public ArrayList<String> images = new ArrayList<String>();
}
Movie Model
public class Movie implements Parcelable {
public String TitleEN;
public String TitleAR;
public String Photo;
public int id;
public Movie(){
}
protected Movie(Parcel in) {
TitleEN = in.readString();
TitleAR = in.readString();
Photo = in.readString();
id = in.readInt();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(TitleEN);
dest.writeString(TitleAR);
dest.writeString(Photo);
dest.writeInt(id);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<Movie> CREATOR = new Parcelable.Creator<Movie>() {
#Override
public Movie createFromParcel(Parcel in) {
return new Movie(in);
}
#Override
public Movie[] newArray(int size) {
return new Movie[size];
}
};
}
Fragament_main
public class Fragament_main extends Fragment {
public View mainFragmentView;
public String LOG_TAG = "ShowcaseFragment";
public ArrayList<Movie> movies = new ArrayList<Movie>();
private RequestQueue mRequestQueue;
public ImageAdapter imageAdapter;
public static Fragament_main instance;
GridView gridview;
public boolean isDualPane = false;
// static to preserve sorting over orientation changes (activity restart)
public static String sortOrder = "popularity.desc", moreParams = "";
public static boolean setting_cached = false;
public int gridPos = -1;
public Fragament_main() {
// Required empty public constructor
instance = this;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mainFragmentView = inflater.inflate(R.layout.fragment_main, container, false);
mRequestQueue = Volley.newRequestQueue(getContext());
// setup adapters
imageAdapter = new ImageAdapter(getContext());
gridview = (GridView) mainFragmentView.findViewById(R.id.gridView);
gridview.setAdapter(imageAdapter);
//updateUI(setting_cached);
//gridview.setOnItemClickListener(new GridClickListener());
// manage grid col count wrt Orientation
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
setGridColCount(3);
else
setGridColCount(2);
return mainFragmentView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("GRIDVIEW_POSITION", gridview.getFirstVisiblePosition());
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null)
gridPos = savedInstanceState.getInt("GRIDVIEW_POSITION");
}
#Override
public void onDestroyView() {
super.onDestroyView();
mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
#Override
public boolean apply(Request<?> request) {
return true;
}
});
}
/*class GridClickListener implements AdapterView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
if (isDualPane){
android.support.v4.app.FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
DetailActivityFragment detailActivityFragment = DetailActivityFragment.newInstance(movies.get(position));
ft.replace(R.id.detailContainer, detailActivityFragment);
ft.commit();
} else {
Intent intent = new Intent(getContext(), DetailActivity.class);
intent.putExtra(Intent.EXTRA_TEXT, (Parcelable) movies.get(position));
startActivity(intent);
}
}
}*/
/* public void updateUI(boolean cached){
movies.clear();
imageAdapter.clearItems();
setting_cached = cached;
if (!cached)
getMovies(sortOrder, moreParams);
else
getFavorites();
}
*/
public void getMovies(String sortOrder, String moreParams){
String url = "http://souq.hardtask.co/app/app.asmx/GetCategories?categoryId=0&countryId=1";
JsonObjectRequest req = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray items = response.getJSONArray("results");
JSONObject movieObj;
for (int i=0; i<items.length(); i++){
movieObj = items.getJSONObject(i);
Movie movie = new Movie();
movie.id = movieObj.getInt("id");
movie.TitleEN = movieObj.getString("original_title");
movie.TitleAR = movieObj.getString("overview");
movie.Photo = "http://souq.hardtask.co/app/app.asmx/GetCategories?categoryId=0&countryId=1" + movieObj.getString("poster_path");
movies.add(movie);
// Add image to adapter
imageAdapter.addItem(movie.Photo);
}
} catch (JSONException e){
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
gridview.setAdapter(imageAdapter);
if (gridPos > -1)
gridview.setSelection(gridPos);
gridPos = -1;
}
});
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(LOG_TAG, "Error in JSON Parsing");
}
});
mRequestQueue.add(req);
}
/* public void getFavorites(){
movies.addAll((new MoviesDB()).getFavoriteMovies(getContext().getContentResolver()));
for (Movie movie : movies){
imageAdapter.addItem(movie.Photo);
}
gridview.setAdapter(imageAdapter);
if (gridPos > -1)
gridview.setSelection(gridPos);
gridPos = -1;
}*/
public void updateFavoritesGrid(){
if (setting_cached) {
int p = gridview.getLastVisiblePosition();
///updateUI(true);
gridview.smoothScrollToPosition(p);
}
}
public void setGridColCount(int n){
((GridView) mainFragmentView.findViewById(R.id.gridView)).setNumColumns(n);
}
}
I don't know how to add Json data into GridView.
Could you help me?
Go through this example to view images in grid,
Convert your jsonArray into an ArrayList by using,
ArrayList<Cars> carsList = new Gson().fromJson(jsonArrayYouHave.toString(),new TypeToken<List<Cars>>() {
}.getType());
Pass this Array to your Adapter.
Use this POJO,
public class Cars {
private String TitleAR;
private String HaveModel;
private String TitleEN;
private String Id;
private ArrayList<SubCategories> SubCategories;
private String Photo;
private String ProductCount;
//Todo please add getter/setters for class Cars variables here
public class SubCategories {
private String TitleAR;
private String HaveModel;
private String TitleEN;
private String Id;
private ArrayList<String> SubCategories;
private String Photo;
private String ProductCount;
//Todo please add getter/setters for class SubCategories variables here
}
I'll suggest to use Retrofit as it'll provide you parsed arraylist which is converted into Response POJO you have provided. You can find many examples for Retrofit.
Step 1
Add the following dependencies in your app level gradle file.Dependencies are for retrofit, gsonConvertor butterknife and glide.
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation('com.squareup.retrofit2:retrofit:2.1.0') {
// exclude Retrofit’s OkHttp dependency module and define your own module import
exclude module: 'okhttp'
}
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
implementation 'com.squareup.okhttp3:okhttp:3.4.1'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation "com.jakewharton:butterknife:$BUTTER_KNIFE_VERSION"
annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTER_KNIFE_VERSION"
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
Step 2 Create a class by name ApiClient and paste the following code in this class
public class ApiClient {
private static Retrofit retrofit = null;
public static Retrofit getRetrofit() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder()
.baseUrl("http://souq.hardtask.co")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
}
Step 3 Create a new Interface class by name APIInterface and paste the following code in this class
#GET("/app/app.asmx/GetCategories")
Call<List<Product>> getProducts(#QueryMap Map<String, String> params);
Step 4 Create POJO classes according to json response. We have two classes Products and their subcategory.So I am creating first class by name Product
public class Product {
#SerializedName("Id")
#Expose
private Integer id;
#SerializedName("TitleEN")
#Expose
private String titleEN;
#SerializedName("TitleAR")
#Expose
private String titleAR;
#SerializedName("Photo")
#Expose
private String photo;
#SerializedName("ProductCount")
#Expose
private String productCount;
#SerializedName("HaveModel")
#Expose
private String haveModel;
#SerializedName("SubCategories")
#Expose
private List<SubCategory> subCategories = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitleEN() {
return titleEN;
}
public void setTitleEN(String titleEN) {
this.titleEN = titleEN;
}
public String getTitleAR() {
return titleAR;
}
public void setTitleAR(String titleAR) {
this.titleAR = titleAR;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public String getProductCount() {
return productCount;
}
public void setProductCount(String productCount) {
this.productCount = productCount;
}
public String getHaveModel() {
return haveModel;
}
public void setHaveModel(String haveModel) {
this.haveModel = haveModel;
}
public List<SubCategory> getSubCategories() {
return subCategories;
}
public void setSubCategories(List<SubCategory> subCategories) {
this.subCategories = subCategories;
}
}
And SubCategory
public class SubCategory {
#SerializedName("Id")
#Expose
private Integer id;
#SerializedName("TitleEN")
#Expose
private String titleEN;
#SerializedName("TitleAR")
#Expose
private String titleAR;
#SerializedName("Photo")
#Expose
private String photo;
#SerializedName("ProductCount")
#Expose
private String productCount;
#SerializedName("HaveModel")
#Expose
private String haveModel;
#SerializedName("SubCategories")
#Expose
private List<Object> subCategories = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitleEN() {
return titleEN;
}
public void setTitleEN(String titleEN) {
this.titleEN = titleEN;
}
public String getTitleAR() {
return titleAR;
}
public void setTitleAR(String titleAR) {
this.titleAR = titleAR;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public String getProductCount() {
return productCount;
}
public void setProductCount(String productCount) {
this.productCount = productCount;
}
public String getHaveModel() {
return haveModel;
}
public void setHaveModel(String haveModel) {
this.haveModel = haveModel;
}
public List<Object> getSubCategories() {
return subCategories;
}
public void setSubCategories(List<Object> subCategories) {
this.subCategories = subCategories;
}
}
Step 5 now we need a view for recyclerview holder(in your case gridview layout). For that we need to create a new layout file inside layout folder. you can name it li_product_view
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="200dp"
android:layout_height="200dp">
<ImageView
android:id="#+id/ImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#mipmap/ic_launcher" />
<TextView
android:id="#+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/ImageView"
android:layout_alignTop="#id/ImageView"
android:layout_alignRight="#id/ImageView"
android:layout_alignBottom="#id/ImageView"
android:text="#string/app_name"
android:gravity="bottom|right" />
</RelativeLayout>
</RelativeLayout>
Step 6 Now we need itemHolder to hold the view for that purpose we will create a new class by name ProductsItemHolderand will have the following code
public class ProductsItemHolder extends RecyclerView.ViewHolder {
#BindView(R.id.ImageView)
ImageView imageView;
#BindView(R.id.tv_title)
TextView textView;
public ProductsItemHolder(#NonNull View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
public void bindData(Product datum, int position, int size) {
Glide.with(itemView)
.asBitmap()
.load(datum.getPhoto())
.into(imageView);
textView.setText(datum.getTitleAR());
}
}
Step 7 Now we need adapter which contains the data to present inside recyclerview. Create a new class by name ProductsAdapter and paste the following code inside this class
public class ProductsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Product> mList;
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.li_product_view, viewGroup, false);
return new ProductsItemHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int position) {
int size= mList.size();
((ProductsItemHolder) viewHolder).bindData(mList.get(position), position,size);
}
#Override
public int getItemCount() {
return mList.size();
}
public void setData(List<Product> userLists) {
this.mList = userLists;
notifyDataSetChanged();
}
}
Step 8 now inside the activity or fragment we need to get response from json and pass this response to recyclerview.
public class MainActivity extends AppCompatActivity {
APIInterface apiInterfacePages;
RecyclerView recyclerView;
List<MultipleResource.Datum> datumList= new ArrayList<>();
ProgressDialog dialog;
ProductsAdapter productsAdapter;
private List<Product> dataArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiInterfacePages= PageApiClient.getRetrofit().create(APIInterface.class);
recyclerView= findViewById(R.id.recyclerView);
productsAdapter= new ProductsAdapter();
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
getData();
}
private void getData() {
dataArrayList = new ArrayList<>();
Map<String, String> params = new HashMap<String, String>();
params.put("categoryId", "0");
params.put("countryId", "1");
Call<List<Product>> call= apiInterfacePages.getProducts(params);
call.enqueue(new Callback<List<Product>>() {
#Override
public void onResponse(Call<List<Product>> call, Response<List<Product>> response) {
dataArrayList = response.body();
productsAdapter.setData(dataArrayList);
recyclerView.setAdapter(productsAdapter);
}
#Override
public void onFailure(Call<List<Product>> call, Throwable t) {
Log.i("Call response",t.getMessage());
}
});
}
}

retrofit, can't display my data on recyclerview from my api

im a newbie, i have a problem in my recyclerview. I cant fetch my data from my api. ive just took this tutorial since it is the same implementation form my app. http://shaoniiuc.com/android/fetch-json-api-data-recyclerview-using-retrofit-library/, Maybe my implementation is wrong here, can you please help me to solve, thank you :)
This is my api:
public interface Api {
#GET("api/Database/GetSchedule?serialNumber=1807200003")
Call<List<ScheduleDetails>> getSchedData();
}
My DetailObjects:
public class ScheduleDetails {
private String ID;
private String Location;
private String Latitude;
private String Longitude;
private String SequenceNumber;
private String Comment;
private String hasArrived;
private String ActualArrival;
private String hasDepart;
private String ActualDeparture;
private String Status;
private String ID_FleetSchedule;
private String ExpectedTimeOfTransaction;
private String EstimatedTimeOfDeparture;
private String ID_FleetCar;
private String Scheduler;
private String Car;
private String ID_FleetCompany;
private String FleetCompany;
private String ID_FleetDevice;
private String SerialNumber;
//Constructor....
//Getter.....
}
note: in my api, these are the string ive get but
ive only getting least of them... you can check
it on my adapterView.
my adapterview:
public class scheduleAdapter extends
RecyclerView.Adapter<scheduleAdapter.MyViewHolder> {
private List<ScheduleDetails> schedlist;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView location,schedule_status,dateTime,IDFleet,iid;
public MyViewHolder(View view) {
super(view);
location=view.findViewById(R.id.schedule_location);
dateTime=view.findViewById(R.id.schedule_dateTime);
schedule_status=view.findViewById(R.id.schedule_Status);
IDFleet=view.findViewById(R.id.schedule_FleetID);
iid=view.findViewById(R.id.schedule_ID);
}
}
public scheduleAdapter(List<ScheduleDetails> scheduleList) {
this.schedlist = scheduleList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.schedule_cardview, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int
position) {
ScheduleDetails sched = schedlist.get(position);
holder.location.setText(sched.getLocation());
holder.schedule_status.setText(sched.getStatus());
holder.dateTime.setText(sched.getExpectedTimeOfTransaction());
holder.IDFleet.setText(sched.getID_FleetSchedule());
holder.iid.setText(sched.getID());
}
#Override
public int getItemCount() {
return schedlist.size();
}
}
this is my API:
public class ApiClient {
private static final String BASE_URL = "http://www.example.com";
private static Retrofit retrofit = null;
public static Retrofit getRetrofit() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
this is my getList via recyclerview on my main activity:
public class ScheduleFleet extends Fragment {
View inflatedView = null;
private RecyclerView recyclerView;
private scheduleAdapter mAdapter;
private LinearLayoutManager layoutManager;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
inflatedView = inflater.inflate(R.layout.fragment_schedule_fleet, container, false);
return inflatedView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Schedule");
final SwipeRefreshLayout refresh = inflatedView.findViewById(R.id.sched_refresh);
getUserList();
refresh.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
doYourUpdate();
}
private void doYourUpdate() {
recyclerView.setAdapter(mAdapter);
getUserList();
refresh.setRefreshing(false);
}
}
);
}
private void getUserList() {
try {
Api service = ApiClient.getRetrofit().create(Api.class);
Call<List<ScheduleDetails>> call = service.getSchedData();
call.enqueue(new Callback<List<ScheduleDetails>>() {
#Override
public void onResponse(Call<List<ScheduleDetails>> call, Response<List<ScheduleDetails>> response) {
List<ScheduleDetails> userList = response.body();
layoutManager = new LinearLayoutManager(getContext());
RecyclerView recyclerView =inflatedView.
findViewById(R.id.scheduleRecycler);
recyclerView.setLayoutManager(layoutManager);
scheduleAdapter recyclerViewAdapter =
new scheduleAdapter(userList);
recyclerView.setAdapter(recyclerViewAdapter);
}
#Override
public void onFailure(Call<List<ScheduleDetails>> call, Throwable t) {
}
});
}catch (Exception e) {}
}
}
note: ive try to use the debug tool.. it says that my api is message:OK also the response= true... but i havnt display the data on my recyclerview...
ill hope, you understand my question.. feel free to comment if i i have wrong in my question.. thanks folks.
this is my sample api get using insomnia:

Android Retrofit 2.1.0 Response.body() is null, status code is 404

I am trying to make a call to this api and am having difficulty as the response.body() is returning null.
http://demo.museum.vebrary.vn/api/stuff/getall
I want to get stuff name of list and show to my recyclerview.
My model:
public class SOAnswersResponse {
#SerializedName("StuffModels")
#Expose
private List<StuffModel> stuffModels = null;
public List<StuffModel> getStuffModels() {
return stuffModels;
}
public void setStuffModels(List<StuffModel> stuffModels) {
this.stuffModels = stuffModels;
}
and
public class StuffModel {
#SerializedName("STUFFID")
#Expose
private Integer sTUFFID;
#SerializedName("STUFFCODE")
#Expose
private String sTUFFCODE;
#SerializedName("STUFFNAME")
#Expose
private String sTUFFNAME;
#SerializedName("STUFFNOTE")
#Expose
private String sTUFFNOTE;
#SerializedName("STUFFORDER")
#Expose
private Integer sTUFFORDER;
#SerializedName("CUSTOMERID")
#Expose
private String cUSTOMERID;
#SerializedName("EXHIBITS")
#Expose
private List<Object> eXHIBITS = null;
Json response
{
"StuffModels":[
{
"STUFFID":2,
"STUFFCODE":"Gi",
"STUFFNAME":"Giấy",
"STUFFNOTE":"",
"STUFFORDER":2,
"CUSTOMERID":"CAMAU",
"EXHIBITS":[
]
},
ApiUtils Class
public class ApiUtils {
private ApiUtils() {
}
public static final String BASE_URL = "http://demo.museum.vebrary.vn/api/";
public static SOService getSOService() {
return RetrofitClient.getClient(BASE_URL).create(SOService.class);
}
}
Service interface
public interface SOService {
#GET("/stuff/getall")
Call<SOAnswersResponse> getAnswers();
}
RetrofitClient Class
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
My RecyclerView adapter
public class CategogyNameRecyclerViewAdapter extends RecyclerView.Adapter<CategogyNameRecyclerViewAdapter.ViewHolder> {
private List<StuffModel> mItems;
private Context mContext;
private PostItemListener mItemListener;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView titleTv;
PostItemListener mItemListener;
public ViewHolder(View itemView, PostItemListener postItemListener) {
super(itemView);
titleTv = itemView.findViewById(R.id.tvListMenuCategogy);
this.mItemListener = postItemListener;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
StuffModel item = getItem(getAdapterPosition());
this.mItemListener.onPostClick(item.getSTUFFID());
notifyDataSetChanged();
}
}
public CategogyNameRecyclerViewAdapter(Context context, List<StuffModel> posts, PostItemListener itemListener) {
mItems = posts;
mContext = context;
mItemListener = itemListener;
}
#Override
public CategogyNameRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View postView = inflater.inflate(R.layout.item_list_text, parent, false);
ViewHolder viewHolder = new ViewHolder(postView, this.mItemListener);
return viewHolder;
}
#Override
public void onBindViewHolder(CategogyNameRecyclerViewAdapter.ViewHolder holder, int position) {
StuffModel item = mItems.get(position);
TextView textView = holder.titleTv;
textView.setText(item.getSTUFFNAME());
}
#Override
public int getItemCount() {
return mItems.size();
}
public void updateAnswers(List<StuffModel> items) {
mItems = items;
notifyDataSetChanged();
}
private StuffModel getItem(int adapterPosition) {
return mItems.get(adapterPosition);
}
public interface PostItemListener {
void onPostClick(long id);
}
}
And my main activity
public class Testttt extends AppCompatActivity {
private CategogyNameRecyclerViewAdapter mAdapter;
private RecyclerView mRecyclerView;
private SOService mService;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView(R.layout.test );
mService = ApiUtils.getSOService();
mRecyclerView = (RecyclerView) findViewById(R.id.rcvCategogyNameMenuTest);
mAdapter = new CategogyNameRecyclerViewAdapter(this, new ArrayList<StuffModel>(0), new CategogyNameRecyclerViewAdapter.PostItemListener() {
#Override
public void onPostClick(long id) {
Toast.makeText(Testttt.this, "Post id is" + id, Toast.LENGTH_SHORT).show();
}
});
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setHasFixedSize(true);
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
mRecyclerView.addItemDecoration(itemDecoration);
loadAnswers();
}
public void loadAnswers() {
mService.getAnswers().enqueue(new Callback<SOAnswersResponse>() {
#Override
public void onResponse(Call<SOAnswersResponse> call, Response<SOAnswersResponse> response) {
Toast.makeText(Testttt.this, "333333333333333333"+response.body(), Toast.LENGTH_SHORT).show();
if(response.isSuccessful()) {
mAdapter.updateAnswers(response.body().getStuffModels());
Log.d("AnswersPresenter", "posts loaded from API");
}else {
int statusCode = response.code();
}
}
#Override
public void onFailure(Call<SOAnswersResponse> call, Throwable t) {
showErrorMessage();
Log.d("AnswersPresenter", "error loading from API");
}
});
}
public void showErrorMessage() {
Toast.makeText(this, "Error loading posts", Toast.LENGTH_SHORT).show();
}
}
The first thing that came in my mind:
Your
public static final String BASE_URL = "http://demo.museum.vebrary.vn/api/";
has a "/" at the the end and your
#GET("/stuff/getall")
Call<SOAnswersResponse> getAnswers();
starts with a "/". So there is a double backslash in the url that might leads to the 404 code. Does this solve the problem?
When i call your URL i receive XML. Maybe the API is not configured correctly?
Change your Service interface
public interface SOService {
#GET("stuff/getall")
Call<SOAnswersResponse> getAnswers();
}
it occurred because you have use start with backslash it already added in your base url

iam using Retrofit library to fetch data from Database to recyclerview

am trying to Fetch the movies data from Mysql DB and show it to Recycler view
but when i run the app nothing shows
here is code i am using Retrofite Library
but i can't parse the Data to the Recycler view
i've made Adapter and Model Class normally like the Json
MainActivity.class
public class MainActivity extends AppCompatActivity {
private static final String url="http://192.168.1.109/stu/";
RecyclerView recyclerViewMovies;
List<MovieListsModels> movies;
MoviesAdapter adapter;
TextView Errortxt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Errortxt = (TextView)findViewById(R.id.txterror);
recyclerViewMovies = (RecyclerView)findViewById(R.id.recyclerview);
recyclerViewMovies.setHasFixedSize(true);
recyclerViewMovies.setLayoutManager(new LinearLayoutManager(this));
movies = new ArrayList<>();
loadDatafromServer();
}
private void loadDatafromServer() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
Api api = retrofit.create(Api.class);
Call<MovieListsModels> call = api.ShowMoviesData();
call.enqueue(new Callback<MovieListsModels>() {
#Override
public void onResponse(Call<MovieListsModels> call, Response<MovieListsModels> response) {
try {
MovieListsModels movie = response.body();
adapter = new MoviesAdapter(MainActivity.this, (List<MovieListsModels>) movie);
recyclerViewMovies.setAdapter(adapter);
}
catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<MovieListsModels> call, Throwable t) {
Errortxt.setText(t.getMessage().toString());
}
});
}
this is the interface of the methods
Api.class Interface
public interface Api {
#GET("config.php")
Call<MovieListsModels> ShowMoviesData();
}
MovieLists.class
public class MovieListsModels {
public MovieListsModels() {
}
int id;
String movie_name;
String movie_image;
String movie_genre;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMovie_name() {
return movie_name;
}
public void setMovie_name(String movie_name) {
this.movie_name = movie_name;
}
public String getMovie_image() {
return movie_image;
}
public void setMovie_image(String movie_image) {
this.movie_image = movie_image;
}
public String getMovie_genre() {
return movie_genre;
}
public void setMovie_genre(String movie_genre) {
this.movie_genre = movie_genre;
}
public MovieListsModels(int id, String movie_name, String movie_image, String movie_genre) {
this.id = id;
this.movie_name = movie_name;
this.movie_image = movie_image;
this.movie_genre = movie_genre;
}
}
MovieAdapter.class
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MovieHolderView> {
private Context mContext;
private List<MovieListsModels> MovieList = new ArrayList<>();
public MoviesAdapter(Context mContext, List<MovieListsModels> movieList) {
this.mContext = mContext;
MovieList = movieList;
}
#NonNull
#Override
public MovieHolderView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item,parent,false);
MovieHolderView holder = new MovieHolderView(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull MovieHolderView holder, int position) {
MovieListsModels list = MovieList.get(position);
holder.txtName.setText(list.getMovie_name());
holder.txtGenre.setText(list.getMovie_genre());
Picasso.get()
.load(list.getMovie_image())
.into(holder.imgMovie);
}
#Override
public int getItemCount() {
return MovieList.size();
}
public class MovieHolderView extends RecyclerView.ViewHolder {
TextView txtName,txtGenre;
ImageView imgMovie;
public MovieHolderView(View itemView) {
super(itemView);
txtName =(TextView)itemView.findViewById(R.id.movieName);
txtGenre =(TextView)itemView.findViewById(R.id.movieGenre);
imgMovie =(ImageView)itemView.findViewById(R.id.movieImg);
}
}
}
If you receive a list of movies is better because you expect a list, I suppose
public void onResponse(Call<MovieListsModels> call, Response<MovieListsModels> response) {
try {
List<MovieListsModels> movie = response.body();
adapter = new MoviesAdapter(MainActivity.this, movies);
And I believe that not executing the notifyDataSetChanged, you can added like that:
private Context mContext;
private List<MovieListsModels> MovieList = new ArrayList<>();
public MoviesAdapter(Context mContext, List<MovieListsModels> movieList) {
this.mContext = mContext;
MovieList = movieList;
notifiyDataSetChanged();
If you are having json response of the form {..}, you are having an object response and you should expect an object as you have done i.e, Call<YourObject>
If you are having json response of the form [..], you are having an array response and you should expect an array i.e, Call<List<YourObject>>
In your case, i hope its an array(second case), So make changes as per the above answer done by #Guillodacosta
First don't forget to add the internet permission in your manifest file
<uses-permission android:name="android.permission.INTERNET" />
Second try this
Picasso.with(mContext).load(list.getMovie_image()).into(holder.imgMovie);

Android Studio Recyclerview use Retrofit

please help me..
i have 10 policy data on my PHP to show on recyclerview android studio using retrofit..but, when i run my emulator, the emulator just show 1 data..my plan just show PolicyNo..when i running emulator and check my log, they've said : my Number Policy Received: 10
sorry for my bad english :(
here is my policyActivity :
public class PolicyActivity extends AppCompatActivity {
private static final String TAG = PolicyActivity.class.getSimpleName();
private String policyno;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_policy);
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.policy_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
ApiEndPoint apiEndPoint =
ApiClient.getClient(this).create(ApiEndPoint.class);
Call<PolicyStatus> call = apiEndPoint.getPolicyNo(policyno);
call.enqueue(new Callback<PolicyStatus>() {
#Override
public void onResponse(Call<PolicyStatus> call, Response<PolicyStatus> response) {
List<PolicyNo> policyNo = response.body().getPolicyNo();
Log.d(TAG, "Number Policy Received: " + policyNo.size());
recyclerView.setAdapter(new PolicyAdapter(policyNo, R.layout.list_item_policy, getApplicationContext()));
}
#Override
public void onFailure (Call <PolicyStatus> call, Throwable t){
Log.e(TAG, t.toString());
}
});
}
}
and this is my policyadapter:
public class PolicyAdapter extends RecyclerView.Adapter<PolicyAdapter.PolicyViewHolder> {
private List<PolicyNo> policyNo;
private int rowLayout;
private Context context;
public static class PolicyViewHolder extends RecyclerView.ViewHolder{
LinearLayout policyLayout;
TextView nomorpolis;
public PolicyViewHolder (View v){
super(v);
policyLayout = (LinearLayout) v.findViewById(R.id.policy_layout);
nomorpolis = (TextView)v.findViewById(R.id.nomorpolis);
}
}
public PolicyAdapter (List<PolicyNo>policyNo, int rowLayout, Context context){
this.policyNo = policyNo;
this.context = context;
this.rowLayout = rowLayout;
}
#Override
public PolicyAdapter.PolicyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View view= LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false);
return new PolicyViewHolder(view);
}
#Override
public void onBindViewHolder (PolicyViewHolder holder, final int position){
holder.nomorpolis.setText(policyNo.get(position).getPolicyNo());
}
#Override
public int getItemCount() {return policyNo.size();}
}
PolicyStatus :
public class PolicyStatus {
#SerializedName("success")
#Expose
private Boolean success;
#SerializedName("PolicyNo")
#Expose
private List<PolicyNo> policyNo = null;
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public List<PolicyNo> getPolicyNo() {
return policyNo;
}
public void setPolicyNo(List<PolicyNo> policyNo) {
this.policyNo = policyNo;
}
PolicyNo :
public class PolicyNo {
#SerializedName("ANO")
#Expose
private Integer aNO;
#SerializedName("PolicyNo")
#Expose
private String policyNo;
#SerializedName("ADate")
#Expose
private ADate aDate;
#SerializedName("ADATE")
#Expose
private String aDATE;
public Integer getANO() {
return aNO;
}
public void setANO(Integer aNO) {
this.aNO = aNO;
}
public String getPolicyNo() {
return policyNo;
}
public void setPolicyNo(String policyNo) {
this.policyNo = policyNo;
}
public ADate getADate() {
return aDate;
}
public void setADate(ADate aDate) {
this.aDate = aDate;
}
public String getADATE() {
return aDATE;
}
public void setADATE(String aDATE) {
this.aDATE = aDATE;
}
public PolicyNo (String policyNo){
this.policyNo = policyNo;
}
}
api endpoint :
#GET ("policy.php")
Call<PolicyStatus> getPolicyNo (#Query("PolicyNo") String policyNo);
I think you have given list_item_policy to match_parent. as you are saying you are getting 10 size in log. then this can be only reason. may be you will find items on scroll. So just change this to wrap_content.
Also check your recyclerView getting full height check in the preview.
Code looks fine except one thing which I noticed :-
Do this :-
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
myList.setLayoutManager(layoutManager);
instead of :-
recyclerView.setLayoutManager(new LinearLayoutManager(this));

Categories

Resources