简体   繁体   English

自定义ListView行中的Clickable元素

[英]Clickable element in custom ListView row

I have created a ListView with custom rows, and within each custom row I would like a particular TextView to be clickable. 我已经创建了一个带有自定义行的ListView,并且在每个自定义行中,我希望可以单击一个特定的TextView。 In the getView method of my custom adapter, I have set an onClickListener to my TextView and implemented onClick(View v) as required. 在自定义适配器的getView方法中,我已将onClickListener设置为TextView并根据需要实现了onClick(View v)。 This is where the problem arises. 这就是问题所在。

In onClick(View v), I require the position of the row of the TextView that was clicked in relation to the adapter data (different to the position parameter of getView()). 在onClick(View v)中,我需要单击的TextView行相对于适配器数据的位置(与getView()的position参数不同)。 After reading around stack overflow and this article in particular, the magic code required to obtain the position of the row of the TextView that was clicked is: 在阅读了有关堆栈溢出的内容后 ,尤其是在阅读了这篇文章之后,获得被单击的TextView行的位置所需的魔术代码为:

final int position = listView.getPositionForView(v);

This code works great and everytime I click a TextView for a particular row, the correct position is returned. 这段代码很好用,每次我单击特定行的TextView时,都会返回正确的位置。 However, when I rotate the phone to change the configuration and then click any of the TextView's, the position that is returned is always -1. 但是,当我旋转手机以更改配置,然后单击任何 TextView时,返回的位置始终为-1。 Rotating the phone back to the original configuration also maintains this behaviour of returning -1 when any TextView is pressed. 将电话旋转回原始配置还可以保持按下任何TextView时返回-1的行为。

Looking at the documentation for getPositionForView, it seems -1 is returned (INVALID_POSITION) if the view "does not correspond to a list item (or it is not currently visible)". 查看getPositionForView的文档,如果视图“不对应于列表项(或当前不可见)”,似乎返回-1(INVALID_POSITION)。 Why is this happening? 为什么会这样呢? Obviously, for me to even be able to click on a TextView the view has to be visible on the screen. 显然,对我来说,甚至还可以单击TextView,该视图必须在屏幕上可见。

If it matters, I am using convertView and the ViewHolder pattern to optimize the ListView. 如果很重要,我将使用convertView和ViewHolder模式来优化ListView。

What am I missing? 我想念什么?

Update: Just to help visualize better, here is what my getView roughly looks like 更新:为了帮助更好地可视化,这是我的getView大致的样子

getView(int position, View convertView, ViewGroup parent) {
        final CustomViewHolder holder;
        View = rowView;
        if (convertView == null) {
            rowView = inflater.inflate(R.layout.listitem, parent, false);
            holder = new CustomViewHolder(rowView);

            holder.textview.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    final int position = listView.getPositionForView(v);
                    //position is always -1 after configuration change
                    Log.d(TAG, "Like button pushed at position: " + position);

                }
            });
            rowView.setTag(postHolder);
        } else {
            rowView = convertView;
            postHolder = (PostListUserPostHolder) convertView.getTag();
        }

        //fill list item with data
    }
    return rowView;
}

UPDATE #2 I seem to have come to a solution. 更新#2我似乎已经解决了。 Instead of passing in a reference to the ListView from the fragment to the adapter, I passed in a reference to the fragment itself into the adapter. 我没有将对片段的Lis​​tView的引用传递给适配器,而是将对片段本身的引用传递给了适配器。 And then I supplied a getter method in the fragment to obtain the ListView and then used the line: 然后,我在片段中提供了一个getter方法以获得ListView,然后使用该行:

final int position = fragment.getListView().getPositionForView(v);

I would've thought that this was essentially the same as what I was doing but it seems it is not the case. 我以为这与我所做的基本上相同,但事实并非如此。 If anyone could perhaps shed some light on what might be happening it would be appreciated. 如果有人可能对可能发生的事情有所了解,将不胜感激。 Otherwise, I am happy that the code is working as expected now! 否则,我很高兴代码现在可以按预期运行!

getView(int position, View convertView, ViewGroup parent) {
        final CustomViewHolder holder;

    if (convertView == null) {
        rowView = inflater.inflate(R.layout.listitem, parent, false);
        holder = new CustomViewHolder();
        convertView .setTag(holder );
    }
    else {

        holder= (CustomViewHolder ) convertView.getTag();
    }

        holder.textview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final int position = listView.getPositionForView(v);
                //position is always -1 after configuration change
                Log.d(TAG, "Like button pushed at position: " + position);

            }
        });

    } 

    //fill list item with data
}
return convertView;

} }

Your getView() is a bit strange. 您的getView()有点奇怪。 The field textview of your holder is never initialized ? 您的持有人的字段textview从未初始化?

The usefulness of the holder is to limit the use of the method findViewById . 持有人的用处是限制方法findViewById的使用。

Here is the skeleton that I would have used : 这是我会使用的骨架:

static class ViewHolder {
  public TextView textview;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
   View rowView = convertView;

   // reuse views
  if (rowView == null) {
       LayoutInflater inflater = context.getLayoutInflater();
       rowView = inflater.inflate(R.layout.listitem, null);
       // configure view holder
       ViewHolder viewHolder = new ViewHolder();
       viewHolder.textview= (TextView) rowView.findViewById(R.id.textview);
       rowView.setTag(viewHolder);
  }
  else {

      ViewHolder holder = (ViewHolder) rowView.getTag();
  }

   // fill data
   holder.textview.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = listView.getPositionForView(v);
            //position is always -1 after configuration change
            Log.d(TAG, "Like button pushed at position: " + position);

        }
    });

    return rowView;
 }
} 

Hopefully it solve your problem ! 希望它能解决您的问题!

have a nice day ! 祝你今天愉快 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM