简体   繁体   中英

get Image from Json data and show it as cover image in RecyclerView android

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

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

这向您显示错误,因为您正在将“ src”作为String并且尝试将其用作int

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)

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM