3

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

假设我在 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

4 回答 4

7

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

例如

    if (convertView == null){
        holder = new ViewHolder ();
        ...
    }else{
        holder = (ViewHolder)convertView.getTag ();
    }
 holder.iconWait.setTag (position);
于 2011-03-04T18:00:47.120 回答
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 ...
    }
});
于 2011-03-04T18:03:16.447 回答
0

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

holder.iconWait.setTag ("String data here");
于 2013-10-03T11:12:10.493 回答
0

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

于 2011-03-04T18:00:05.700 回答