0

I am trying to get json data from Rest Api , deserialize it and show it to RecyclerView.

I am using retrofit 1.9. In JSONArray(s) I can see data api in logcat.

I can deserialize the data outside array of json, like body, title etc.

But there are some images as Array inside json. I have created two static inner class for appimage and testImage.

AppImage has 3 or four images. Test Image have only one image source.

At first I want to get TeaserimageSample to set it as RecyclerView heading image.

I am trying to get the src value from it. But could not get it how to do it.

I would also like to know if my model class is correct based on the given JSON. I have explained in detail inside the code.

Edited Controller Class

    public class NewsController {
    private static final String TAG = NewsController.class.getSimpleName();
    private UserCallbackListener mListener;
    private NewsRestApiManager mApiManager;

    public NewsController(UserCallbackListener listener) {
        mListener = listener;
        mApiManager = new NewsRestApiManager();
    }

    public void startFetching(){

        mApiManager.getNewsApi().getNews(new Callback<String>() {

            @Override
            public void success(String s, Response response) {
                Log.d(TAG, "JSON :: " + s);

                try {
                    JSONArray array = new JSONArray(s);

                    for(int i = 0; i < array.length(); i++) {
                        JSONObject object = array.getJSONObject(i);

                        NewsModel news = new NewsModel();
                        news.setTitle( object.optString( "title") );
                        news.setBody( object.optString( "body" ) );

                        ArrayList<NewsModel.AppImage> list = new ArrayList();
                        JSONArray imageArray =object.getJSONArray("appImages");
                        for(int j=0; j<imageArray.length();j++){
                            NewsModel.AppImage appImages  = new NewsModel.AppImage();
                            appImages.setSrc(imageArray.getJSONObject( j ).getString( "src" ));
                            list.add(appImages);
                        }
                        news.setAppImages( list );

                        JSONObject jo=object.getJSONObject( "teaserImageSmall​" );
                        NewsModel.TeaserImageSmall coverImage=new NewsModel.TeaserImageSmall();
                        coverImage.setSrc( jo.optString( "src" ));
                        news.setTeaserImageSmall(coverImage);
                        mListener.onFetchProgress(news);

                    }

                } catch (JSONException e) {
                    mListener.onFetchFailed();
                }


                mListener.onFetchComplete();
            }

            @Override
            public void failure(RetrofitError error) {
                Log.d(TAG, "Error :: " + error.getMessage());
                mListener.onFetchComplete();
            }
        });

    }
    public interface UserCallbackListener{
        void onFetchStart();
        void onFetchProgress(NewsModel news);
        void onFetchProgress(List<NewsModel> userList);
        void onFetchComplete();
        void onFetchFailed();
    }
}

My Edited Adapter Class Where I set Picasso to set image for cover image. But still I can see nothing in recyclerview

...............
    // create new views (invoked by the layout manager)
    @Override
    public NewsHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.news_row_layout,parent,false);
        return new NewsHolder(view);
    }

    @Override
    public void onBindViewHolder(NewsHolder holder, int position) {

        final NewsModel currentNews = mNews.get(position);
        Picasso.with(holder.itemView.getContext());
        Picasso.with(holder.itemView.getContext()).load(currentNews.getTeaserImageSmall().getSrc()).into( holder.newsImage );

        holder.newsImage.setImageResource( R.drawable.image1 );
        holder.newsHeadline.setText(currentNews.getTitle());
        holder.newsDate.setText(currentNews.getPostDate());

    }

    @Override
    public int getItemCount() {
        return mNews.size();
    }


    public class NewsHolder extends RecyclerView.ViewHolder {

        public CardView cardView;
        public ImageView newsImage;
        public TextView newsHeadline;
        public TextView newsDate;

        public NewsHolder(View itemView) {
            super(itemView);
            newsImage=(ImageView)itemView.findViewById(R.id.news_picture);
            newsHeadline=(TextView)itemView.findViewById(R.id.news_headline);
            newsDate=(TextView) itemView.findViewById(R.id.news_date);
            cardView=(CardView)itemView.findViewById(R.id.cardview_news);
        }
    }
}
  • @Benjamin I have given in my question the api mager –  Aug 22 '17 at 10:43
  • can you post API link ? I mean from where you getting this json response? – V-rund Puro-hit Aug 22 '17 at 10:43
  • I think you cannot have authorization to see it. https://app.blu-pa.com/api/news.. But the json data is same like this –  Aug 22 '17 at 10:44
  • Because I cann see all data in logcat. I can also see body , text, update date in recyclerview. But I stuck with issue with image at this moment –  Aug 22 '17 at 10:45
  • ok I am trying this one –  Aug 22 '17 at 10:46
  • i am not able to get exact image link from that response. I mean that links from src tags are not working. – V-rund Puro-hit Aug 22 '17 at 10:47
  • why are you even using Gson here if you are returning the whole response as a String which you then deserialize by hand? – Benjamin Aug 22 '17 at 10:49
  • @Benjamin Sorry I am still very new in handling so complex stuff. I have seen one tutorial . and try to implement it in my code. I got response from api with this code. that is why I wrote in this way –  Aug 22 '17 at 10:51
  • It is shwoing error, Cannot resolve convert GsonConstructor. –  Aug 22 '17 at 10:58
  • see my updated response below – Benjamin Aug 22 '17 at 11:10
  • I have mentioned in my question that I am using retrofit 1.9. is there no wan to loop through the appIMage array and TestImageSample and get the image?. –  Aug 22 '17 at 11:17

