【问题标题】:get Image from Json data and show it as cover image in RecyclerView android从 Json 数据中获取图像并将其显示为 RecyclerView android 中的封面图像
【发布时间】:2018-01-30 14:01:53
【问题描述】:

我正在尝试从 Rest Api 获取 json 数据,对其进行反序列化并将其显示给 RecyclerView。

我正在使用改造 1.9。在 JSONArray(s) 中,我可以在 logcat 中看到数据 api。

我可以反序列化 json 数组之外的数据,如正文、标题等。

但是在 json 中有一些图像作为数组。我为 appimage 和 testImage 创建了两个静态内部类。

AppImage 有 3 或 4 个图像。测试图像只有一个图像源。

起初我想获取 TeaserimageSample 将其设置为 RecyclerView 标题图像。

我正在尝试从中获取 src 值。但不知道该怎么做。

我还想知道我的模型类是否基于给定的 JSON 是正确的。我在代码里面已经详细解释过了。

编辑的控制器类

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

我已编辑的适配器类我在其中设置 Picasso 以设置封面图像的图像。但我仍然在 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 我在我的问题中给出了 api mager
  • 你能发布API链接吗?我的意思是你从哪里得到这个 json 响应?
  • 我认为您无权查看它。 app.blu-pa.com/api/news.. 但是json数据是这样的
  • 因为我在 logcat 中看不到所有数据。我还可以在 recyclerview 中看到正文、文本、更新日期。但我此时遇到了图像问题
  • 好的,我正在尝试这个

标签: java android json deserialization picasso


【解决方案1】:

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

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

【讨论】:

  • @V-rund,如何修改?
  • appImages.setSrc(imageArray.optString( "src" )) 使用这个。我也怀疑图像不是从 url 加载的。我想可能会有不同的路径
  • @V-rundPuro-hit iam 仍然收到 appImages.setSrc(imageArray.optString( "src" )) 错误
  • JSONArray 中的 getString(int) 无法应用于 java.lang.string。我已经在代码中编辑了这一行
  • @V-rundPuro-hit 我仍然不明白为什么 src 不起作用。为什么我显示这个错误
【解决方案2】:

您可以直接从网络显示图像而无需下载

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

并将其设置为 ImageView。

否则你可以使用像毕加索这样的图书馆,

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

Here 讨论毕加索的一些替代品(Imageloader、Fresco、Glide)

【讨论】:

  • @Nicole 是一个rest api,未经授权任何人都不能使用,我也做了离线版本。所以我想首先进行反序列化,然后将其展示给recyclerview。
【解决方案3】:

有两种可能。

  • 第一个是你的imageView的height属性是zore。
  • 第二个是您的网址不够正确,无法加载图片。

所以首先尝试为imageView设置有效高度,如果不能成功,请尝试修复你的url。

修复网址

将此方法添加到您的帮助程序类中并与 Picasso 或 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";
}

你的代码应该是这样的;

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

当您通过浏览器打开图片时,您可以看到该图片,但有时 Android 无法找到该图片。通过这个 url 对话,Picasso 或 Glide 可以找到该 url。

我在使用毕加索图书馆时也遇到了这个问题。我无法修复它,然后我迁移到 Glide 库,我的问题已经消失了。

【讨论】:

  • 对不起,我可以在 NewsController 类中实现 json 数组吗.. 因为你的代码与我的代码无关
  • 很抱歉,我没有其他办法可以解决您的问题。我遇到了这个问题,我做了上述步骤并修复了它。
  • 好的。但我认为这与我的代码无关。因为你看,我有控制器类,我的 url 是 json 格式的。我正面临源的正确反序列化。到目前为止这是我的问题
  • 好的,尝试将它添加到您的 imageview 布局中,并确保 imageview 的 layout_height 属性是 wrap_content。 android:adjustViewBounds="true" android:scaleType="fitXY" 在编译项目之前,清理项目然后编译它。
  • 是的,我设置了这个。但这不会改变代码内部的任何内容。
【解决方案4】:

正如您在回复中看到的那样:

"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 是 jsonArray,要从中获取 src 的值,您需要首先从该 json 对象中获取 jsonobject,src 的字符串值如下:

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

试试这个

【讨论】:

  • 在这种情况下如何获取teaserImageSmall​。我已经编辑了我的控制器类。你能看看吗
  • 你能告诉我在这种情况下如何在毕加索中获得图像。我希望 zo 一开始只得到 testImageSamll。 Picasso.with(holder.itemView.getContext()).load( /* 我想从 TeaserImageSmall 设置 imagew 源*/);
  • for picasso:- Picasso.with(holder.itemView.getContext()).load(从teaserImageSmall的json对象获取src的字符串);即Picasso .with(holder.itemView.getContext()).load(object.getJSONObject("teaserImageSmall​").getString("src"))
  • 我刚刚编辑了我的问题,也编辑了适配器类。我仍然没有得到任何东西:(我还为 testImageSample 编写了代码。你能看看吗
  • 这里你没有设置任何图像,所以在这里设置,然后将 newsmodel 添加到列表中,即 ** JSONObject Jo= object.getJSONObject("teaserImageSmall​"); NewsModel.TeaserImageSmall coverImage=new NewsModel.TeaserImageSmall(); coverImage.setSrc(Jo.getString(‌​"src")); mListener.onFetchProgress(news);**
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多