将图像URL加载到ImageView中时,毕加索返回错误

时间:2018-12-07 08:03:30

标签: android-studio fragment android-adapter picasso android-viewholder

我正在尝试从ImageView的Adapter类中将图像URL字符串加载到RecyclerView中,并且在RecyclerView中显示Fragment。但是,使用毕加索代码加载URL时,ImageView中什么也不显示。我试图放置上下文this.main.getActivity()this.main.getContext()this.main.getActivity().getApplicationContext()。什么都没用。

public class NewsAdapter extends RecyclerView.Adapter<NewsHolder> {

OneFragment main;
private Context context;
LayoutInflater inflater;
private ArrayList<Latest_News> arraylist;
private int itemResource;


public NewsAdapter(Context context, OneFragment main, ArrayList<Latest_News> arraylist)
{
    this.context = context;
    this.main = main;
    inflater = LayoutInflater.from(context);
    this.arraylist = arraylist;
}


@Override
public NewsHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.news_cell, viewGroup, false);

    return new NewsHolder(this.context, view);
}

@Override
public void onBindViewHolder(final NewsHolder newsHolder, int i) {

    Latest_News news = this.arraylist.get(i);

    Picasso.with(context)
            .load(news.getNewsImageURL())
            .into(newsHolder.newsImage);

}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemCount() {

    return this.arraylist.size();
}

}

这是我的ViewHolder的代码,我称之为NewsHolder:

public class NewsHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

public TextView subject;
public ImageView newsImage;

private Latest_News news;
private Context context;

public LinearLayout linearLayout;

ProgressBar progressBar;

public NewsHolder(Context context, View itemView) {

    super(itemView);

    // 1. Set the context
    this.context = context;

    // 2. Set up the UI widgets of the holder

    linearLayout = (LinearLayout) itemView.findViewById(R.id.linearLayout);
    this.subject = (TextView) itemView.findViewById(R.id.subject);
    this.newsImage = (ImageView) itemView.findViewById(R.id.newsImage);

    if (itemView != null) {
        progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar);
        //progressBar.setVisibility(View.VISIBLE);
    }

    final Typeface tvFont = Typeface.createFromAsset(context.getAssets(), "fonts/FSMatthew-Medium.otf");
    this.subject.setTypeface(tvFont);

    // 3. Set the "onClick" listener of the holder
    itemView.setOnClickListener(this);
}

public void bindBakery(Latest_News news) {

    // 4. Bind the data to the ViewHolder
    this.news = news;
    this.subject.setText(news.subject);

    //load the image url with a callback to a callback method/class
    String iconUrl = news.getNewsImageURL();
}

@Override
public void onClick(View v) {

    // 5. Handle the onClick event for the ViewHolder
    if (this.news != null) {

        Toast.makeText(this.context, "Clicked on " + this.news.subject, Toast.LENGTH_SHORT ).show();
    }
}

private class ImageLoadedCallback implements Callback {
    ProgressBar progressBar;

    public  ImageLoadedCallback(ProgressBar progBar){
        progressBar = progBar;
    }

    @Override
    public void onSuccess() {

    }

    @Override
    public void onError() {

    }
}


}

这是我的数据模型的类,我称它为Latest_News:

public class Latest_News {
public String subject;
public String body;
public String image_url;
public String news_url;


public Latest_News(String subject, String body, String image_url, String news_url) {
    this.subject = subject;
    this.body = body;
    this.image_url = image_url;
    this.news_url = news_url;
}

public Latest_News() {
}

public String getNewsSubject() {
    return this.subject;
}

public String getNewsBody() {
    return this.body;
}

public String getNewsImageURL() {
    return this.image_url;
}

public String getNewsURL() {
    return this.news_url;
}
}

这是我的Fragment的类,我称之为OneFragment:

