Home > Back-end >  Add Image in listView using image from url Picasso crash in android
Add Image in listView using image from url Picasso crash in android

Time:07-07

Bonjour I have spent days and night looking for an answer suitable to my case can you help please Here is the code I am using anytime I add the ligne with Picasso, the program crashes It works fine with static images from drawable I just want to display the text with the image that corresponds

    public void Afficher_les_vues(String url_in) {

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            .url(url_in)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
            e.printStackTrace();
        }

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
            if (response.isSuccessful()) {

                myResponse = response.body().string();
                Annonces.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {


                        try {
                            JSONObject reader = new JSONObject(myResponse);

                            JSONArray eglises = reader.getJSONArray("Annonces_adv");


                            arrayList.clear();


                            for (int i = 0; i < eglises.length(); i  ) {

                                JSONObject eglise = eglises.getJSONObject(i);
                                String titre = eglise.getString(titret);
                                String description = eglise.getString(descriptionet);
                                int ref = Integer.parseInt(eglise.getString(reft));
                                String image = eglise.getString(imaget);
                                String url_image = eglise.getString(imaget);

                                HashMap<String, String> data = new HashMap<>();


                                data.put(titret, titre);
                                data.put(descriptionet, description);
                                data.put(reft, String.valueOf(ref));
                                data.put(imaget, image);
                                data.put(url_imaget, url_image);

                                arrayList.add(data);


                                ImageView imageViewlogo = findViewById(R.id.imageViewLogoNews);
                                //Picasso.get().load(url_image).into(imageViewlogo);

                                //new GetImageFromUrl(imageViewlogo).execute(url_image);


                                ListAdapter adapter = new SimpleAdapter(Annonces.this, arrayList, R.layout.listview_layout
                                        , new String[]{titret, descriptionet, reft, url_imaget}, new int[]{R.id.titre_de, R.id.description_de,
                                        R.id.reference, R.id.url_image});


                                lv.setAdapter(adapter);

                            }


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


                    }
                });


            }

When I use Picasso to display and image in a simple ImageView not in a listView, it works fine

Thank you in advance I work with android studio Blessings

CodePudding user response:

Merci beaucoup

you right Tyler V for the R.id.imageViewLogoNews, it is always null.... To test, I did put an imageView with the id: R.id.imageViewLogoNews and a single image appears and no clash, so the problem seems to come from there. The log says the same thing:

  java.lang.IllegalArgumentException: Target must not be null.
    at com.squareup.picasso.RequestCreator.into(RequestCreator.java:682)
    at com.squareup.picasso.RequestCreator.into(RequestCreator.java:665)

How can i create and set the adapter outside of the loop?

some help..... Do I need to do all over... do I do the correct thing?

The App uses basically 3 main files

The main XML

     <?xml version="1.0" encoding="utf-8"?>
  <androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".Annonces">


<!--Swipe Refresh Layout -->
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:id="@ id/refreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@ id/listview"/>

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>


  </androidx.constraintlayout.widget.ConstraintLayout>

Here is the XML with the single item

    <?xml version="1.0" encoding="utf-8"?>
  <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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">


<ImageView
    android:id="@ id/imageViewLogoNews"
    android:layout_width="50dp"
    android:layout_height="70dp"
    android:layout_margin="10dp"
    app:srcCompat="@drawable/truc"
    android:contentDescription="TODO"
    tools:ignore="ContentDescription" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@ id/titre_de"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="Titre"
        android:textSize="15sp"
        android:textStyle="bold" />

    <TextView
        android:id="@ id/description_de"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Description"
        android:textSize="14sp" />

    <TextView
        android:id="@ id/reference"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="reference"
        android:textSize="0sp" />

    <TextView
        android:id="@ id/url_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="url_image"
        android:textSize="0sp" />

</LinearLayout>




  </LinearLayout>

The function that calls the listview in the main page

String myResponse;
ListView lv;
String titret="titre";
String descriptionet="texte";
String reft="ref";
String imaget="image";
String url_imaget="";

Bitmap bitmap;
ImageView image;

RecyclerView.ViewHolder holder = null;


ImageView imageViewdd;

