Android Retrofit parsing - android

i just followed exapmple :
https://www.learn2crack.com/2016/02/recyclerview-json-parsing.html
its working great ..i want to parse
[
{
"song_name": "Hero",
"song_id": "1990",
"artist_name": "Enrique"
},{
"song_name": "African Queen",
"song_id": "2004",
"artist_name": "Tuface"
}, {
"song_name": "Ifunanyi",
"song_id": "2012",
"artist_name": "PSquare"
}
]
Here is my code am getting blank..Am new to android
Give some ideas nothing else i want..Any one please guide me
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ArrayList<ItemObject> data;
private MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews(){
recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
loadJSON();
}
private void loadJSON(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://toscanyacademy.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface request = retrofit.create(RequestInterface.class);
Call<JSONResponse> call = request.getJSON();
call.enqueue(new Callback<JSONResponse>() {
#Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
JSONResponse jsonResponse = response.body();
data = new ArrayList<>(Arrays.asList(jsonResponse.getAndroid()));
adapter = new MyAdapter(data);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<JSONResponse> call, Throwable t) {
Log.d("Error",t.getMessage());
}
});
}
}
My Request interface:
public interface RequestInterface {
#GET("blog/mp.php")
Call<JSONResponse> getJSON();
}
Json Response:
public class JSONResponse {
private ItemObject[] obj;
public ItemObject[] getAndroid() {
return obj;
}
}
public class ItemObject {
public String getSong_name() {
return song_name;
}
public String getSong_id() {
return song_id;
}
public String getArtist_name() {
return artist_name;
}
private String song_name,song_id,artist_name;
}
Here is my Adapter:
public class MyAdapter extends RecyclerView.Adapter {
private ArrayList<ItemObject> users;
public MyAdapter(ArrayList<ItemObject> first) {
this.users = first;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int i) {
viewHolder.song_title.setText(users.get(i).getsong_name());
viewHolder.song_id.setText(users.get(i).getsong_id());
viewHolder.song_author.setText(users.get(i).getartist_name());
}
#Override
public int getItemCount() {
return users.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView song_title, song_id, song_author;
public ViewHolder(View view) {
super(view);
song_title = (TextView) view.findViewById(R.id.song_name);
song_id = (TextView) view.findViewById(R.id.song_id);
song_author=(TextView) view.findViewById(R.id.artist_name);
}
}
}
Row Layout:
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
card_view:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical">
<TextView
android:id="#+id/song_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:textColor="#000"
android:layout_marginTop="20dp" />
<TextView
android:id="#+id/song_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:textColor="#000"
/>
<TextView
android:id="#+id/artist_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:textColor="#000" />

Create your POJO class:
Example.java
#Generated("org.jsonschema2pojo")
public class Example {
#SerializedName("song_name")
#Expose
private String songName;
#SerializedName("song_id")
#Expose
private String songId;
#SerializedName("artist_name")
#Expose
private String artistName;
public String getSongName() {
return songName;
}
public void setSongName(String songName) {
this.songName = songName;
}
public String getSongId() {
return songId;
}
public void setSongId(String songId) {
this.songId = songId;
}
public String getArtistName() {
return artistName;
}
public void setArtistName(String artistName) {
this.artistName = artistName;
}
}
In your interface:
public interface RequestInterface {
#GET("blog/mp.php")
Call<List<Example>> getJSON();
}
And in your activity:
ArrayList<Example> arrayList = new ArrayList<>();
//Inside loadJSON()
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://toscanyacademy.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface request = retrofit.create(RequestInterface.class);
Call<List<Example>> listCall = request.getJSON();
listCall.enqueue(new Callback<List<Example>>() {
#Override
public void onResponse(Call<List<Example>> call, Response<List<Example>> response) {
for (int i = 0; i < response.body().size(); i++) {
Example example = new Example();
example.setArtistName(response.body().get(i).getArtistName());
example.setSongId(response.body().get(i).getSongId());
example.setSongName(response.body().get(i).getSongName());
arrayList.add(example);
}
adapter = new MyAdapter(arrayList);
recyclerView.setAdapter(adapter);
}
#Override
public void onFailure(Call<List<Example>> call, Throwable t) {
Log.d("Error",t.getMessage());
}
});