public class OneFragment extends Fragment implements Download_data.download_complete {

RecyclerView listView;
public NewsAdapter adapter;

private static View view;

RecyclerView.LayoutManager layoutManager;

private ProgressBar spinner;

public static ArrayList<Latest_News> news;
public static ArrayList<Latest_News> news_sort;



public OneFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_one, container, false);

    spinner = (ProgressBar)view.findViewById(R.id.progressBar1);
    spinner.setVisibility(View.VISIBLE);

    news = new ArrayList<>();
    news_sort = new ArrayList<>();

    adapter = new NewsAdapter(getActivity(), this, news);
    //adapter = new ListAdapter(getContext(), R.layout.stations_cell, stations);


    // 4. Initialize ItemAnimator, LayoutManager and ItemDecorators
    layoutManager = new LinearLayoutManager(getActivity());

    int verticalSpacing = 40;
    VerticalSpaceItemDecorator itemDecorator =
            new VerticalSpaceItemDecorator(verticalSpacing);
    ShadowVerticalSpaceItemDecorator shadowItemDecorator =
            new ShadowVerticalSpaceItemDecorator(getActivity(), R.drawable.drop_shadow);


     // 5. Setup our RecyclerView
    listView = (RecyclerView)view.findViewById(R.id.listings_view);



     // 6. For performance, tell OS RecyclerView won't change size
    listView.setHasFixedSize(true);

    // 7. Set the LayoutManager
    listView.setLayoutManager(layoutManager);

     // 8. Set the ItemDecorators
    listView.addItemDecoration(shadowItemDecorator);
    listView.addItemDecoration(itemDecorator);

    // 9. Attach the adapter to RecyclerView
    listView.setAdapter(adapter);


    additems();
    adapter.notifyDataSetChanged();

    // Inflate the layout for this fragment
    return view;
}

public void additems() {


    Download_data download_data = new Download_data((Download_data.download_complete) this);

    String apiURL = String.format("https://example.com/API/latestnews/1");

    download_data.download_data_from_link(apiURL);

    Log.d("myTag", "dafdewfewffe" + adapter.getItemCount());

}



public void get_data(String data)
{

    try {
        JSONArray data_array=new JSONArray(data);

        for (int i = 0 ; i < data_array.length() ; i++)
        {
            JSONObject obj=new JSONObject(data_array.get(i).toString());

            Latest_News developers = new Latest_News(obj.getString("subject"), obj.getString("body"), obj.getString("image_url"), obj.getString("news_url"));
            news.add(developers);
            spinner.setVisibility(View.GONE);

        }

        adapter = new NewsAdapter(getActivity(), this, news);
        listView.setAdapter(adapter);
        adapter.notifyDataSetChanged();

    } catch (JSONException e) {
        e.printStackTrace();
    }

}

}

2 个答案:

答案 0 :(得分:0)

您的代码似乎还可以。

检查设备的互联网连接,如果可以,请检查您要加载的网址,看看其是否正常运行。

提示:不要每次都将字体放在ViewHolder中来创建字体,而是一次创建一次字体,使其静止并每隔一次使用

答案 1 :(得分:0)

问题是毕加索不接受加载http URL。这是我解决的方法:

首先,我将gradle文件中的以下内容与之前已经编译过的Picasso库一起进行了编译:

implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.squareup.okhttp:okhttp:2.2.0'
implementation 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'

然后我创建了以下课程:

public class PicassoTrustAll {

private static Picasso mInstance = null;

private PicassoTrustAll(Context context) {
    OkHttpClient client = new OkHttpClient();
    client.setHostnameVerifier(new HostnameVerifier() {
        @Override
        public boolean verify(String s, SSLSession sslSession) {
            return true;
        }
    });
    TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        @Override
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] x509Certificates,
                String s) throws java.security.cert.CertificateException {
        }

        @Override
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] x509Certificates,
                String s) throws java.security.cert.CertificateException {
        }

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[] {};
        }
    } };
    try {
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        client.setSslSocketFactory(sc.getSocketFactory());
    } catch (Exception e) {
        e.printStackTrace();
    }

    mInstance = new Picasso.Builder(context)
            .downloader(new OkHttpDownloader(client))
            .listener(new Picasso.Listener() {
                @Override
                public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
                    Log.e("PICASSO", String.valueOf(exception));
                }
            }).build();

}

public static Picasso getInstance(Context context) {
    if (mInstance == null) {
        new PicassoTrustAll(context);
    }
    return mInstance;
}
}

这是我在Adapter类中使用Picasso的方式:

PicassoTrustAll.getInstance(context)
            .load(news.getNewsImageURL())
            .into(newsHolder.newsImage);

感谢@RamchandraSingh https://stackoverflow.com/a/49795716/4846301