ArrayList<HashMap<String,String>> arrayList;

    public void Afficher_les_vues(String url_in) {

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            .url(url_in)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
            e.printStackTrace();
        }

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
            if (response.isSuccessful()) {

                myResponse = response.body().string();
                Annonces.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {


                        try {
                            JSONObject reader = new JSONObject(myResponse);

                            JSONArray eglises = reader.getJSONArray("Annonces_adv");


                            arrayList.clear();


                            for (int i = 0; i < eglises.length(); i  ) {

                                JSONObject eglise = eglises.getJSONObject(i);
                                String titre = eglise.getString(titret);
                                String description = eglise.getString(descriptionet);
                                int ref = Integer.parseInt(eglise.getString(reft));
                                String image = eglise.getString(imaget);
                                String url_image = eglise.getString(imaget);

                                //HashMap<String, String> data = new HashMap<>();


                                data.put(titret, titre);
                                data.put(descriptionet, description);
                                data.put(reft, String.valueOf(ref));
                                data.put(imaget, image);
                                data.put(url_imaget, url_image);

                                arrayList.add(data);


                                ImageView imageViewlogo = findViewById(R.id.imageViewLogoNews);
                                Picasso.get().load(url_image).into(imageViewlogo);


                                ListAdapter adapter = new SimpleAdapter(Annonces.this, arrayList, R.layout.listview_layout
                                        , new String[]{titret, descriptionet, reft, url_imaget}, new int[]{R.id.titre_de, R.id.description_de,
                                        R.id.reference, R.id.url_image});


                                lv.setAdapter(adapter);

                            }

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


                    }
                });


            }


        }
    });

}

I géve you all Thank you in avance from France, english is my second language, I hope I was clear Blessings

CodePudding user response:

The main things you need to fix are not creating the adapter every loop instance and not accessing row views (the ImageView) from outside the adapter.

1. Do not make the adapter inside the loop

You should build the array of data to display first, then after the loop that builds the array create the adapter and set it on the ListView.

arrayList.clear();

for (int i = 0; i < eglises.length(); i  ) {

    JSONObject eglise = eglises.getJSONObject(i);
    String titre = eglise.getString(titret);
    String description = eglise.getString(descriptionet);
    int ref = Integer.parseInt(eglise.getString(reft));
    String image = eglise.getString(imaget);
    String url_image = eglise.getString(imaget);

    HashMap<String, String> data = new HashMap<>();


    data.put(titret, titre);
    data.put(descriptionet, description);
    data.put(reft, String.valueOf(ref));
    data.put(imaget, image);
    data.put(url_imaget, url_image);

    arrayList.add(data);
}

// You CANNOT access row view here - in this context findViewById searches the main
// view heirarchy, and will not find views in your ListView rows

// Make the adapter *AFTER* the loop where you fill the array
// you will need to make your own custom adapter to load the image
ListAdapter adapter = new CustomAdapter(Annonces.this, arrayList, R.layout.listview_layout, 
                                        new String[]{titret, descriptionet, reft, url_imaget}, 
                                        new int[]{R.id.titre_de, R.id.description_de, R.id.reference, R.id.url_image});


lv.setAdapter(adapter);

2. Do not attempt to access row views outside the adapter

Your row views should only be accessed inside getView in your adapter itself. This is where you should load the image. If you were using a standard adapter before, you will need to implement your own custom adapter to do this. There are instructions for how to do that here.

@Override
public View getView(int position, View convertView, ViewGroup parent) {

   // Get the data map for this position
   HashMap<String,String> data = getItem(position);    
   
   // Check if an existing view is being reused, otherwise inflate the view
   if (convertView == null) {
      convertView = LayoutInflater.from(context).inflate(R.layout.listview_layout, parent, false);
   }
   

   // Set views, load images, etc for this specific row
   // set TextView text and stuff here too (not shown)
   ImageView imageViewlogo = convertView.findViewById(R.id.imageViewLogoNews);

   // Load the URL to use from the data map
   String url_image = data.get(url_imaget);

   // Start Picasso loading into the ImageView for this row
   Picasso.get().load(url_image).into(imageViewlogo);
                                
   return convertView;
}

  • Related