这个主要是补充《ListView中加入LinearLayout【一】》中的一些限制
在【一】 中,我试了很多方法添加网络上的图片,在无数次失败后,终于成功添加。
{此方法不建议使用 要用listView建议重写BaseAdapter的getView方法 自己想怎么定义Adapter就怎么定义 就不用费这么大的周折了-----2011.11.23
}
这个就要用到Android的API源码,我改写了下SimpleAdapter这个类(主要是重写一个setViewImage方法)。并命名为MyAdapter.java
另外添加了一个把URL资源转换成BitMap图像的类
代码如下:
/** * Class Name: UrlToBitmap * @author Pweibo * Turn an Url image to Bitmap type */ public class UrlToBitmap { private Bitmap bitmap; /** * * @param myFileUrl An image of URL type */ public UrlToBitmap(URL myFileUrl) { // URL myFileUrl = null; bitmap = null; try { HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection(); conn.setDoInput(true); conn.connect(); InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); } } /** * * @return A Bitmap type */ public Bitmap reutrnBitmap(){ return bitmap; } }
/** * Class Name: MyAdapter * @author Pcd * </br>rewriting code from SimpleAdapter * */ public class MyAdapter extends BaseAdapter implements Filterable { private int[] mTo; private String[] mFrom; private ViewBinder mViewBinder; private List<? extends Map<String, ?>> mData; private int mResource; private int mDropDownResource; private LayoutInflater mInflater; private SimpleFilter mFilter; private ArrayList<Map<String, ?>> mUnfilteredData; /** * Constructor * * @param context The context where the View associated with this SimpleAdapter is running * @param data A List of Maps. Each entry in the List corresponds to one row in the list. The * Maps contain the data for each row, and should include all the entries specified in * "from" * @param resource Resource identifier of a view layout that defines the views for this list * item. The layout file should include at least those named views defined in "to" * @param from A list of column names that will be added to the Map associated with each * item. * @param to The views that should display column in the "from" parameter. These should all be * TextViews. The first N views in this list are given the values of the first N columns * in the from parameter. */ public MyAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) { mData = data; mResource = mDropDownResource = resource; mFrom = from; mTo = to; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } /** * @see android.widget.Adapter#getCount() */ public int getCount() { return mData.size(); } /** * @see android.widget.Adapter#getItem(int) */ public Object getItem(int position) { return mData.get(position); } /** * @see android.widget.Adapter#getItemId(int) */ public long getItemId(int position) { return position; } /** * @see android.widget.Adapter#getView(int, View, ViewGroup) */ public View getView(int position, View convertView, ViewGroup parent) { return createViewFromResource(position, convertView, parent, mResource); } private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) { View v; if (convertView == null) { v = mInflater.inflate(resource, parent, false); } else { v = convertView; } bindView(position, v); return v; } /** * <p>Sets the layout resource to create the drop down views.</p> * * @param resource the layout resource defining the drop down views * @see #getDropDownView(int, android.view.View, android.view.ViewGroup) */ public void setDropDownViewResource(int resource) { this.mDropDownResource = resource; } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { return createViewFromResource(position, convertView, parent, mDropDownResource); } private void bindView(int position, View view) { final Map dataSet = mData.get(position); if (dataSet == null) { return; } final ViewBinder binder = mViewBinder; final String[] from = mFrom; final int[] to = mTo; final int count = to.length; for (int i = 0; i < count; i++) { final View v = view.findViewById(to[i]); if (v != null) { final Object data = dataSet.get(from[i]); String text = data == null ? "" : data.toString(); if (text == null) { text = ""; } boolean bound = false; if (binder != null) { bound = binder.setViewValue(v, data, text); } if (!bound) { if (v instanceof Checkable) { if (data instanceof Boolean) { ((Checkable) v).setChecked((Boolean) data); } else if (v instanceof TextView) { // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text); } else { throw new IllegalStateException(v.getClass().getName() + " should be bound to a Boolean, not a " + (data == null ? "<unknown type>" : data.getClass())); } } else if (v instanceof TextView) { // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text); } else if (v instanceof ImageView) { if (data instanceof Integer) { setViewImage((ImageView) v, (Integer) data); } else if(data instanceof Bitmap){ setViewImage((ImageView) v, (Bitmap) data); } else { setViewImage((ImageView) v, text); } } else { throw new IllegalStateException(v.getClass().getName() + " is not a " + " view that can be bounds by this SimpleAdapter"); } } } } } /** * Returns the {@link ViewBinder} used to bind data to views. * * @return a ViewBinder or null if the binder does not exist * * @see #setViewBinder(android.widget.SimpleAdapter.ViewBinder) */ public ViewBinder getViewBinder() { return mViewBinder; } /** * Sets the binder used to bind data to views. * * @param viewBinder the binder used to bind data to views, can be null to * remove the existing binder * * @see #getViewBinder() */ public void setViewBinder(ViewBinder viewBinder) { mViewBinder = viewBinder; } public void setViewImage(ImageView v, Bitmap bm) { try { v.setImageBitmap(bm); } catch (Exception e ) { System.err.print("Erro in ViewImage"); } } /** * Called by bindView() to set the image for an ImageView but only if * there is no existing ViewBinder or if the existing ViewBinder cannot * handle binding to an ImageView. * * This method is called instead of {@link #setViewImage(ImageView, String)} * if the supplied data is an int or Integer. * * @param v ImageView to receive an image * @param value the value retrieved from the data set * * @see #setViewImage(ImageView, String) */ public void setViewImage(ImageView v, int value) { v.setImageResource(value); } /** * Called by bindView() to set the image for an ImageView but only if * there is no existing ViewBinder or if the existing ViewBinder cannot * handle binding to an ImageView. * * By default, the value will be treated as an image resource. If the * value cannot be used as an image resource, the value is used as an * image Uri. * * This method is called instead of {@link #setViewImage(ImageView, int)} * if the supplied data is not an int or Integer. * * @param v ImageView to receive an image * @param value the value retrieved from the data set * * @see #setViewImage(ImageView, int) */ public void setViewImage(ImageView v, String value) { try { v.setImageResource(Integer.parseInt(value)); } catch (NumberFormatException nfe) { v.setImageURI(Uri.parse(value)); } } /** * Called by bindView() to set the text for a TextView but only if * there is no existing ViewBinder or if the existing ViewBinder cannot * handle binding to an TextView. * * @param v TextView to receive text * @param text the text to be set for the TextView */ public void setViewText(TextView v, String text) { v.setText(text); } public Filter getFilter() { if (mFilter == null) { mFilter = new SimpleFilter(); } return mFilter; } /** * This class can be used by external clients of SimpleAdapter to bind * values to views. * * You should use this class to bind values to views that are not * directly supported by SimpleAdapter or to change the way binding * occurs for views supported by SimpleAdapter. * * @see SimpleAdapter#setViewImage(ImageView, int) * @see SimpleAdapter#setViewImage(ImageView, String) * @see SimpleAdapter#setViewText(TextView, String) */ public static interface ViewBinder { /** * Binds the specified data to the specified view. * * When binding is handled by this ViewBinder, this method must return true. * If this method returns false, SimpleAdapter will attempts to handle * the binding on its own. * * @param view the view to bind the data to * @param data the data to bind to the view * @param textRepresentation a safe String representation of the supplied data: * it is either the result of data.toString() or an empty String but it * is never null * * @return true if the data was bound to the view, false otherwise */ boolean setViewValue(View view, Object data, String textRepresentation); } /** * <p>An array filters constrains the content of the array adapter with * a prefix. Each item that does not start with the supplied prefix * is removed from the list.</p> */ private class SimpleFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); if (mUnfilteredData == null) { mUnfilteredData = new ArrayList<Map<String, ?>>(mData); } if (prefix == null || prefix.length() == 0) { ArrayList<Map<String, ?>> list = mUnfilteredData; results.values = list; results.count = list.size(); } else { String prefixString = prefix.toString().toLowerCase(); ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData; int count = unfilteredValues.size(); ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count); for (int i = 0; i < count; i++) { Map<String, ?> h = unfilteredValues.get(i); if (h != null) { int len = mTo.length; for (int j=0; j<len; j++) { String str = (String)h.get(mFrom[j]); String[] words = str.split(" "); int wordCount = words.length; for (int k = 0; k < wordCount; k++) { String word = words[k]; if (word.toLowerCase().startsWith(prefixString)) { newValues.add(h); break; } } } } } results.values = newValues; results.count = newValues.size(); } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { //noinspection unchecked mData = (List<Map<String, ?>>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } } }
最后,主程序代码如下
/*
主Activity代码 */ public class ListViewTest extends Activity { /** Called when the activity is first created. */ private ListView listv; private String urladdress = "http://www.csdnimg.cn/www/images/csdnindex_logo.gif"; //图片的URL地址 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listv = (ListView) findViewById(R.id.list); //关联到mian的ListView ArrayList<Map<String, Object>> arrayl = new ArrayList<Map<String, Object>>(); Bitmap bm = new UrlToBitmap(urladdress).returnBitMap(); //先把URL资源转成Bitmap for(int count = 0; count<15; count++){ Map<String, Object> map= new HashMap<String, Object>(); map.put(“image”, bm); //放入图片资源 map.put(“Text”, “This is a Listview , No. “+ count + ” !”); //放入计数器 arrayl.add(map); } //注意这里是MyAdapter MyAdapter adapte = new MyAdapter(this, R.layout.content, new String[] {“image”, “Text”}, new int[]{R.id.img, R.id.text}); listv.setAdapter(adapter); } }