2015-07-20 4 views
1

Я начинаю с android и пытаюсь использовать изображение из API google places в свой собственный listview. Я пытаюсь сделать это с помощью Picasso. Я могу получить текст без проблем, но когда я пытаюсь прикрепить изображение с url, он дает мне ошибку «Target not be null». Любые комментарии/помощь/предложения приветствуются.Picasso on custom listview

Мой заказ listrow places_layout.xml:

 <?xml version="1.0" encoding="utf-8"?> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" 
     android:weightSum="1"> 
      <ImageView 
      android:id="@+id/placeicon" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_weight="0.10"/> 
      <TextView 
      android:id="@+id/placeinfo" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:drawablePadding="20dp" 
      android:layout_centerVertical="true" 
      android:layout_toRightOf="@+id/placeicon" 
      android:layout_toEndOf="@+id/placeicon" /> 
    </RelativeLayout> 

Мои Асинхронный PostExecute код:

ImageView places_icon = (ImageView) findViewById(R.id.placeicon); 

    venuesfound = (ArrayList) parsedataFound(result); 
      ArrayList<String> venuesList = new ArrayList<>(); 
      for(int i = 0; i<venuesfound.size();i++){ 
       if(venuesfound.get(i).getImageURL() != null){ 
        Picasso.with(getApplicationContext()) 
          .load(venuesfound.get(i).getImageURL()) 
          .into(places_icon); 
       } 
       venuesList.add(venuesfound.get(i).getName() 
         + "\nOpen: " + venuesfound.get(i).getOpenNow() 
         + "\n(" + venuesfound.get(i).getCategory() + ")"); 
      } 
      placesList = (ListView) findViewById(R.id.places_list); 
      placesAdapter = new ArrayAdapter(DisplayPlacesActivity.this, R.layout.places_layout, R.id.placeinfo, venuesList); 
      placesList.setAdapter(placesAdapter); 

Logcat:

 java.lang.IllegalArgumentException: Target must not be null. 
     at com.squareup.picasso.RequestCreator.into(RequestCreator.java:618) 
     at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601) 
     at com.example.johnchy.samplegui.DisplayPlacesActivity$dataRequest.onPostExecute(DisplayPlacesActivity.java:102) 
     at com.example.johnchy.samplegui.DisplayPlacesActivity$dataRequest.onPostExecute(DisplayPlacesActivity.java:56) 
     at android.os.AsyncTask.finish(AsyncTask.java:631) 
     at android.os.AsyncTask.access$600(AsyncTask.java:177) 
     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 
     at android.os.Handler.dispatchMessage(Handler.java:99) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:5419) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:525) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 
     at dalvik.system.NativeStart.main(Native Method) 

Опять же, любая помощь приветствуется!

+0

где is 'com.example.johnchy.samplegui.DisplayPlacesActivity $ dataRequest.onPostExecute (DisplayPlacesActivity.java:102)'? – JohnnyAW

+0

Спасибо, что ответили! Я считаю, что это строка picasso для кода Async onPostExecute: Picasso.with (getApplicationContext()) .load (venuesfound.get (i) .getImageURL()) .into (places_icon); Он находится на втором блоке кода – Masterofawesome

+0

, а затем проверяет значения с вашим отладчиком, что-то «null» в этой строке. Я бы предположил, что «places_icon» имеет значение null, так как он является целевым – JohnnyAW

ответ

2

Проблема в том, что вы пытаетесь прикрепить изображение к ImageView, которого еще нет. Поскольку вы хотите показать изображение в своем списке, вам нужно переместить вложение в адаптер, так как здесь вы создаете новый ImageView. Вам нужно будет создать новый ArrayAdapter для этой цели:

public class PicassoAdapter extends ArrayAdapter<String> { 
    public PicassoAdapter(List<String> urls, Context context){ 
     super(context, 0, urls); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     PlaceViewHolder holder; 
     //ListView tries to reuse invisible Row-Views to save memory, thats why this method can be called with null OR actually a ready View 
     if(convertView == null){ 
      //in this case we need to create a new View 
      //create a holder Object that we will attach to the view 
      holder = new PlaceViewHolder(); 
      //in this line we actually create a new row from the xml-file 
      convertView = View.inflate(getContext(), R.layout.places_layout, parent, false); 
      //we attach the Image- and Text-View to our holder, so we can access them in the next step 
      holder.placeIcon = (ImageView)convertView.findViewById(R.id.placeicon); 
      holder.placeInfo = (TextView)convertView.findViewById(R.id.placeinfo); 
      convertView.setTag(holder) 
     } else { 
      //if the view is already created, simply get the holder-object 
      holder = (PlaceViewHolder)convertView.getTag(); 
     } 
     //I assume the URL is a String, if you need another Type, simply change it here and in class declaration 
     String url = getItem(position); 
     Picasso.with(getContext()) 
         .load(url) 
         //now we have an ImageView, that we can use as target 
         .into(holder.placeIcon); 
     //you can set the info here 
     holder.placeInfo.setText("test"); 
     } 
    } 

    //we need this class as holder object 
    public static class PlaceViewHolder { 
     private ImageView placeIcon; 
     private TextView palceInfo; 
    } 
} 

теперь вы можете использовать этот адаптер в вашем списке:

placesList.setAdapter(new PicassoAdapter(urls, DisplayPlacesActivity.this)); 

остерегайтесь, что выполнение этого кода может быть очень плохо, так как мы пытаемся загрузить изображение в UI-Thread, но я думаю, что это нормально в качестве примера

+0

Спасибо! это сработало! Но вы правы, это немного снизило мое приложение. Есть ли у вас какие-либо предложения о том, как сделать это более эффективным? – Masterofawesome

+0

вы можете попробовать загрузить изображения в своем асинхронном вызове и поместить значки в виде 'byte []' в 'List' и вызвать адаптер с этим списком вместо Url. Я не знаком с Пикассо, но я думаю, у них есть функция, чтобы получить значок как 'byte []'. Даже при этом отображение нескольких больших изображений на экране является тяжелой задачей для смартфонов в среднем и более низком ценовом сегменте – JohnnyAW

+0

Спасибо! Я попробую это. – Masterofawesome