单击特定视图时,如何在列表视图中获取项目的位置?

时间:2011-03-04 17:53:46

标签: android listview click android-arrayadapter

正如标题所示,当我点击项目内的视图时,我想知道项目的确切位置。

假设我在ArrayAdapter的getView()方法中有以下代码:

...
holder = new ViewHolder ();
holder.iconAction = (ImageView)convertView.findViewById (R.id.download_item_iconAction);
holder.iconAction.setOnClickListener (new View.OnClickListener(){
    @Override
    public void onClick (View v){
        //Item X is clicked
    }
});
...

在onClick()中,我知道点击的视图,v,但我不知道项目的位置。

我们来做个伎俩。当getView()创建视图时,我将在ViewHolder中保存位置:

public View getView (int position, View convertView, ViewGroup parent){
    ViewHolder holder;
    if (convertView == null){
        holder = new ViewHolder ();
        holder.iconAction = (ImageView)convertView.findViewById (id);
        holder.iconAction.setOnClickListener (new View.OnClickListener(){
            @Override
            public void onClick (View v){
                int pos = (Integer)v.getTag ();
            }
        });
        holder.iconWait.setTag (position);

        ...
    }else{
        holder = (ViewHolder)convertView.getTag ();
    }

    ...
}

此代码有效......但并非总是如此。如果必须滚动列表以查看视图被回收的所有项目。假设列表有10个元素,只有5个可见(可见意味着:如果我们看到一个项目的1个像素行,则此项目可见)。现在,如果我们向下滚动,我们将看到第六个元素,但第一个(0)仍然可见。我们滚动一点,第一个元素将被隐藏,我们将看到第七个元素出现,但这个新元素的视图是第一个元素(0)的视图。
所以我保存了位置:0,1,2,3,4和5.第七个元素(6)将保存位置0:错误。

获取单击回调的另一种方法是使用ListView的OnItemClickListener侦听器:

listView = getListView ();
listView.setOnItemClickListener (new AdapterView.OnItemClickListener(){
    @Override
    public void onItemClick (AdapterView<?> parentView, View childView, int position, long id){
        ...
    }
});

如果我向下滚动,我会得到确切的位置,但是通过这种方式,我会在点击项目时收到回调,无论点击的子视图如何。

感谢。

4 个答案:

答案 0 :(得分:7)

你几乎就在那里,你需要做的就是在if / else子句之后设置标签。这是为了确保在视图被回收时以及从新创建时更新标记。

e.g

    if (convertView == null){
        holder = new ViewHolder ();
        ...
    }else{
        holder = (ViewHolder)convertView.getTag ();
    }
 holder.iconWait.setTag (position);

答案 1 :(得分:3)

本地匿名类可以引用最终局部变量。

通过将position方法更改为

来使getView()成为最终版本
public View getView (final int position, View convertView, ViewGroup parent) {

然后您可以在OnClickListener

中引用位置
holder.iconAction.setOnClickListener (new View.OnClickListener(){
    @Override
    public void onClick (View v){
        ... use position here ...
    }
});

答案 2 :(得分:0)

你的第二个答案(在一个元素上设置标签)如果你将holder.iconWait.setTag (position)移到if / then语句之外就行了 - 也就是说,你应该在回收的行上设置标签,而不仅仅是新膨胀的。

答案 3 :(得分:0)

我还需要添加其他数据以传递给onClick,它也可以使用字符串。

holder.iconWait.setTag ("String data here");