1

いくつかの画像の遅延読み込みを実行し、レイアウトを拡張するカスタムbaseadapterがあるので、画像とテキストの両方が1行に表示されるリストビューになります。

ユーザーがリストビューの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>>);が、リストビューのすべてのアイテムに同じタグを設定しないと、これをどのように実行できるかわかりません。

4

2 に答える 2

5

ListView自体でonItemClickListenerを使用してみませんか?

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

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;

これで、ビューはこれを複数の値を持つ1つのレイアウトではなく、1つのオブジェクトとして処理します。

次に、すべてのクリックアクションを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とdataを分離したい場合。setTag(id、obj);を使用できます。両方のオブジェクトなど。

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

更新:私の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);

これがあなたの質問に答えることを願っています:)

于 2012-02-05T18:41:26.140 に答える
1
text.setText(msg[position]);
text.getLineCount();
imageLoader.DisplayImage(data[position], image);

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

getItem(int position)アダプタのとをオーバーライドしてみてください。getItemId(int position)そして、の内部の配列自体の代わりにそれを使用してくださいgetView

于 2012-02-05T18:51:16.657 に答える