2015-07-20 38 views
1

我是一个初学者与Android,我试图从谷歌地方API使用图像到我的自定义列表视图。我试图用毕加索来做到这一点。我可以让文本没有问题,但是当我试图从URL附加图像时,它给了我一个“目标不能为空”的错误。任何意见/帮助/建议表示赞赏。毕加索对自定义列表视图

我定制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

其中是'com.example.johnchy.samplegui.DisplayPlacesActivity $ dataRequest.onPostExecute(DisplayPlacesActivity.java:102)'? – JohnnyAW

+0

感谢您的回复!我相信这是Async onPostExecute代码上的Picasso行:Picasso.with(getApplicationContext()) .load(venuesfound.get(i).getImageURL()) .into(places_icon);它在第二块代码 – Masterofawesome

+0

上,然后用你的调试器检查这些值,在这一行中有一些是'null'。我猜'places_icon'为空,因为它是目标 – 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线程上加载图像,但我认为它可以作为示例

+0

谢谢!工作!但是你是对的,它确实减慢了我的应用程序。你对如何提高效率有什么建议吗? – Masterofawesome

+0

您可以尝试在异步调用中加载图像,并将图标作为byte []放入List中,并使用该列表而不是Url调用适配器。我对毕加索不熟悉,但我想他们有一些功能可以将图标变为'byte []'。即使如此,在屏幕上显示多个大图像对于中低价位的智能手机来说是一项沉重的任务 – JohnnyAW

+0

谢谢!我会尝试。 – Masterofawesome