Retrofit saves you the trouble of parsing the json response.
Inorder to parse the json response, the Modal class should be named accordingly.
You can see in the example you followed, that the modal class variables are named after thejsonObjects in the response.
In your case,
the variables should be song_name, song_id, artist_name.
Try changing the modal class according to you response.
Hope this helps..! Happy coding :)

.baseUrl("http://toscanyacademy.com")
Try with .baseUrl("http://toscanyacademy.com/")
becasue when retrofit builds url it is like this in your situation
http://toscanyacademy.comblog/mp.php

Try to change as below if it helps:
private void initViews(){
recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
data = new ArrayList<>();
adapter = new MyAdapter(data);
recyclerView.setAdapter(adapter);
loadJSON();
}
RequestInterface request = retrofit.create(RequestInterface.class);
Call<List<ItemObject>> call = request.getJSON();
call.enqueue(new Callback<List<ItemObject>>() {
#Override
public void onResponse(Call<List<ItemObject>> call, Response<List<ItemObject>> response) {
for(ItemObject obj: response.body()) {
data.add(obj);
}
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<List<ItemObject>> call, Throwable t) {
Log.d("Error",t.getMessage());
}
});

Related

Data is not showing in recycler view from an api

I am trying to fetch data from server and showing it in recycler view.I am using retrofit library and RxJava2 but its unable to fetch data from server.
Its showing following line in LogCat:
E/RecyclerView: No adapter attached; skipping layout
Response form the server:
[
{
"term_id": "4",
"name": "Entertainment"
},
{
"term_id": "5",
"name": "Tech & Gadgets"
},
{
"term_id": "6",
"name": "Sports"
},
{
"term_id": "7",
"name": "Health and Fitness Tips"
}
]
Below is my code:
RetrofitClient.java
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getInstance(){
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(22,TimeUnit.SECONDS)
.readTimeout(22, TimeUnit.SECONDS)
.writeTimeout(22, TimeUnit.SECONDS)
.build();
if(retrofit == null)
retrofit = new Retrofit.Builder()
.baseUrl("https://www.flypped.com/api/")
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
return retrofit;
}
}
ApiService.class
public interface ApiService {
#GET("Categoery_api")
Observable<List<Model>> getData();
}
Model.java
public class Model {
#SerializedName("catId")
#Expose
String catId;
#SerializedName("catName")
#Expose
String catName;
public Model(){
}
public Model(String catId, String catName) {
this.catId = catId;
this.catName = catName;
}
public String getCatId() {
return catId;
}
public void setCatId(String catId) {
this.catId = catId;
}
public String getCatName() {
return catName;
}
public void setCatName(String catName) {
this.catName = catName;
}
}
MainActivity.java
private void fetchData(){
Retrofit retrofit = RetrofitClient.getInstance();
ApiService myApi = retrofit.create(ApiService.class);
myApi.getData().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Model>>() {
#Override
public void onSubscribe(Disposable d) {
d.dispose();
}
#Override
public void onNext(List<Model> models) {
if(models.size() > 0){
progress.setVisibility(View.INVISIBLE);
adapter = new PostAdapter(getApplicationContext(),list);
recycler.setAdapter(adapter);
}
}
#Override
public void onError(Throwable e) {
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
#Override
public void onComplete() {
}
});
}
PostAdapter.java
public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder> {
List<Model> list = new ArrayList<>();
Context context;
public PostAdapter(Context context,List<Model> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public PostAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_row,parent,false);
ViewHolder view = new ViewHolder(v);
return view;
}
#Override
public void onBindViewHolder(#NonNull PostAdapter.ViewHolder holder, int position) {
Model model = list.get(position);
holder.catName.setText(model.getCatName());
holder.catId.setText(model.getCatId());
}
#Override
public int getItemCount() {
return list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView catId,catName,comp,titl;
public ViewHolder(#NonNull View itemView) {
super(itemView);
catId = itemView.findViewById(R.id.catId);
catName = itemView.findViewById(R.id.catName);
}
}
}
Someone please let me know what I am doing wrong any help would be appreciated.
THANKS
You are calling d.dispose(); in onSubscribe which will dispose the resource and result so remove dispose call as
public void onSubscribe(Disposable d) {
//d.dispose(); remove it
}
you can move dispose in onDestroy to free up resources(JIC request is still running) when activity(or fragment) is going to be removed from memory and make sure you have layout manager set on recycler view.