4 Answers4

1

appImages.setSrc( imageArray.optString( Integer.parseInt( "src" )

This is showing you error because you are receving "src" as String and you trying to use it as int

V-rund Puro-hit
  • 5,518
  • 9
  • 31
  • 50
yogesh lokhande
  • 1,245
  • 1
  • 11
  • 20
  • @V-rund, how can I modify it? –  Aug 22 '17 at 10:35
  • `appImages.setSrc(imageArray.optString( "src" ))` use this. Also i suspected that images aren't loading from url. i guess there might be different path for that – V-rund Puro-hit Aug 22 '17 at 10:38
  • @V-rundPuro-hit iam still getting error with appImages.setSrc(imageArray.optString( "src" )) –  Aug 22 '17 at 10:52
  • getString(int) in JSONArray cannot be applied to java.lang.string. I have edited this line in code –  Aug 22 '17 at 11:00
  • @V-rundPuro-hit I am still not getting why src is not working. why this error i sshowing –  Aug 22 '17 at 11:09
  • @ktina src not working means? you are not able to see image ?? – yogesh lokhande Aug 22 '17 at 11:23
  • @ysl, Yes I can see the image, url is fine, api is fine, everything is alright. What I want to do,at fisrt call TeaserImageSmall class in json deserilization as described in code , get the src as in controller class and then in adpter class show in picasso at fisrt. THen next step , loop through the appimage array. I just stuck with this problem. First step I want to solve TestImageSmall problem. then we can go to next step –  Aug 22 '17 at 11:26
0

You can directly show image from web without downloading it with

public static Drawable loadImage(String url) {
    try {
        InputStream inputStream = (InputStream) new URL(url).getContent();
        return Drawable.createFromStream(is, "src name");
    } catch (Exception e) {
        return null;
    }
}

and setting it to the ImageView.

Otherwise you can use some library like picasso, with

Picasso.with(context)
   .load(url)
   .placeholder(R.drawable.placeholder) //optional
   .resize(width, height)               //optional  
   .into(image);                        //your image view

Here a discussiuon on some Picasso alternatives (Imageloader, Fresco, Glide)

Nicola De Fiorenze
  • 1,958
  • 1
  • 17
  • 27
  • @Nicole its a rest api, no one can use without authorization, I have make as offline version also. So I want make a deserialization at fisrt and then show it to recyclerview. –  Aug 22 '17 at 10:30
0

As you can see in response :

"appImages": [
  {
    "alt": "",
    "src": "http://www.blu-pa.com/sites/www.blu-pa.com/files/DSC_7549.JPG",
    "_id": "599b39a20dbf4e002b875f71"
  },
  {
    "alt": "",
    "src": "http://www.blu-pa.com/sites/www.blu-pa.com/files/DSC_7531.JPG",
    "_id": "599b39a20dbf4e002b875f70"
  },
  {
    "alt": "",
    "src": "http://www.blu-pa.com/sites/www.blu-pa.com/files/DSC_7349.JP",
    "_id": "599b39a20dbf4e002b875f6f"
  },
  {
    "alt": "",
    "src": "http://image4.JPG",
    "_id": "599b39a20dbf4e002b875f6e"
  },
  {
    "alt": "",
    "src": "http://image4.JPG",
    "_id": "599b39a20dbf4e002b875f6d"
  }
],

appImages is jsonArray, to get value of src from this you need to get jsonobject first the from that json object the string value for src like this:

JSONArray imageArray =object.getJSONArray("appImages");
for(int j=0; j<imageArray.length();j++){
     NewsModel.AppImage appImages  = new NewsModel.AppImage(); 
     appImages.setSrc(imageArray.getJsonObject(j).getString("src"));

}

list.add(appImages); //how to add image after iteration

try this

KeLiuyue
  • 8,149
  • 4
  • 25
  • 42
Nikhil Jadhav
  • 1,621
  • 2
  • 12
  • 19
  • How can I get teaserImageSmall​ in this case. I have edited my Controller Class. Could you please have a look –  Aug 22 '17 at 11:42
  • Could you please tell me how can get image in picasso in this case. I want zo get only testImageSamll at first. Picasso.with(holder.itemView.getContext()).load( /* I want to set imagew source from TeaserImageSmall*/); –  Aug 22 '17 at 11:49
  • for picasso:- Picasso.with(holder.itemView.getContext()).load( from json object of teaserImageSmall get string for **src**);i.e **Picasso.with(holder.itemView.getContext()).load(object.getJSONObject("teaserImageSmall​").getString("src"))** – Nikhil Jadhav Aug 22 '17 at 11:58
  • I just edited my question, the adapter class also. still I am not getting anything :( I also write the code for testImageSample. Could you plaese have a look –  Aug 22 '17 at 11:59
  • here you are not setting any image so set here and then add newsmodel to list i.e. ** JSONObject Jo= object.getJSONObject("teaserImageSmall​"); NewsModel.TeaserImageSmall coverImage=new NewsModel.TeaserImageSmall(); coverImage.setSrc(Jo.getString(‌​"src")); mListener.onFetchProgress(news);** – Nikhil Jadhav Aug 22 '17 at 12:04
  • NewsModel.TeaserImageSmall coverImage=new NewsModel.TeaserImageSmall(); coverImage.setSrc( jo.optString( "src" )); mListener.onFetchProgress(news); } you are just creating a object for teaserImage but not setting to newsModel anywhere so you will not find the same in adapter class until it is set somewhere – Nikhil Jadhav Aug 22 '17 at 12:08
  • still recyclerview is empty –  Aug 22 '17 at 12:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/152523/discussion-between-nikhil-jadhav-and-ktina). – Nikhil Jadhav Aug 22 '17 at 12:11
0

There are two possibilities.

  • The first one is your imageView's height attribute is zore.
  • The second one is your url is not correct enough to load image.

So first try to set valid height to imageView, if you can not get any success, try to fix your url.

Fix the Url

Add this method into your helper class and use it with Picasso or Glide;

public static String getUrl(String the_url){
    try {
        URI uri = null;
        URL url = new URL(the_url);
        uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
        return uri.toASCIIString();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    return "no_image_url";
}

Your code should be like;

Picasso.with(holder.itemView.getContext()).load(MyHelper.getUrl(currentNews.getTeaserImageSmall().getSrc())).into( holder.newsImage );

When you open an image via your browser, you can see the image but sometimes Android could't find that image. With this url conversation, Picasso or Glide can find the url.

And also I met with this issue when working with Picasso library. I could't fix it and then I migrated to Glide library and my problem has gone.

Community
  • 1
  • 1
Muhammed Yusuf
  • 146
  • 2
  • 20
  • Sorry but, can I implement the json array in NewsController class.. because your code is not relavant to my code –  Aug 22 '17 at 14:18
  • I'm sorry but I don't have any other idea to fix your problem. I faced with this problem , i did the above steps and fixed it. – Muhammed Yusuf Aug 22 '17 at 14:29
  • ok. but I think this in not relavant my code. Because you see, I have controller class, and my url is there in json format. I am facing correct deserialization of the source. that is my question so far –  Aug 22 '17 at 14:32
  • ok, try to add this to your imageview layout and be sure that imageview's layout_height attribute is wrap_content. `android:adjustViewBounds="true" android:scaleType="fitXY"` and before compiling project, clean the project and then compile it. – Muhammed Yusuf Aug 22 '17 at 14:37
  • yes I set this. but this does not change anything inside code. –  Aug 22 '17 at 15:10