2012-02-05 59 views
1

我有一個自定義的baseadapter,它會對一些圖像進行一些延遲加載,然後對佈局進行膨脹,以便最終獲得一個listview,其中我有一個圖像和文本在一個行。自定義適配器:獲取在充氣列表視圖中點擊項目的項目編號

當用戶按下列表視圖中的一個項目時,比如說項目0(頂部項目),我想顯示一個包含特定內容的對話框。此內容取決於商品編號 - 因此,商品0顯示的內容與商品1不同,等等。

這裏是自定義適配器的getView方法:

public View getView(int position, View convertView, ViewGroup parent) 
{ 
    View vi=convertView;   
    if(convertView==null) 
    { 
     vi = inflater.inflate(R.layout.facebook_item, null);       
     vi.setClickable(true); 
     vi.setOnClickListener(new OnClickListener() 
     { 
      @Override 
      public void onClick(View v) 
      {     
       String s = "test"; 
       Toast.makeText(myContext, s, Toast.LENGTH_SHORT).show(); 
      } 
     }); 
    }   

    TextView text=(TextView)vi.findViewById(R.id.text); 
    ImageView image=(ImageView)vi.findViewById(R.id.image); 
    text.setText(msg[position]); 
    text.getLineCount(); 
    imageLoader.DisplayImage(data[position], image); 
    return vi; 
} 

這裏的關鍵是怎麼回事在onClick方法。我想有一個項目參數,但這是不可能的這個OnClickListener。正常的列表視圖是可能的,我知道這一點。

那麼 - 如何確定哪個項目被點擊?

PS:我試圖想到使用某種vi.setTag(<<number>>);,但我沒有看到如果沒有爲列表視圖的所有項目設置相同的標記,可以做到這一點。

+0

產品編號從哪裏來?你爲什麼不直接使用'setTag'和特定視圖的特定項目號? – Cody 2012-02-05 18:40:42

回答

5

爲什麼不在ListView本身上使用onItemClickListener?

您的適配器應該包含一個對象類型的列表(沒有嚴格的規則,但它有助於更​​輕鬆地管理項目)。例如

class MsgObject{ 
    String msg; 
    String data 

    //TODO Getters/Setters goes here 
} 

然後你CustomAdapter將只包含

List<MsgObject> objectList; 

然後你getView將類似於這樣

MsgObject m = (MsgObject)getObject(position); 
    TextView text=(TextView)vi.findViewById(R.id.text); 
    ImageView image=(ImageView)vi.findViewById(R.id.image); 
    text.setText(m.getMsg()); 
    text.getLineCount(); 
    imageLoader.DisplayImage(m.getData(), image); 
    //Tag id is predefined in xml 
    vi.setTag(R.id.listItemTag, m); 
    return vi; 

現在你的觀點會處理這個作爲一個對象,而不是一個佈局具有多個值。

然後,我們把所有的點擊動作到ListView控件駐留在活動。

listView.setOnItemClickListener(){ 
    new AdapterView.OnItemClickListener(){ 

     @override 
     public onItemClick(AdapterView<?> parent, View view, int position, long id){ 
      MsgObject m = (MsgObject)view.getTag(R.id.listItemTag); 
      Toast.makeText(context, "Pos[" + position 
       + "] clicked, with msg: " + m.getMessage(), Toast.LENGTH_SHORT).show(); 
     } 
    } 

}; 

這是我有我的延遲加載的ImageView ListView控件以及方式。然後,您將能夠訪問與該視圖關聯的對象以及被點擊的位置。

如果你想分開msg和數據。你可以使用setTag(id,obj);兩個對象等

setTag(R.id.listItemMsg, msg[position]); 
setTag(R.id.listItemData, data[position]); 

UPDATE:我CustomAdapter的例子

/** 
* Adapter for displaying Place selection list. 
* @author Poohdish Rattanavijai 
* 
*/  
public class PlaceAdapter extends BaseAdapter { 
    private static final String TAG = PlaceAdapter.class.getSimpleName(); 
    private List<PlaceVO> list; // <-- list of PlaceVOs 
    private Context context; 
    private int viewResourceId; 

    /** 
    * 
    * @param context Context 
    * @param viewResourceId Layout ID for each item 
    * @param list resource list to populate 
    */ 
    public PlaceAdapter(Context context, int viewResourceId, List<PlaceVO> list){ 
     this.context = context; 
     this.viewResourceId = viewResourceId; 
     this.list = list; 
    } 