No data by using RecylcerView and Retrofit2 latest

I'm new to retrofit2 android. I'm trying to work around an app which displays earthquake information using retrofit and RecyclerView. But I'm unable to display any data fetch from the URL in JSON format.
Most of the times I'm getting No adapter attached; skipping layout error. I've searched a lot but didn't get it resolve.
I'm using HttpLoggingInterceptor to see response. Response body of my JSON data is showing in Verbose of Logcat but not in RecyclerView.
Sometimes no error nothing in verbose everything blank even app is blank no data.
Help me please with my issue.
URL from which I'm fetching data. I limit it to 2 so that you can see it clearly.
https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&limit=2
This is my MainActivity.
public class EarthquakeActivity extends AppCompatActivity {
private static final String TAG = EarthquakeActivity.class.getSimpleName();
private RecyclerView recyclerView;
private List<Feature> featureList;
private DataAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG,"onCreate() method called...");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_earthquke);
recyclerView = findViewById(R.id.earthquake_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpClientBuilder.addInterceptor(loggingInterceptor);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://earthquake.usgs.gov/")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClientBuilder.build())
.build();
EarthquakeRequestInterface requestInterface = retrofit.create(EarthquakeRequestInterface.class);
Call<EarthquakeResponse> responseCall =requestInterface.getJSON("geojson");
responseCall.enqueue(new Callback<EarthquakeResponse>() {
#Override
public void onResponse(Call<EarthquakeResponse> call, Response<EarthquakeResponse> response) {
if (response.isSuccessful()){
EarthquakeResponse earthquakeResponse = response.body();
adapter = new DataAdapter(earthquakeResponse.getFeatures());
recyclerView.setAdapter(adapter);
}
else {
Toast.makeText(getApplicationContext(),"No data Found",Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<EarthquakeResponse> call, Throwable t) {
Log.e("Error",t.getMessage());
}
});
}
}`
This is my adapter class.
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private List<Feature> features;
public DataAdapter(List<Feature> features1) {
this.features = features1;
}
#NonNull
#Override
public DataAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.earthquake_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull DataAdapter.ViewHolder viewHolder, int i) {
viewHolder.earthquakeMag.setText(features.get(i).getProperties().getMag().toString());
viewHolder.earthquakePlace.setText(features.get(i).getProperties().getPlace());
viewHolder.earthquakeUrl.setText(features.get(i).getProperties().getUrl());
}
#Override
public int getItemCount() {
return features.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView earthquakeMag,earthquakePlace,earthquakeUrl;
public ViewHolder(View view) {
super(view);
earthquakeMag = view.findViewById(R.id.earthquake_mag);
earthquakePlace = view.findViewById(R.id.earthquake_place);
earthquakeUrl = view.findViewById(R.id.earthquake_url);
}
}
}
This is my API interface.
public interface EarthquakeRequestInterface {
#GET ("fdsnws/event/1/query")
Call<EarthquakeResponse> getJSON(#Query("format") String format);
}
This is my Response java class (POJO or Model class).
public class EarthquakeResponse {
#SerializedName("type")
#Expose
private String type;
#SerializedName("metadata")
#Expose
private Metadata metadata;
#SerializedName("features")
#Expose
private List<Feature> features = null;
#SerializedName("bbox")
#Expose
private List<Double> bbox = null;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Metadata getMetadata() {
return metadata;
}
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
}
public List<Feature> getFeatures() {
return features;
}
public void setFeatures(List<Feature> features) {
this.features = features;
}
public List<Double> getBbox() {
return bbox;
}
public void setBbox(List<Double> bbox) {
this.bbox = bbox;
}
}
This is my Feature class (POJO class)
public class Feature {
#SerializedName("type")
#Expose
private String type;
#SerializedName("properties")
#Expose
private Properties properties;
#SerializedName("geometry")
#Expose
private Geometry geometry;
#SerializedName("id")
#Expose
private String id;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Geometry getGeometry() {
return geometry;
}
public void setGeometry(Geometry geometry) {
this.geometry = geometry;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
This is Properties Java class (POJO class). It contains the data I'm interested in. I reduce it to only 3 for checking my code is working or not.
public class Properties {
#SerializedName("mag")
#Expose
private Double mag;
#SerializedName("place")
#Expose
private String place;
#SerializedName("url")
#Expose
private String url;
#SerializedName("detail")
#Expose
private String detail;
public Double getMag() {
return mag;
}
public void setMag(Double mag) {
this.mag = mag;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDetail() {
return detail;
}
}
There are other POJO classes like Geometry, Metadata which are present in JSON response but I'm not interested in it.
This is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for a list of earthquakes -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/earthquake_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</android.support.v7.widget.RecyclerView>
</LinearLayout>
This is my custom adapter layout file.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/earthquake_layout"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="16dp"
android:paddingTop="16dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/earthquake_mag"
android:layout_gravity="top"
android:textStyle="bold"
android:textSize="16sp"
android:textColor="#android:color/black"
android:paddingLeft="10dp"
android:paddingRight="10dp"
tools:text="Place"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/earthquake_place"
android:layout_gravity="top"
android:textStyle="bold"
android:textSize="16sp"
android:textColor="#android:color/black"
android:paddingLeft="10dp"
android:paddingRight="10dp"
tools:text="Place"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/earthquake_url"
android:layout_gravity="top"
android:textStyle="bold"
android:textSize="16sp"
android:textColor="#android:color/black"
android:paddingLeft="10dp"
android:paddingRight="10dp"
tools:text="Place"
/>
</LinearLayout>
Sorry for my bad English or any improper way of asking a question. I'm new to stackoverflow. I recently sign up.
Please really need some serious help to overcome this.
Try to set the adapter outside the Retrofit method. Something like this:
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
mItems = new ArrayList<Feature>;
adapter = new DataAdapter(mItems);
recyclerView.setAdapter(adapter);
// .. other code
EarthquakeRequestInterface requestInterface = retrofit.create(EarthquakeRequestInterface.class);
Call<EarthquakeResponse> responseCall =requestInterface.getJSON("geojson");
responseCall.enqueue(new Callback<EarthquakeResponse>() {
#Override
public void onResponse(Call<EarthquakeResponse> call, Response<EarthquakeResponse> response) {
if (response.isSuccessful()){
EarthquakeResponse earthquakeResponse = response.body();
mItems.addAll(earthquakeResponse.getFeatures());
adapter.notifyDatasetChanged();
} else {
Toast.makeText(getApplicationContext(),"No data Found",Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<EarthquakeResponse> call, Throwable t) {
Log.e("Error",t.getMessage());
}
});

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);

E/RecyclerView: No adapter attached; skipping layout when fetching Json Array

I have this strange issue. When i try to get data on my screen from database. It does not shows anything and goes my onFailure method in UsersHomeActivity class. My web service works fine when i try with Postman, i get all the data as Json Array. Also in Debug screen at LogCat i can see my response and request , they all correct. But when i click the bDisplayActivity, nothing shows and i see E/RecyclerView: No adapter attached; skipping layout.
My PHP WebService:
<?php
require_once ('viewConnection.php');
$status="status";
$message = "message";
$sql = "SELECT Activity_Name, Activity_StartDate, Activity_EndDate, Activity_Capacity, Activity_City,
Activity_Deadline_Abstract, Activity_Deadline_Notice, Activity_Deadline_CameraReady, Activity_Deadline_FullVersion FROM activity";
$res = mysqli_query($conn,$sql);
$result = array();
while($row = mysqli_fetch_array($res)){
array_push($result,
array('Activity_Name'=>$row[0], 'Activity_StartDate'=>$row[1],
'Activity_EndDate'=>$row[2], 'Activity_Capacity'=>$row[3], 'Activity_City'=>$row[4],
'Activity_Deadline_Abstract'=>$row[5], 'Activity_Deadline_Notice'=>$row[6],
'Activity_Deadline_CameraReady'=>$row[7], 'Activity_Deadline_FullVersion'=>$row[8],));
}
echo json_encode(array("Activity"=>$result,$status=>1,$message=>"Success"));
mysqli_close($conn);
?>
These are my codes:
my row list item layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="horizontal"
android:padding="5dp">
<TextView
android:id="#+id/tvActivity_Name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="#android:style/TextAppearance.Material.Body1" />
<TextView
android:id="#+id/tvActivity_StartDate"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvActivity_EndDate"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvActivity_Capacity"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvActivity_City"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvActivity_Deadline_Abstract"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvActivity_Deadline_Notice"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvActivity_Deadline_CameraReady"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tvActivity_Deadline_FullVersion"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
This my activity layout :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.furkankaracan.activityplanner.UserHomeActivity">
<Button
android:id="#+id/button_display_data_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Aktiviteleri Yükle" />
<android.support.v7.widget.RecyclerView
android:layout_marginTop="20dp"
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="300dp" />
</LinearLayout>
And my adapter and my activity class :
public class ActivityAdapter extends
RecyclerView.Adapter<ActivityAdapter.ViewHolder> {
private List<ActivityModel> dataList;
private Context context;
public ActivityAdapter(List<ActivityModel> dataList, Context context){
this.dataList = dataList;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View view = LayoutInflater.from(context).inflate(R.layout.list_view, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position){
ActivityModel model = dataList.get(position);
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
holder.tvActivity_Name.setText(model.getActivityName());
holder.tvActivity_StartDate.setText(df.format(model.getActivityStartDate()));
holder.tvActivity_EndDate.setText(df.format(model.getActivityEndDate()));
holder.tvActivity_Capacity.setText(model.getActivityCapacity());
holder.tvActivity_City.setText(model.getActivityCity());
holder.tvActivity_Deadline_Abstract.setText(df.format(model.getActivityDeadlineAbstract()));
holder.tvActivity_Deadline_Notice.setText(df.format(model.getActivityDeadlineNotice()));
holder.tvActivity_Deadline_CameraReady.setText(df.format(model.getActivityDeadlineCameraReady()));
holder.tvActivity_Deadline_FullVersion.setText(df.format(model.getActivityDeadlineFullVersion()));
}
#Override
public int getItemCount(){
return dataList.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView tvActivity_Name, tvActivity_StartDate, tvActivity_EndDate, tvActivity_Capacity, tvActivity_City,
tvActivity_Deadline_Abstract, tvActivity_Deadline_Notice, tvActivity_Deadline_CameraReady,
tvActivity_Deadline_FullVersion;
ViewHolder(View itemView){
super(itemView);
tvActivity_Name = (TextView) itemView.findViewById(R.id.tvActivity_Name);
tvActivity_StartDate = (TextView) itemView.findViewById(R.id.tvActivity_StartDate);
tvActivity_EndDate = (TextView) itemView.findViewById(R.id.tvActivity_EndDate);
tvActivity_Capacity = (TextView) itemView.findViewById(R.id.tvActivity_Capacity);
tvActivity_City = (TextView) itemView.findViewById(R.id.tvActivity_City);
tvActivity_Deadline_Abstract = (TextView) itemView.findViewById(R.id.tvActivity_Deadline_Abstract);
tvActivity_Deadline_Notice = (TextView) itemView.findViewById(R.id.tvActivity_Deadline_Notice);
tvActivity_Deadline_CameraReady = (TextView) itemView.findViewById(R.id.tvActivity_Deadline_CameraReady);
tvActivity_Deadline_FullVersion = (TextView) itemView.findViewById(R.id.tvActivity_Deadline_FullVersion);
}
}
}
public class UserHomeActivity extends AppCompatActivity {
private ActivityAdapter adapter;
private RecyclerView recyclerView;
private ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_home);
Button bDisplayActivity = (Button) findViewById(R.id.button_display_data_activity);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
progressDialog = new ProgressDialog(this);
bDisplayActivity.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
getAllActivity();
}
});
}
private void getAllActivity(){
progressDialog.setTitle("Displaying Data");
progressDialog.setMessage("Loading...");
GetActivityDataAPI service = RetrofitService.getClient().create(GetActivityDataAPI.class);
Call<ActivityListModel> listModelCall = service.getAllDataActivity();
listModelCall.enqueue(new Callback<ActivityListModel>() {
#Override
public void onResponse(Call<ActivityListModel> call, Response<ActivityListModel> response) {
ActivityListModel activityListModel = response.body();
if(activityListModel.getStatus() == 1){
List<ActivityModel> activityModels = activityListModel.getActivityList();
ActivityAdapter activityAdapter = new ActivityAdapter(activityModels, UserHomeActivity.this);
recyclerView.setLayoutManager(new LinearLayoutManager(UserHomeActivity.this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(activityAdapter);
progressDialog.dismiss();
}else {
Toast.makeText(UserHomeActivity.this, activityListModel.getMessage(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ActivityListModel> call, Throwable t) {
Toast.makeText(UserHomeActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
});
}
}
And My Model Classes:
ublic class ActivityModel {
#SerializedName("Activity_Name")
private String activityName;
#SerializedName("Activity_StartDate")
private Date activityStartDate;
#SerializedName("Activity_EndDate")
private Date activityEndDate;
#SerializedName("Activity_Capacity")
private Integer activityCapacity;
#SerializedName("Activity_City")
private String activityCity;
#SerializedName("Activity_Deadline_Abstract")
private Date activityDeadlineAbstract;
#SerializedName("Activity_Deadline_Notice")
private Date activityDeadlineNotice;
#SerializedName("Activity_Deadline_CameraReady")
private Date activityDeadlineCameraReady;
#SerializedName("Activity_Deadline_FullVersion")
private Date activityDeadlineFullVersion;
public ActivityModel(String activityName,Date activityStartDate, Date activityEndDate, Integer activityCapacity, String activityCity,
Date activityDeadlineAbstract, Date activityDeadlineNotice, Date activityDeadlineCameraReady, Date activityDeadlineFullVersion)
{
this.activityName = activityName;
this.activityStartDate = activityStartDate;
this.activityEndDate = activityEndDate;
this.activityCapacity = activityCapacity;
this.activityCity = activityCity;
this.activityDeadlineAbstract = activityDeadlineAbstract;
this.activityDeadlineNotice = activityDeadlineNotice;
this.activityDeadlineCameraReady = activityDeadlineCameraReady;
this.activityDeadlineFullVersion = activityDeadlineFullVersion;
}
public String getActivityName() {
return activityName;
}
public void setActivityName(String activityName) {
this.activityName = activityName;
}
public Date getActivityStartDate() {
return activityStartDate;
}
public void setActivityStartDate(Date activityStartDate) {
this.activityStartDate = activityStartDate;
}
public Date getActivityEndDate() {
return activityEndDate;
}
public void setActivityEndDate(Date activityEndDate) {
this.activityEndDate = activityEndDate;
}
public int getActivityCapacity() {
return activityCapacity;
}
public void setActivityCapacity(int activityCapacity) {
this.activityCapacity = activityCapacity;
}
public String getActivityCity() {
return activityCity;
}
public void setActivityCity(String activityCity) {
this.activityCity = activityCity;
}
public Date getActivityDeadlineAbstract() {
return activityDeadlineAbstract;
}
public void setActivityDeadlineAbstract(Date activityDeadlineAbstract) {
this.activityDeadlineAbstract = activityDeadlineAbstract;
}
public Date getActivityDeadlineNotice() {
return activityDeadlineNotice;
}
public void setActivityDeadlineNotice(Date activityDeadlineNotice) {
this.activityDeadlineNotice = activityDeadlineNotice;
}
public Date getActivityDeadlineCameraReady() {
return activityDeadlineCameraReady;
}
public void setActivityDeadlineCameraReady(Date activityDeadlineCameraReady) {
this.activityDeadlineCameraReady = activityDeadlineCameraReady;
}
public Date getActivityDeadlineFullVersion() {
return activityDeadlineFullVersion;
}
public void setActivityDeadlineFullVersion(Date activityDeadlineFullVersion) {
this.activityDeadlineFullVersion = activityDeadlineFullVersion;
}
}
public class ActivityListModel {
#SerializedName("Activity")
private ArrayList<ActivityModel> ActivityList ;
#SerializedName("status")
private Integer status;
#SerializedName("message")
private String message;
public ActivityListModel() {
}
public ArrayList<ActivityModel> getActivityList() {
return ActivityList;
}
public void setActivityList(ArrayList<ActivityModel> ActivityList) {
this.ActivityList = ActivityList;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
My LoggingInterceptors Class:
public class LoggingInterceptors implements Interceptor{
#Override
public Response intercept(Chain chain) throws IOException{
Request request = chain.request();
long t1 = System.nanoTime();
String requestLog = String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers());
if (request.method().compareToIgnoreCase("post") == 0){
requestLog = "\n" + requestLog + "\n" + bodyToString(request);
}
Log.d("TAG", "request" + "\n" + requestLog);
Response response = chain.proceed(request);
long t2 = System.nanoTime();
String responseLog = String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers());
String bodyString = response.body().string();
Log.d("TAG", "response" + "\n" + responseLog + "\n" + bodyString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), bodyString))
.build();
}
public static String bodyToString(final Request request){
try{
final Request copy = request.newBuilder().build();
final Buffer buffer = new Buffer();
copy.body().writeTo(buffer);
return buffer.readUtf8();
}catch (final IOException e){
return "hatalı bodyToString";
}
}
}
Try calling notifyDataSetChanged() in your adapter where you update your data source.
I think it would be a good idea to have a swapCursor method. This method will set the cursor and you can notify if the data has changed as follows:
public void swapCursor(Cursor cursor) {
if (mCursor != null) {
mCursor.close();
}
mCursor = cursor;
notifyDataSetChanged();
}
Then when you are loading the data in your Fragment/Activity you call it like this:
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data)
{
mAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader)
{
mAdapter.swapCursor(null);
}
Hope this helps :)

RxJava,Retrofit Error :Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

I am using Retrofit and RxJava Library and trying to parse this url:
My code is as below.
APIInterface.java
public interface APIService {
#GET("/bins/tdze5")
Observable<List<Student>> getdata();
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<Student> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
getData();
}
private void getData() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.myjson.com")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
APIService apiService = retrofit.create(APIService.class);
Observable<List<Student>> observable = apiService.getdata().subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
observable.subscribe(new Observer<List<Student>>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
Log.d("error",e.toString());
}
#Override
public void onNext(List<Student> students) {
list = new ArrayList<>();
Log.d("response size", String.valueOf(students.size()));
for(int i = 0; i < students.size(); i++){
Student student = new Student();
student.setId(students.get(i).getId());
student.setName(students.get(i).getName());
list.add(student);
}
RecyclerAdapter recyclerAdapter = new RecyclerAdapter(list);
RecyclerView.LayoutManager recyce = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(recyce);
recyclerView.setItemAnimator( new DefaultItemAnimator());
recyclerView.setAdapter(recyclerAdapter);
}
});
}
}
My Model Class is as below
Student.java
public class Student {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} }
I am getting
D/error: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was
BEGIN_OBJECT at line 1 column 2 path $ in Log
I have searched everywhere about this error but I couldn't find anything about RxJava and Retrofit.
Add this one more class and use it like below.
public class ResponseClass {
#SerializedName("students")
#Expose
private List<Student> students = null;
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
APIInterface.java
public interface APIService {
#GET("/bins/tdze5")
Observable<ResponseClass> getdata();
}
MainActivity.java
private void getData() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.myjson.com")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
APIService apiService = retrofit.create(APIService.class);
Observable<ResponseClass> observable = apiService.getdata().subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread());
observable.subscribe(new Observer<ResponseClass>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
Log.d("error",e.toString());
}
#Override
public void onNext(ResponseClass response) {
list = new ArrayList<>();
List<Student> students = response.getStudents();
Log.d("response size", String.valueOf(students.size()));
for(int i = 0; i < students.size(); i++){
Student student = new Student();
student.setId(students.get(i).getId());
student.setName(students.get(i).getName());
list.add(student);
}
RecyclerAdapter recyclerAdapter = new RecyclerAdapter(list);
RecyclerView.LayoutManager recyce = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(recyce);
recyclerView.setItemAnimator( new DefaultItemAnimator());
recyclerView.setAdapter(recyclerAdapter);
}
});
}

Categories

Resources