This question already has an answer here:
Android - null object reference when iterating List
(1 answer)
Closed 5 years ago.
i want parse json with retrofit2 but my code dose not work
this web service is:(please check the webservice):
http://services.groupkt.com/country/search?text=
this is my model class:
public class Country {
#SerializedName("name")
#Expose
private String name;
#SerializedName("alpha2_code")
#Expose
private String alpha2Code;
#SerializedName("alpha3_code")
#Expose
private String alpha3Code;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAlpha2Code() {
return alpha2Code;
}
public void setAlpha2Code(String alpha2Code) {
this.alpha2Code = alpha2Code;
}
public String getAlpha3Code() {
return alpha3Code;
}
public void setAlpha3Code(String alpha3Code) {
this.alpha3Code = alpha3Code;
}
}
And:
public class CountryResponse {
#SerializedName("messages")
#Expose
private List<String> messages = null;
#SerializedName("result")
#Expose
private List<Country> countryList = null;
public List<String> getMessages() {
return messages;
}
public void setMessages(List<String> messages) {
this.messages = messages;
}
public List<Country> getCountryList() {
return countryList;
}
public void setCountryList(List<Country> countryList) {
this.countryList = countryList;
}
}
And:
public class Example {
#SerializedName("RestResponse")
#Expose
private CountryResponse restResponse;
public CountryResponse getRestResponse() {
return restResponse;
}
public void setRestResponse(CountryResponse restResponse) {
this.restResponse = restResponse;
}
}
And this is my interface class:
public interface APIInterface {
#GET("search?text=")
Call<Example> getCountries();
}
And i write 2 classes for return retrofit object:
public class APIClient {
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;
}
}
public class APIUtils {
public static final String BASE_URL =
"http://services.groupkt.com/country/";
public static APIInterface getSOService() {
return APIClient.getClient(BASE_URL).create(APIInterface.class);
}
}
My Adapter:
public class ResponseAdapter extends
RecyclerView.Adapter<ResponseAdapter.ViewHolder> {
private List<Example> mItems;
private Context mContext;
Example example;
CountryResponse countyResponse;
public ResponseAdapter(Context context, Example example) {
this.example = example;
mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item_list, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Example example = mItems.get(position);
TextView textView = holder.name;
textView.setText(example.getRestResponse()
.getCountryList().get(position).getName());
TextView textView1 = holder.alpha;
textView1.setText(example.getRestResponse().
getCountryList().get(position).getAl
pha2Code());
TextView textView2 = holder.alpha2;
textView2.setText(example.getRestResponse().
getCountryList().get(position).getAl
pha3Code());
}
#Override
public int getItemCount() {
return mItems.size();
}
public void updateAnswers(CountryResponse countryRes) {
countyResponse = countryRes;
notifyDataSetChanged();
}
private Example getItem(int adapterPosition) {
return mItems.get(adapterPosition);
}
public interface PostItemListener {
void onPostClick(long id);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView name, alpha, alpha2;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
alpha = (TextView) itemView.findViewById(R.id.alpha);
alpha2 = (TextView) itemView.findViewById(R.id.alpha2);
}
}
}
And My Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_response);
apiInterface= APIUtils.getSOService();
mRecyclerView= (RecyclerView) findViewById(R.id.my_recycler_view);
mAdapter=new ResponseAdapter(this,new Example());
RecyclerView.LayoutManager layoutManager = new
LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setHasFixedSize(true);
loadAnswers();
}
private void loadAnswers() {
apiInterface.getCountries().enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example>
response) {
mAdapter.updateAnswers(response.body().getRestResponse());
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
}
});
}
when run a error showing that
'java.util.Iterator java.util.List.iterator()' on a null object reference
You have
#Override
public int getItemCount() {
return mItems.size();
}
public void updateAnswers(CountryResponse countryRes) {
countyResponse = countryRes;
notifyDataSetChanged();
}
Your List is not initialized in the first place. Secondly you need to populate your List with items. And your list must be Country list not of type Example
You need to change to
public void updateAnswers(CountryResponse countryRes) {
mItems.addAll(countryRes.getCountryList())
notifyDataSetChanged();
}
And also initialize the list
List<Country> mItems = new ArrayList();
// note its of type Country not of Example
Finally update your views accordingly in onBindViewHolder
textView.setText(mItems.get(position).getName());
textView1.setText(mItems.get(position).getAlpha2Code());
textView2.setText(mItems.get(position).getAlpha3Code());
Related
The output is not displayed even if there is no error and I can't seem to comprehend where I am making a mistake. It will be helpful if someone finds my error in code and help me to rectify it
Model class
public class TopAnime {
private Integer malId;
private String url;
private String title;
private String titleEnglish;
private String titleJapanese;
public Integer getMalId() {
return malId;
}
public void setMalId(Integer malId) {
this.malId = malId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitleEnglish() {
return titleEnglish;
}
public void setTitleEnglish(String titleEnglish) {
this.titleEnglish = titleEnglish;
}
public String getTitleJapanese() {
return titleJapanese;
}
public void setTitleJapanese(String titleJapanese) {
this.titleJapanese = titleJapanese;
}
}
ApiService Interface
public interface ApiService {
//https://api.jikan.moe/v4/top/anime
#GET("top/anime")
Call<List<TopAnime>> getTopAnimeList(#Query("type") String type);
}
RetroInstance Class
public class RetroInstance {
public static String BASE_URL="https://api.jikan.moe/v4/";
private static Retrofit retrofit;
public static ApiService getApiService() {
if(retrofit == null ) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit.create(ApiService.class);
}
}
Adapter class
public class TopAnimeAdapter extends RecyclerView.Adapter<TopAnimeAdapter.TopAnimeViewHolder>{
private Context context;
private List<TopAnime> topAnimeList;
public TopAnimeAdapter(Context context, List<TopAnime> topAnimeList) {
this.context = context;
this.topAnimeList = topAnimeList;
}
#NonNull
#Override
public TopAnimeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.anime_list, parent, false);
return new TopAnimeViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull TopAnimeViewHolder holder, int position) {
// holder.animeTitle.setText(this.topAnimeList.get(position).getTitle().toString());
holder.animeTitle.setText(this.topAnimeList.get(position).getTitle());
}
#Override
public int getItemCount() {
if(this.topAnimeList != null){
return this.topAnimeList.size();
}
return 0;
}
public class TopAnimeViewHolder extends RecyclerView.ViewHolder {
TextView animeTitle;
public TopAnimeViewHolder(#NonNull View itemView) {
super(itemView);
animeTitle= itemView.findViewById(R.id.animeName);
}
}
}
MainActivity
I even tried to put the findAnime() at the top thinking the error was because I was adding the 'topAniemList' into the adapter even before the retrofit but it still gave the error
List<TopAnime> topAnimeList = new ArrayList<>();
private TopAnimeAdapter topAnimeAdapter;
RecyclerView recyclerView;
TextView noResult;
LinearLayoutManager linearLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findAnime();
topAnimeAdapter = new TopAnimeAdapter(this,topAnimeList);
noResult= findViewById(R.id.noResultTv);
recyclerView= findViewById(R.id.animeRecyclerView);
linearLayoutManager= new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(topAnimeAdapter);
}
private void findAnime(){
RetroInstance.getApiService().getTopAnimeList("tv").enqueue(new Callback<List<TopAnime>>() {
#Override
public void onResponse(Call<List<TopAnime>> call, Response<List<TopAnime>> response) {
if(response.isSuccessful()){
topAnimeList.addAll(response.body());
noResult.setVisibility(View.GONE);
}
else {
noResult.setVisibility(View.VISIBLE);
}
}
#Override
public void onFailure(Call<List<TopAnime>> call, Throwable t) {
Toast.makeText(MainActivity.this,"Error" + t.getMessage(), Toast.LENGTH_SHORT)
.show();
}
});
}
}
Try this - you have to pass the updated list to the adaptor and notify it
Create the below method in the Adapter class
updateList(List<TopAnime> list){
topAnimeList;
notifyDataSetChanged();
}
Call adaptor method updateList() from findAnime() method in MainActivity.java
private void findAnime(){
RetroInstance.getApiService().getTopAnimeList("tv").enqueue(new Callback<List<TopAnime>>() {
#Override
public void onResponse(Call<List<TopAnime>> call, Response<List<TopAnime>> response) {
if(response.isSuccessful()){
topAnimeList.addAll(response.body());
topAnimeAdapter.updateList(topAnimeList);
noResult.setVisibility(View.GONE);
}
else {
noResult.setVisibility(View.VISIBLE);
}
}
#Override
public void onFailure(Call<List<TopAnime>> call, Throwable t) {
Toast.makeText(MainActivity.this,"Error" + t.getMessage(), Toast.LENGTH_SHORT)
.show();
}
});
I need some help with two of my recycler views(one named "recentRecycler", and the other "topPlacesRecycler").My question is, how do I make to be redirected on a specific Activity when I click a specific item from the recycler. For example:
1- when I click the first item from the "recentRecycler" to be redirected to "Parlament.class"
2- when I click the first item from the "topPlacesRecycler" to be redirected to "Ramada.class"
etc.
My Main Activity which is named "BUCint" (The code from the bottom is from a drawerlayout that I use for my project)
public class BUCint extends AppCompatActivity {
DrawerLayout drawerLayout;
RecyclerView recentRecycler, topPlacesRecycler;
RecentsAdapter recentsAdapter;
TopPlacesAdapter topPlacesAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buc_int);
drawerLayout = findViewById(R.id.drawer_layout);
List<RecentsData> recentsDataList = new ArrayList<>();
recentsDataList.add(new RecentsData("Palatul Parlamentului","Cladire administrativă","40 lei",R.drawable.palatulparlamentului));
recentsDataList.add(new RecentsData("Arcul de Triumf","Monument istoric","Gratis",R.drawable.arctriumf));
recentsDataList.add(new RecentsData("Carturesti Carusel","Librarie","Gratis",R.drawable.carturesti));
recentsDataList.add(new RecentsData("Parcul Herăstrău","Parc","Gratis",R.drawable.parculherastrau));
recentsDataList.add(new RecentsData("Parcul Cișmigiu","Parc","Gratis",R.drawable.parculcismigiu));
recentsDataList.add(new RecentsData("Muzeul Antipa","Muzeu","20 lei",R.drawable.muzeulantipa));
setRecentRecycler(recentsDataList);
List<TopPlacesData> topPlacesDataList = new ArrayList<>();
topPlacesDataList.add(new TopPlacesData("Ramada Parc","Sectorul 1","227 lei",R.drawable.ramadaparc));
topPlacesDataList.add(new TopPlacesData("Berthelot","Sectorul 1","207 lei",R.drawable.bethelot));
topPlacesDataList.add(new TopPlacesData("Union Plaza","Centru","215 lei",R.drawable.unionplaza));
topPlacesDataList.add(new TopPlacesData("Rin Grande","Sectorul 4","223 lei",R.drawable.ringrande));
topPlacesDataList.add(new TopPlacesData("Hilton Garden","Centru","240 lei",R.drawable.hiltongarden));
setTopPlacesRecycler(topPlacesDataList);
}
private void setRecentRecycler(List<RecentsData> recentsDataList){
recentRecycler = findViewById(R.id.recent_recycler);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
recentRecycler.setLayoutManager(layoutManager);
recentsAdapter = new RecentsAdapter(this, recentsDataList);
recentRecycler.setAdapter(recentsAdapter);
}
private void setTopPlacesRecycler(List<TopPlacesData> topPlacesDataList){
topPlacesRecycler = findViewById(R.id.top_places_recycler);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
topPlacesRecycler.setLayoutManager(layoutManager);
topPlacesAdapter = new TopPlacesAdapter(this, topPlacesDataList);
topPlacesRecycler.setAdapter(topPlacesAdapter);
}
public void ClickMenu(View view){
BUCM.openDrawer(drawerLayout);
}
public void ClickLogo(View view){
BUCM.closeDrawer(drawerLayout);
}
public void ClickHome(View view){
BUCM.redirectActivity(this, Acasa.class);
}
public void ClickLinii(View view){
BUCM.redirectActivity(this,BUClinii.class);
}
public void ClickPreturi(View view){
BUCM.redirectActivity(this, BUCpreturi.class);
}
public void Clickint(View view){
recreate();
}
public void ClickSetari(View view) {
BUCM.redirectActivity(this, Setari.class);
}
public void ClickInformatii(View view){
BUCM.redirectActivity(this, Informatii.class);
}
public void ClickLogout(View view){
BUCM.logout(this);
}
#Override
protected void onPause(){
super.onPause();
BUCM.closeDrawer(drawerLayout);
}
}
The Adapter for recentRecycler, named RecentsAdapter
public class RecentsAdapter extends RecyclerView.Adapter<RecentsAdapter.RecentsViewHolder> {
Context context;
List<RecentsData> recentsDataList;
public RecentsAdapter(Context context, List<RecentsData> recentsDataList) {
this.context = context;
this.recentsDataList = recentsDataList;
}
#NonNull
#Override
public RecentsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recents_row_item, parent, false);
return new RecentsViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RecentsViewHolder holder, int position) {
holder.countryName.setText(recentsDataList.get(position).getCountryName());
holder.placeName.setText(recentsDataList.get(position).getPlaceName());
holder.price.setText(recentsDataList.get(position).getPrice());
holder.placeImage.setImageResource(recentsDataList.get(position).getImageUrl());
}
#Override
public int getItemCount() {
return recentsDataList.size();
}
public static final class RecentsViewHolder extends RecyclerView.ViewHolder{
ImageView placeImage;
TextView placeName, countryName, price;
public RecentsViewHolder(#NonNull View itemView) {
super(itemView);
placeImage = itemView.findViewById(R.id.place_image);
placeName = itemView.findViewById(R.id.place_name);
countryName = itemView.findViewById(R.id.country_name);
price = itemView.findViewById(R.id.price);
}
}
}
The DataModel for recentRecycler, named RecentsData
package com.example.spinner.model;
public class RecentsData {
String placeName;
String countryName;
String price;
Integer imageUrl;
public Integer getImageUrl() {
return imageUrl;
}
public void setImageUrl(Integer imageUrl) {
this.imageUrl = imageUrl;
}
public RecentsData(String placeName, String countryName, String price, Integer imageUrl) {
this.placeName = placeName;
this.countryName = countryName;
this.price = price;
this.imageUrl = imageUrl;
}
public String getPlaceName() {
return placeName;
}
public void setPlaceName(String placeName) {
this.placeName = placeName;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
The Adapter for topPlacesRecycler, named TopPlacesAdapter
public class TopPlacesAdapter extends RecyclerView.Adapter<TopPlacesAdapter.TopPlacesViewHolder> {
Context context;
List<TopPlacesData> topPlacesDataList;
public TopPlacesAdapter(Context context, List<TopPlacesData> topPlacesDataList) {
this.context = context;
this.topPlacesDataList = topPlacesDataList;
}
#NonNull
#Override
public TopPlacesViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.top_places_row_item, parent, false);
return new TopPlacesViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull TopPlacesViewHolder holder, int position) {
holder.countryName.setText(topPlacesDataList.get(position).getCountryName());
holder.placeName.setText(topPlacesDataList.get(position).getPlaceName());
holder.price.setText(topPlacesDataList.get(position).getPrice());
holder.placeImage.setImageResource(topPlacesDataList.get(position).getImageUrl());
}
#Override
public int getItemCount() {
return topPlacesDataList.size();
}
public static final class TopPlacesViewHolder extends RecyclerView.ViewHolder{
ImageView placeImage;
TextView placeName, countryName, price;
public TopPlacesViewHolder(#NonNull View itemView) {
super(itemView);
placeImage = itemView.findViewById(R.id.place_image);
placeName = itemView.findViewById(R.id.place_name);
countryName = itemView.findViewById(R.id.country_name);
price = itemView.findViewById(R.id.price);
}
}
}
The DataModel for topPlacesRecycler, named TopPlacesData
public class TopPlacesData {
String placeName;
String countryName;
String price;
Integer imageUrl;
public Integer getImageUrl() {
return imageUrl;
}
public void setImageUrl(Integer imageUrl) {
this.imageUrl = imageUrl;
}
public TopPlacesData(String placeName, String countryName, String price, Integer imageUrl) {
this.placeName = placeName;
this.countryName = countryName;
this.price = price;
this.imageUrl = imageUrl;
}
public String getPlaceName() {
return placeName;
}
public void setPlaceName(String placeName) {
this.placeName = placeName;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
I'm pretty new with Android Studio so every feedback would be gladly accepted.
Thanks in advance!
The best solution that does not overload the adapter would be to use interface.
Declare an interface in your adapter like this...
public class RecentsAdapter extends RecyclerView.Adapter<RecentsAdapter.RecentsViewHolder> {
Context context;
List<RecentsData> recentsDataList;
private RecentsAdapter.OnRecentItemclickListener listener;
public void setOnRecentItemclickListener(RecentsAdapter.OnRecentItemclickListener listener){
this.listener = listener;
}
public RecentsAdapter(Context context, List<RecentsData> recentsDataList) {
this.context = context;
this.recentsDataList = recentsDataList;
}
#NonNull
#Override
public RecentsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recents_row_item, parent, false);
return new RecentsViewHolder(view, listener);
}
#Override
public void onBindViewHolder(#NonNull RecentsViewHolder holder, int position) {
holder.countryName.setText(recentsDataList.get(position).getCountryName());
holder.placeName.setText(recentsDataList.get(position).getPlaceName());
holder.price.setText(recentsDataList.get(position).getPrice());
holder.placeImage.setImageResource(recentsDataList.get(position).getImageUrl());
}
#Override
public int getItemCount() {
return recentsDataList.size();
}
public static final class RecentsViewHolder extends RecyclerView.ViewHolder{
ImageView placeImage;
TextView placeName, countryName, price;
public RecentsViewHolder(#NonNull View itemView, RecentsAdapter.OnRecentItemclickListener listener) {
super(itemView);
placeImage = itemView.findViewById(R.id.place_image);
placeName = itemView.findViewById(R.id.place_name);
countryName = itemView.findViewById(R.id.country_name);
price = itemView.findViewById(R.id.price);
itemView.setOnclickListener( -> {
if(listner == null)return;
int pos = getAdapterposition()
if(pos == RecyclerView.NO_POSITION)return;
listner.onRecentItemclickListener(pos);
});
}
}
public interface OnRecentItemclickListener {
void onRecentItemClickListener(int position);
}
}
Add then in you activity
private void setRecentRecycler(List<RecentsData> recentsDataList){
recentRecycler = findViewById(R.id.recent_recycler);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
recentRecycler.setLayoutManager(layoutManager);
recentsAdapter = new RecentsAdapter(this, recentsDataList);
recentRecycler.setAdapter(recentsAdapter);
recentsAdapter.setOnRecentItemclickListener(this::onOpenParlamentClass)
}
private void onOpenParlamentClass(int position){
//perform your intent here. you can also get the clicked item using the position of the data list and pass it to the receiving activity
}
Happy coding. If you are new to android you can also consider Kotlin.
public static final class RecentsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView placeImage;
TextView placeName, countryName, price;
public RecentsViewHolder(#NonNull View itemView) {
super(itemView);
placeImage = itemView.findViewById(R.id.place_image);
placeName = itemView.findViewById(R.id.place_name);
countryName = itemView.findViewById(R.id.country_name);
price = itemView.findViewById(R.id.price);
itemView.setOnClickListener(this);
//you can do same code for another recyclerview.
}
#Override
public void onClick(View view) {
Intent intent = new Intent(context, Parlament.class);
view.getContext().startActivity(intent);
}
}
I want to display images from https://picsum.photos/ into the imageView using recyclerView. Note that "https://picsum.photos/200" gets you a random square (200x200) image. I'm not sure if I'm using Glide and retrofit correctly (for arraylist with links it worked perfectly). I apriciate any hints. Thanks!
Edit: link to repo with all code: https://github.com/LightingTT/RecycleViewPictures
This is my ApiService:
public interface ApiService {
#GET("200/")
Call<List<Pictures>> getFile();
ApiClient:
public class ApiClient {
public static String BASE_URL = "https://picsum.photos/";
private static Retrofit retrofit;
public static Retrofit getClient(){
if(retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
Object class:
public class Pictures {
#SerializedName("picture")
private String picturesUrl;
public Pictures (String picturesUrl)
{
this.picturesUrl = picturesUrl;
}
public String getImageUrl() {
return picturesUrl;
}
Adapter:
public class MyRecycleAdapter extends RecyclerView.Adapter<MyRecycleAdapter.ViewHolderClass> {
private static final String TAG = "MainActivity";
private Context context;
private List<Pictures> imageList;
//Constructor
public MyRecycleAdapter(Context context, List<Pictures> imageList)
{
this.context = context;
this.imageList = imageList;
}
//
public void setMyRecycleAdapter(List<Pictures> imageList)
{
this.imageList = imageList;
notifyDataSetChanged();
}
#NonNull
#Override
public ViewHolderClass onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.single_picture_view, parent, false);
ViewHolderClass linearViewHolderClass = new ViewHolderClass(view);
return linearViewHolderClass;
}
#Override
public void onBindViewHolder(#NonNull ViewHolderClass holder, int position) {
Glide
.with(context)
.load(imageList.get(position).getImageUrl())
.into(holder.imageView);
Log.d(TAG, "onBindViewHolder: ------>called<-----");
}
#Override
public int getItemCount() {
return imageList.size();
}
public class ViewHolderClass extends RecyclerView.ViewHolder{
private ImageView imageView;
//Constructor
public ViewHolderClass(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.single_picture_id);
}
}
And MainActivity:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
MyRecycleAdapter recyclerAdapter;
List<Pictures> imageList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageList = new ArrayList<>();
//Create RecycleView object and pin view
RecyclerView recycleView = findViewById(R.id.linear_layout_with_recycleView_ID);
GridLayoutManager linearLayoutManager = new GridLayoutManager (this, 2);
//Setup Adapter
recycleView.setLayoutManager(linearLayoutManager);
recyclerAdapter = new MyRecycleAdapter(MainActivity.this, imageList);
recycleView.setAdapter(recyclerAdapter);
Log.d(TAG, "onCreate: ------>called<-----");
//Creating reference for MyService and receiving deserialized data.
ApiService apiClient = ApiClient.getClient().create(ApiService.class);
Call<List<Pictures>> call = apiClient.getFile();
call.enqueue(new Callback<List<Pictures>>() {
#Override
public void onResponse(Call<List<Pictures>> call, Response<List<Pictures>> response) {
imageList = response.body();
Log.d(TAG, "onResponse: ------>called<-----");
recyclerAdapter.setMyRecycleAdapter(imageList);
}
#Override
public void onFailure(Call<List<Pictures>> call, Throwable t) {
Log.d("TAG","onFailure = ------>called<----- "+t.toString());
}
});
}
}
It seems that I was asking wrong api. It should be
public interface ApiService {
#GET("/v2/list")
Call<List<Pictures>> getFile();
}
And object class was wrong. Generated by http://www.jsonschema2pojo.org/
public class Pictures {
#SerializedName("id")
#Expose
private String id;
#SerializedName("author")
#Expose
private String author;
#SerializedName("width")
#Expose
private Integer width;
#SerializedName("height")
#Expose
private Integer height;
#SerializedName("url")
#Expose
private String url;
#SerializedName("download_url")
#Expose
private String downloadUrl;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
}
Now it works and displays nice random pictures in gridview.
My RecyclerView not show any data from Firebase. I don't see any errors at logcat so I don't know why. I followed guide from youtube video. But still nothing. I'm using android 8.0 and API 27. Hope Somebody can help.
My Main Activity Code:
public class ViewProduct extends AppCompatActivity {
DatabaseReference ref;
ArrayList<Model> list;
private RecyclerView recyclerView;
private RecyclerView.Adapter viewHolder;
private RecyclerView.LayoutManager layoutManager;
SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_product) ;
ref = FirebaseDatabase.getInstance().getReference().child("buddymealplanneruser").
child("Products");
recyclerView = findViewById(R.id.stallproductRecyclerView);
//recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//SEARCH VIEW
searchView = findViewById(R.id.searchProductStall);
//ADAPTER
list = new ArrayList<>();
viewHolder = new ViewHolder(list);
recyclerView.setAdapter(viewHolder);
}
#Override
protected void onRestart() {
super.onRestart();
if (ref!=null)
{
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
//list = new ArrayList<>();
list.clear();
for(DataSnapshot ds : dataSnapshot.getChildren())
{
list.add(ds.getValue(Model.class));
}
//ViewHolder viewHolder = new ViewHolder(list);
//recyclerView.setAdapter(viewHolder);
viewHolder.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(ViewProduct.this, databaseError.getMessage(),
Toast.LENGTH_SHORT).show();
}
});
}
if (searchView !=null)
{
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s)
{
return false;
}
#Override
public boolean onQueryTextChange(String s) {
search(s);
return true;
}
});
}
}
private void search(String str) {
ArrayList<Model> myList = new ArrayList<>();
for(Model object : list)
{
if(object.getProductName().toLowerCase().contains(str.toLowerCase()))
{
myList.add(object);
}
}
ViewHolder viewHolder = new ViewHolder(myList);
recyclerView.setAdapter(viewHolder);
}
}
My Adapter:
public class ViewHolder extends RecyclerView.Adapter<ViewHolder.MyViewHolder> {
ArrayList<Model> list;
public ViewHolder (ArrayList<Model> list)
{
this.list=list;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_product, viewGroup,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.productName.setText(list.get(i).getProductName());
myViewHolder.productCalorie.setText(list.get(i).getProductCalorie());
myViewHolder.StallId.setText(list.get(i).getStallId());
myViewHolder.productType.setText(list.get(i).getProductType());
myViewHolder.productServing.setText(list.get(i).getProductServing());
myViewHolder.statusProduct.setText(list.get(i).getStatusProduct());
}
#Override
public int getItemCount()
{
return list.size();
}
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView productName, productCalorie, StallId;
TextView productType, productServing, statusProduct;
ImageView productImageView;
public MyViewHolder (#NonNull View itemView){
super((itemView));
productName = itemView.findViewById(R.id.productTitle);
productCalorie = itemView.findViewById(R.id.productDescriptionCalorie);
StallId = itemView.findViewById(R.id.productDescriptionStallId);
productType = itemView.findViewById(R.id.productDescriptionType);
productServing=itemView.findViewById(R.id.productDescriptionServing);
statusProduct=itemView.findViewById(R.id.productDescriptionAvailibility);
//productImageView = itemView.findViewById(R.id.productImageView);
}
}
}
My Model :
package com.example.buddymealplannerstall.Child;
import android.view.Display;
public class Model {
//String productName, productImage, productCalorie, StallId, productType, productServing, statusProduct;
private String StallId;
private String productCalorie;
private String productImage;
private String productName;
private String productServing;
private String productType;
private String statusProduct;
public Model (String StallId,
String productCalorie,
String productImage,
String productName,
String productServing,
String productType,
String statusProduct){
this.StallId = StallId;
this.productCalorie = productCalorie;
this.productImage = productImage;
this.productName = productName;
this.productServing = productServing;
this.productType = productType;
this.statusProduct = statusProduct;
}
public Model(){
}
public String getStallId() {
return StallId;
}
public void setStallId(String stallId) {
StallId = stallId;
}
public String getProductCalorie() {
return productCalorie;
}
public void setProductCalorie(String productCalorie) {
this.productCalorie = productCalorie;
}
public String getProductImage() {
return productImage;
}
public void setProductImage(String productImage) {
this.productImage = productImage;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductServing() {
return productServing;
}
public void setProductServing(String productServing) {
this.productServing = productServing;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
public String getStatusProduct() {
return statusProduct;
}
public void setStatusProduct(String statusProduct) {
this.statusProduct = statusProduct;
}
}
Screen Shot of my firebase and my apps.
firebase
my app
According to your comment:
yes, buddymealplanner is my project's name
Please note that there is no need to add the name of your project as a child in the reference. So please change the following line of code:
ref = FirebaseDatabase.getInstance().getReference().child("buddymealplanneruser").
child("Products");
Simply to:
ref = FirebaseDatabase.getInstance().getReference().child("Products");
I dont think you are populating your list, you are sending it empty. From what I can see, you only add items to the list when you are restarting the activity. Try either populating it before sendinig the list, or changing the onRestart() for an onStart() or an onResume().
I can't understand why it makes problem with it. It take data from server with retrofit and it can't use that data in recyclerview. It make problem with Constructor but I can not understand why it makes problem with it. That can get data from service successfully with this Model, but problem is to put adapter and recyclierview. How can solve it?
ProductPage.java
public class ProductPage {
private int productID;
private String productName;
private String productDescription;
private List<String> productImages;
private List<ProductPrice> productPrices;
public int getProductID() {
return productID;
}
public void setProductID(int productID) {
this.productID = productID;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductDescription() {
return productDescription;
}
public void setProductDescription(String productDescription) {
this.productDescription = productDescription;
}
public List<String> getProductImages() {
return productImages;
}
public void setProductImages(List<String> productImages) {
this.productImages = productImages;
}
public List<ProductPrice> getProductPrices() {
return productPrices;
}
public void setProductPrices(List<ProductPrice> productPrices) {
this.productPrices = productPrices;
}
}
ProductDetailAdapter.java
public class ProductDetailAdapter extends RecyclerView.Adapter<ProductDetailAdapter.ViewHolder> {
private Context mContext;
int rawLayout;
private List<ProductPage> productPageList;
private int cartAmount;
public ProductDetailAdapter(Context mContext,int rawLayout, List<ProductPage> productPageList, CartListener cartListener) {
this.mContext = mContext;
this.rawLayout = rawLayout;
this.productPageList = productPageList;
this.cartListener = cartListener;
}
#NonNull
#Override
public ProductDetailAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View mView = LayoutInflater.from(parent.getContext()).inflate(rawLayout, parent, false);
return new ViewHolder(mView); }
#Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
Glide.with(mContext).load(productPageList.get(position).getProductPrices().get(position).getShopImage())
.apply(RequestOptions.placeholderOf(R.drawable.ic_glide_img).error(R.drawable.ic_glide_warning)).
into(viewHolder.imgProductDetail);
viewHolder.textProductDetailCost.setText(Double.toString(productPageList
.get(position).getProductPrices().get(position).getShopProductPrice())+" TL");
viewHolder.textProductDetailMarket.setText(productPageList.get(position).getProductPrices().get(position).getShopName());
}
#Override
public int getItemCount() {
return productPageList.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
private ImageView imgProductDetail;
private TextView textProductDetailCost, textProductDetailMarket;
private Button btnProductDetail;
private CardView cardViewProductDetail;
ViewHolder(View itemView){
super(itemView);
imgProductDetail = itemView.findViewById(R.id.imageView_product_detail);
textProductDetailCost = itemView.findViewById(R.id.text_product_detail_cost);
textProductDetailMarket = itemView.findViewById(R.id.textViewProductShopName);
btnProductDetail = itemView.findViewById(R.id.buttonProductDetail);
cardViewProductDetail = itemView.findViewById(R.id.cardViewProductDetail);
}
}
public interface CartListener {
void onProductSelect(ProductPage productPage);
}
}
ProductActivity.java
public class ProductActivity extends AppCompatActivity implements ProductDetailAdapter.CartListener {
TextView textProductName, textDescription;
RecyclerView recyclerViewProduct;
protected RecyclerView.LayoutManager mLayoutManager;
String productCost, productMarket, productImage, productTitle, prdouctMarketImage;
int id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product);
init();
loadProductPage();
}
private void init() {
textProductName = findViewById(R.id.text_product_title);
imgProduct = findViewById(R.id.img_product);
recyclerViewProduct = findViewById(R.id.product_recycylerwiew);
textDescription = findViewById(R.id.text_product_description);
textDescription.setMovementMethod(new ScrollingMovementMethod()); // Scroll yapabilmek için açmıştım
mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerViewProduct.setLayoutManager(mLayoutManager);
private void loadProductPage() {
ApiInterface apiInterface = ApiClient.getRetrofitInstance().create(ApiInterface.class);
Call<ProductPage> call = apiInterface.getProductPage(id);
call.enqueue(new Callback<ProductPage>() {
#Override
public void onResponse(Call<ProductPage> call, Response<ProductPage> response) {
if (response.isSuccessful()) {
ProductPage product_page_list = response.body();
textProductName.setText(product_page_list.getProductName());
textDescription.setText(product_page_list.getProductDescription());
Glide.with(getApplicationContext()).load(product_page_list.getProductImages())
.apply(RequestOptions.placeholderOf(R.drawable.ic_glide_img).error(R.drawable.ic_glide_warning)).
into(imgProduct);
ProductDetailAdapter myAdapter = new ProductDetailAdapter(getApplicationContext(),R.layout.product_detail_item_view,product_page_list,ProductActivity.this);
recyclerViewProduct.setAdapter(myAdapter);
}
else
ApiErrorUtils.parseError(response);
}
#Override
public void onFailure(Call<ProductPage> call, Throwable t) {
Log.d("response","apiError");
}
});
}
#Override
public void onProductSelect(ProductPage productPage) {
}
You are just passing ProductPage object to adapter.
ProductPage product_page_list = response.body();
but your adapter required
List<ProductPage> productPageList
So you need to add product object to product list like this
ProductPage productPage = response.body();
List<ProductPage> productList=new ArrayList<>();
productList.add(productPage);
ProductPage product_page_list = response.body();
product_page_list is not List<ProductPage>()
in your adapter need List<ProductPage> productPageList