关于Spinner的解释及基本用法,已经可以找到很多例子:

Spinner中文API:http://www.cnblogs.com/over140/archive/2010/11/17/1879794.html

用法:http://blog.csdn.net/dadahacker/archive/2010/07/17/5741865.aspx 

http://yilee.info/android-spinner.html

在这里,我想向大家介绍一种高级的用法,在下拉列表的菜单项中显示相应的Icon,解决问题的关键就是需要重写Adapter,关于Adapter呢,大家可以参考http://yahaitt.javaeye.com/blog/453060

这不是本文的重点,本范例主要通过重写Adapter,。

一般我们需要重写Adapter类的四个方法即可,分别是public int getCount() 、public Object getItem(int position)、public long getItemId(int position) 
和public View getView(int position, View convertView, ViewGroup parent)。

新建一个IconSpinnerAdapter类,继承BaseAdapter,实现上面四个必须覆盖的方法:


    
    
  1. public class IconSpinnerAdapter extends BaseAdapter { 
  2.     private Context mContext; 
  3.     private int mDropDownResource; 
  4.     private boolean mNotifyOnChange = true
  5.     private List<BabyInfo> mBabyInfoList; 
  6.     private LayoutInflater mInflater; 
  7.     private int mResource; 
  8.     private int mTextViewResourceId; 
  9.     private int mImageViewResourceId; 
  10.     private ArrayList<BabyInfo> mOriginalValues; 
  11.     private Object mLock; 
  12.     @Override 
  13.     public int getCount() { 
  14.         return mBabyInfoList.size(); 
  15.     } 
  16.  
  17.     @Override 
  18.     public Object getItem(int position) { 
  19.         return mBabyInfoList.get(position); 
  20.     } 
  21.  
  22.     @Override 
  23.     public long getItemId(int position) { 
  24.         return mBabyInfoList.get(position).getBabyID(); 
  25.     } 
  26.  
  27.     @Override 
  28.     public View getView(int position, View convertView, ViewGroup parent) { 
  29.         return createViewFromResource(position, convertView, parent, mResource); 
  30.     } 
  31.  
  32.     private View createViewFromResource(int position, View convertView, 
  33.             ViewGroup parent, int resource) { 
  34.         View view; 
  35.         ImageView imageView; 
  36.         TextView text; 
  37.         if (convertView == null) { 
  38.             view = mInflater.inflate(resource, parent, false); 
  39.         } else { 
  40.             view = convertView; 
  41.         } 
  42.         BabyInfo babyInfo = (BabyInfo) getItem(position); 
  43.         imageView = (ImageView) view.findViewById(mImageViewResourceId); 
  44.         imageView.setAdjustViewBounds(true); 
  45.         imageView.setImageResource(babyInfo.getImgResource()); 
  46.         text = (TextView) view.findViewById(mTextViewResourceId); 
  47.         text.setText(babyInfo.getBabyName()); 
  48.         return view; 
  49.     } 
  50.  
  51.     public IconSpinnerAdapter(Context context, int resource, 
  52.             int imageViewResourceId, int textViewResourceId) { 
  53.         mContext = context; 
  54.         mInflater = (LayoutInflater) context 
  55.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
  56.         mResource = mDropDownResource = resource; 
  57.         mBabyInfoList = new ArrayList<BabyInfo>(); 
  58.         mImageViewResourceId = imageViewResourceId; 
  59.         mTextViewResourceId = textViewResourceId; 
  60.     } 
  61.  
  62.     public IconSpinnerAdapter(Context context, int resource, 
  63.             int imageViewResourceId, int textViewResourceId, 
  64.             List<BabyInfo> babyInfoList) { 
  65.         mContext = context; 
  66.         mInflater = (LayoutInflater) context 
  67.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
  68.         mResource = mDropDownResource = resource; 
  69.         mBabyInfoList = babyInfoList; 
  70.         mImageViewResourceId = imageViewResourceId; 
  71.         mTextViewResourceId = textViewResourceId; 
  72.     } 
  73.      
  74.     /** 
  75.      * Sets the layout resource to create the drop down views. 
  76.      *  
  77.      * @param resource 
  78.      *            the layout resource defining the drop down views 
  79.      */ 
  80.     public void setDropDownViewResource(int resource) { 
  81.         mDropDownResource = resource; 
  82.     } 
  83.  
  84.     @Override 
  85.     public View getDropDownView(int position, View convertView, ViewGroup parent) { 
  86.         return createViewFromResource(position, convertView, parent, 
  87.                 mDropDownResource); 
  88.     } 

当然,为了使功能更加强大,可以重写其他方法:


     
     
  1. /** 
  2.      * Adds the specified object at the end of the array. 
  3.      *  
  4.      * @param babyInfo 
  5.      *            The baby info to add at the end of the array. 
  6.      */ 
  7.     public void add(BabyInfo babyInfo) { 
  8.         if (mOriginalValues != null) { 
  9.             synchronized (mLock) { 
  10.                 mOriginalValues.add(babyInfo); 
  11.                 if (mNotifyOnChange) 
  12.                     notifyDataSetChanged(); 
  13.             } 
  14.         } else { 
  15.             mBabyInfoList.add(babyInfo); 
  16.             if (mNotifyOnChange) 
  17.                 notifyDataSetChanged(); 
  18.         } 
  19.     } 
  20.  
  21.     /** 
  22.      *  
  23.      * @param babyInfo 
  24.      *            The baby info to insert into the array. 
  25.      * @param index 
  26.      *            The index at which the object must be inserted. 
  27.      */ 
  28.     public void insert(BabyInfo babyInfo, int index) { 
  29.         if (mOriginalValues != null) { 
  30.             synchronized (mLock) { 
  31.                 mOriginalValues.add(index, babyInfo); 
  32.                 if (mNotifyOnChange) 
  33.                     notifyDataSetChanged(); 
  34.             } 
  35.         } else { 
  36.             mBabyInfoList.add(index, babyInfo); 
  37.             if (mNotifyOnChange) 
  38.                 notifyDataSetChanged(); 
  39.         } 
  40.     } 
  41.  
  42.     /** 
  43.      * Removes the specified object from the array. 
  44.      *  
  45.      * @param babyInfo 
  46.      *            The baby info to remove. 
  47.      */ 
  48.     public void remove(BabyInfo babyInfo) { 
  49.         if (mOriginalValues != null) { 
  50.             synchronized (mLock) { 
  51.                 mOriginalValues.remove(babyInfo); 
  52.             } 
  53.         } else { 
  54.             mBabyInfoList.remove(babyInfo); 
  55.         } 
  56.         if (mNotifyOnChange) 
  57.             notifyDataSetChanged(); 
  58.     } 
  59.  
  60.     /** 
  61.      * Remove all elements from the list. 
  62.      */ 
  63.     public void clear() { 
  64.         if (mOriginalValues != null) { 
  65.             synchronized (mLock) { 
  66.                 mOriginalValues.clear(); 
  67.             } 
  68.         } else { 
  69.             mBabyInfoList.clear(); 
  70.         } 
  71.         if (mNotifyOnChange) 
  72.             notifyDataSetChanged(); 
  73.     } 
  74.  
  75.     /** 
  76.      * Sorts the content of this adapter using the specified comparator. 
  77.      *  
  78.      * @param comparator 
  79.      *            The comparator used to sort the objects contained in this 
  80.      *            adapter. 
  81.      */ 
  82.     public void sort(Comparator<? super BabyInfo> comparator) { 
  83.         Collections.sort(mBabyInfoList, comparator); 
  84.         if (mNotifyOnChange) 
  85.             notifyDataSetChanged(); 
  86.     } 
  87.  
  88.     /** 
  89.      * 更改数据 
  90.      *  
  91.      * @param babyInfoList 
  92.      */ 
  93.     public void updateDataSource(List<BabyInfo> babyInfoList) { 
  94.         clear(); 
  95.         mBabyInfoList = babyInfoList; 
  96.     } 
使用到一个自定义的BabyInfo类,懒得修改,直接拿过来用了,你可以封装其他对象:

      
      
  1. public class BabyInfo { 
  2.     /** 
  3.      * 构造函数 
  4.      *  
  5.      * @param babyId 
  6.      * @param babyName 
  7.      * @param birthDate 
  8.      * @param gender 
  9.      * @param createTime 
  10.      * @param updateTime 
  11.      * @param imgUri 
  12.      * @param weight 
  13.      * @param height 
  14.      * @param note 
  15.      */ 
  16.     public BabyInfo(int babyId, String babyName, long birthDate, 
  17.             long createTime, long updateTime, int imgResource, float 
  18. weight, float height, String note) { 
  19.         super(); 
  20.         this.babyId = babyId; 
  21.         this.babyName = babyName; 
  22.         this.birthDate = birthDate; 
  23.         this.createTime = createTime; 
  24.         this.updateTime = updateTime; 
  25.         this.imgResource = imgResource; 
  26.         this.weight = weight; 
  27.         this.height = height; 
  28.         this.note = note; 
  29.     } 
  30.  
  31.     public int getBabyID() { 
  32.         return babyId; 
  33.     } 
  34.  
  35.     public void setBabyID(int babyID) { 
  36.         this.babyId = babyID; 
  37.     } 
  38.  
  39.     public String getBabyName() { 
  40.         return babyName; 
  41.     } 
  42.  
  43.     public void setBabyName(String babyName) { 
  44.         this.babyName = babyName; 
  45.     } 
  46.  
  47.     public long getBirthDate() { 
  48.         return birthDate; 
  49.     } 
  50.  
  51.     public void setBirthDate(long birthDate) { 
  52.         this.birthDate = birthDate; 
  53.     } 
  54.  
  55.     public long getCreateTime() { 
  56.         return createTime; 
  57.     } 
  58.  
  59.     public void setCreateTime(long createTime) { 
  60.         this.createTime = createTime; 
  61.     } 
  62.  
  63.     public long getUpdateTime() { 
  64.         return updateTime; 
  65.     } 
  66.  
  67.     public void setUpdateTime(long updateTime) { 
  68.         this.updateTime = updateTime; 
  69.     } 
  70.  
  71.     public int getImgResource() { 
  72.         return imgResource; 
  73.     } 
  74.  
  75.     public void setImgResource(int imgResource) { 
  76.         this.imgResource = imgResource; 
  77.     } 
  78.  
  79.     public float getWeight() { 
  80.         return weight; 
  81.     } 
  82.  
  83.     public void setWeight(float weight) { 
  84.         this.weight = weight; 
  85.     } 
  86.  
  87.     public float getHeight() { 
  88.         return height; 
  89.     } 
  90.  
  91.     public void setHeight(float height) { 
  92.         this.height = height; 
  93.     } 
  94.  
  95.     public void setNote(String note) { 
  96.         this.note = note; 
  97.     } 
  98.  
  99.     public String getNote() { 
  100.         return note; 
  101.     } 
  102.  
  103.     private int babyId; 
  104.     private String babyName; 
  105.     private long birthDate; 
  106.     private long createTime; 
  107.     private long updateTime; 
  108.     private int imgResource; 
  109.     private float weight; 
  110.     private float height; 
  111.     private String note; 
  112. }
使用方法:

     
     
  1. spinner = (Spinner) findViewById(R.id.Spinner); 
  2. iconSpinnerAdapter = new IconSpinnerAdapter(this
  3. R.layout.icon_spinner_dropdown_item, R.id.imageView, R.id.textView); 
  4. List<BabyInfo> babyInfoList = new ArrayList<BabyInfo>(5); 
  5. babyInfoList.add(new BabyInfo(1"Lucky"000
  6. android.R.drawable.ic_menu_myplaces, 00null)); 
  7. babyInfoList.add(new BabyInfo(2"Breezy"000
  8. android.R.drawable.ic_menu_my_calendar, 00null)); 
  9. babyInfoList.add(new BabyInfo(3"Lucy"000
  10. android.R.drawable.ic_menu_today, 00null)); 
  11. babyInfoList.add(new BabyInfo(4"Emma"000
  12. android.R.drawable.ic_menu_month, 00null)); 
  13. babyInfoList.add(new BabyInfo(5"Frances  "000
  14. android.R.drawable.ic_menu_compass, 00null)); 
  15. iconSpinnerAdapter.updateDataSource(babyInfoList); 
  16. spinner.setAdapter(iconSpinnerAdapter); 
方法都很简单,关键是要理解必须重载那几个方法的作用,系统什么时候调用,比如getCount()会在绑定的时 候,首先要确定有多少项,getItemId返回相应行绑定的id,当Item的Click或者长按事件中的参数long itemId,就会调用这个方法返回相应id,绑定的时候,就会循环调用public View getView(int position, View convertView, ViewGroup parent)方法等。
最后看一下效果,Spinner没有控制样式,那个向下箭头的Image已经变形了: