自定义列表视图上的毕加索
Picasso on custom listview
我是 android 的初学者,我正在尝试将 google 个位置 API 中的图像用于我的自定义列表视图。我正在尝试使用毕加索来做到这一点。我可以毫无问题地获取文本,但是当我尝试从 url 附加图像时,它给了我一个 "Target must not be null" 错误。任何 comments/help/suggestions 表示赞赏。
我的自定义列表行 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>
我的异步后执行代码:
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.access0(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)
再次感谢任何帮助!
问题是,您尝试将图像附加到 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 上加载图像,但我认为作为示例没问题
我是 android 的初学者,我正在尝试将 google 个位置 API 中的图像用于我的自定义列表视图。我正在尝试使用毕加索来做到这一点。我可以毫无问题地获取文本,但是当我尝试从 url 附加图像时,它给了我一个 "Target must not be null" 错误。任何 comments/help/suggestions 表示赞赏。
我的自定义列表行 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>
我的异步后执行代码:
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.access0(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)
再次感谢任何帮助!
问题是,您尝试将图像附加到 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 上加载图像,但我认为作为示例没问题