自定义适配器:在膨胀的列表视图中获取单击项目的项目编号 [英] Custom adapter: get item number of clicked item in inflated listview

查看:28
本文介绍了自定义适配器:在膨胀的列表视图中获取单击项目的项目编号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义 baseadapter,它会延迟加载一些图像,然后对布局进行膨胀,因此我最终得到了一个列表视图,其中在一行中同时包含图像和文本.

I have a custom baseadapter which does some lazy loading of some images, and then inflating the layout so I end up with a listview where I have both image and text in one row.

当用户按下列表视图的一项时,例如项目 0(顶部项目),我想显示一个包含某些特定内容的对话框.此内容取决于项目编号 - 因此项目 0 显示的内容与项目 1 不同,依此类推.

When the user presses one item of the listview, say for example item 0 (top item), I want to show a dialog box with some specific content. This content depends on the item number - so the content shown for item 0 is not the same as for item 1, and so on.

这里是自定义适配器的getView方法:

Here is the getView method of the custom adapter:

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 方法中发生的事情.我想要一个 item 参数,但这对于这个 OnClickListener 是不可能的.普通的列表视图是可能的,我知道.

What's important here is what's going on in the onClick method. I would like to have an item parameter, but this is not possible for this OnClickListener. It's possible for normal listviews, I know that.

那么 - 我如何确定点击了哪个项目?

So - how can I determine which item is clicked?

PS:我曾尝试考虑使用某种 vi.setTag(<<number>>);,但我不知道如何在没有为列表视图的所有项目设置相同的标签.

PS: I've tried to think of using some sort of vi.setTag(<<number>>);, but I don't see how this can be done without having the same tag set for all items of the listview.

推荐答案

为什么不在 ListView 本身上使用 onItemClickListener?

Why not use onItemClickListener on ListView itself?

你的适配器应该包含一个对象类型的列表(没有严格的规则,但它有助于更​​容易地管理项目).例如

Your Adapter should contain a List of one Object type (there is no strict rule, but it helps managing the item much easier). For example

class MsgObject{
    String msg;
    String data

    //TODO Getters/Setters goes here
}

那么你的 CustomAdapter 将只包含

Then your CustomAdapter will only contain

List<MsgObject> objectList;

那么你的 getView 看起来会像这样

Then your getView will looks similar to this

    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;

现在你的视图将把它作为一个对象而不是一个具有多个值的布局来处理.

Now your view will handle this as one object instead of one layout with multiple values.

然后我们将所有的点击动作移到 ListView 所在的 Activity 中.

Then we move all the click action to the Activity which ListView resides in.

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();
        }
    }

};

这也是我的 ListView 和延迟加载 ImageView 的方式.然后您将能够访问绑定到该视图的对象以及点击的位置.

This is the way I have my ListView with Lazy load ImageView as well. Then you will be able to access the object tied to that view and also the position which is clicked.

如果您希望将 msg 和 data 分开.您可以使用 setTag(id, obj);对于两个对象等

If you are so wish to separate msg and data. You can use setTag(id, obj); for both object, etc.

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

更新:我的 CustomAdapter 示例

UPDATE: Example of my 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;
    }
}

Inside Activity 我处理项目点击动作

Inside Activity I handle item click action with

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);

希望这能回答你的问题:)

Hope this answer your question :)

这篇关于自定义适配器:在膨胀的列表视图中获取单击项目的项目编号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