    /** 
    * Number of result in the list plus one (for +add at the last item) 
    */ 
    @Override 
    public int getCount() { 

     if(null != list){ 
      return list.size(); 
     } 

     return 1; 
    } 

    @Override 
    public Object getItem(int arg0) { 
     if(null != list){ 
      try { 
       return list.get(arg0); 
      } catch (IndexOutOfBoundsException e) { 
       return null; 
      } 
     } 
     return null; 
    } 

    @Override 
    public long getItemId(int position) { 
//  if(null != list){ 
//   try { 
//    return list.get(position).getId(); 
//   } catch (IndexOutOfBoundsException e) { 
//    return 0; 
//   } 
//  } 
     return 0; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if(null == convertView){ 
      /** 
      * View does not exist, populate. 
      */ 
      LayoutInflater inflater = LayoutInflater.from(this.context); 
      convertView = inflater.inflate(this.viewResourceId, parent, false); 
     } 
     ViewHolder holder = (ViewHolder)convertView.getTag(R.id.adpter_view); 

     if(null == holder){ 
      Log.d(TAG, "holder not found, init."); 
      /** 
      * ViewHolder does not exists for this view; create and assign respective view. 
      */ 
      holder = new ViewHolder(); 
      holder.title = (TextView) convertView.findViewById(R.id.title); 
      holder.details = (TextView) convertView.findViewById(R.id.details); 
      holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
      holder.progress = (ProgressBar) convertView.findViewById(R.id.progress); 
     } 

     PlaceVO v = (PlaceVO)getItem(position); // <-- GetItem 

     if(null != v){ 
      Log.d(TAG, "Place not null"); 
      if(HelperUtil.IsNotNullOrEmpty(v.getName())){ 
       Log.d(TAG, "Name: " + v.getName()); 
       holder.title.setText(v.getName()); 
      } 

      if(HelperUtil.IsNotNullOrEmpty(v.getVicinity())){ 
       Log.d(TAG, "details: " + v.getVicinity()); 
       holder.details.setText(v.getVicinity()); 
      } 

      if(HelperUtil.IsNotNullOrEmpty(v.getIcon())){ 
       holder.progress.setVisibility(View.VISIBLE); 
       holder.icon.setVisibility(View.GONE); 
          //TODO Initialize LazyLoad 
      }else{ 
       holder.progress.setVisibility(View.VISIBLE); 
       holder.icon.setVisibility(View.GONE); 
      } 
     } 
      // Two tags, one for holder, another for the VO 
     convertView.setTag(R.id.adpter_view, holder); 
     convertView.setTag(R.id.adpter_object, v); 
     return convertView; 
    } 

    static class ViewHolder{ 
     TextView title; 
     TextView details; 
     ImageView icon; 
     ProgressBar progress; 
    } 
} 

內活動我處理項目點擊行動

OnItemClickListener itemClick = new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> arg0, View arg1, 
        int arg2, long arg3) { 
       PlaceVO v = (PlaceVO)arg1.getTag(R.id.adpter_object); // <-- get object using tag. 
       switchToPlaceScreen(v); 
      } 
     }; 
listView.setOnItemClickListener(itemClick); 

希望這回答你的問題:)

+0

謝謝 - 看起來像這樣可以工作。您可以詳細說明如何編寫該類MsgObject?我的意思是你沒有寫getMsg()和getData()方法。實際的msg和數據字符串在哪裏設置?另外 - 在哪裏'必須使用objectList'? – eightx2 2012-02-05 19:04:27

+0

你將需要getter/setter,我只是省略了它們以保持簡單。 – RobGThai 2012-02-06 02:56:46

+0

管理使其與您首先發布的代碼和其他示例的組合一起使用。乾杯! – eightx2 2012-03-19 20:37:20

1
text.setText(msg[position]); 
text.getLineCount(); 
imageLoader.DisplayImage(data[position], image); 

在您創建自定義適配器時,您希望儘可能使用getItem(int position)引用項目。避免使用您在Adapter構造函數中傳遞的實際數組來引用它。

嘗試覆蓋您的適配器上的getItem(int position)getItemId(int position),並在您的getView中使用該代替陣列本身。

相關問題