2012-02-05 28 views
1

私はいくつかのイメージのいくつかの遅延読み込みを行い、レイアウトを膨らませるカスタムbaseadapterを持っていますので、イメージビューとテキスト行。カスタムアダプター:膨らんだリストビューでクリックしたアイテムのアイテム番号を取得

ユーザがリストビューの1つの項目、たとえば項目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

答えて

5

なぜListView自体でonItemClickListenerを使用しないのですか?

アダプタには、1つのオブジェクトタイプのリストが含まれている必要があります(厳密なルールはありませんが、アイテムの管理がはるかに簡単です)。例

class MsgObject{ 
    String msg; 
    String data 

    //TODO Getters/Setters goes here 
} 

について次に、あなたのCustomAdapterはその後、あなたのgetViewメソッドは、今すぐあなたのビューではなく、1つのレイアウトの1つのオブジェクトとしてこれを処理します。この

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; 

に似てます

List<MsgObject> objectList; 

が含まれています複数の値を持つ

その後、我々は、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を持っている方法です。次に、そのビューに結び付けられたオブジェクト、およびクリックされた位置にアクセスすることができます。

メッセージとデータを別々にしたい場合は、 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

+0

getter/setterが必要ですが、単純にするために省略しました。 – RobGThai

+0

あなたが最初に投稿したコードとあなたの他の例の組み合わせで動作するように管理します。乾杯! – eightx2

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

カスタムアダプターを作成するには、できるだけgetItem(int position)を使用して項目を参照する必要があります。アダプタコンストラクタで渡す実際の配列を使用して参照するのは避けてください。

アダプターでgetItem(int position)getItemId(int position)を無効にして、getView内の配列自体の代わりに使用してください。

関連する問題