获取 ListView 行的 id / 位置

Get id / position of ListView row

我有一个包含一堆行的 Android ListView。每行包含一个图像和一些文本。如果我单击一行的图像,我想执行操作 A,如果我单击该行中的任何其他位置,我想执行操作 B。这两个操作都需要 ListView 项目的 ID 才能工作。

到目前为止,对于操作 B,我只是使用了列表视图的 onItemClick,我从参数中获取了 id。但是,据我所知,找出用户单击了行本身的哪个视图的唯一方法是向触发操作 A 的 ImageView 添加一个 onClick 事件处理程序。在这种情况下,我只获取被点击的视图,但不是 ImageView 所在行的 ID。

我的问题是 - 如何从 View 对象转到获取 ListView 中父行的 ID?

您可以通过适配器中的 getView() 方法为一行中的每个视图设置点击监听器。

可以在listview的adapter的getView()方法中实现

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1,
            int position, long id)

在此方法中,视图 arg1 为您提供项目视图,您可以通过此 arg1.findViewById(R.id.content); 找到项目内容。这里的位置给你列表视图的项目位置

onItemClickListener 方法已经有一个 onClick interfaceviewposition 传递给它:您可以通过执行 switch 语句并在单击特定视图时执行专用操作。

例如

listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
        String item = listView.getItemAtPosition(position);
        Toast.makeText(this,"You selected : " + item,Toast.LENGTH_SHORT).show();                
    }
});

如图How to create listview onItemclicklistener

你会看到在 onItemClick 接口中它有 View view 作为参数和 int position 作为参数,使用这两个参数在监听器中执行操作.就像我之前提到的,您可以使用 switch 语句。

listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
            String item = listView.getItemAtPosition(position);
            switch(view.getId()) {
               case R.id.imageView:
                      //perform action for imageView using the data from Item (if you have used an MVC pattern)
               break;
               // you can do this for any widgets you wish to listen for click actions
            }           
        }
    });

更新:所有功劳都归功于 How to know which view inside a specific ListView item that was clicked

中的 wwfloyd
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {

    // Check if an existing view is being reused, otherwise inflate the view
    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.one_line, parent, false);
    }

    // This chunk added to get textview click to register in Fragment's onItemClick()
    // Had to make position and parent 'final' in method definition
    convertView.findViewById(R.id.someName).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ((ListView) parent).performItemClick(v, position, 0);
        }
    });
    // do stuff...
}

在您的适配器中将点击侦听器应用于元素,然后触发接口方法,以便您可以识别已被点击的注册小部件,然后在您的 onItemClick 中执行:

public void onItemClick(AdapterView adapterView, View view, int position, long id) {
    long viewId = view.getId();
    switch (viewId) {
       case R.id.someName:
            //widget has been clicked
       break;

       default:
           //row has been clicked
       break;
    }
}

如果您不使用标签,那么您可以

int itemId=...;
OnClickListener customOnClick=...;
imageView.setTag(itemId);
imageView.setOnClickListener(customOnClick);

以及您的自定义 OnClickListener

int itemId = (Integer) view.getTag();

请注意,您可以将 "any" Object 设置为标签,因此您甚至可以设置整个自定义对象,而不仅仅是 id