android-listview按位置获取项目视图


69

我有带有自定义适配器(基本适配器)的listview。我想按位置从listview获取视图。我试过了mListView.getChildAt(position),但是没有用。如何获得按位置查看的项目?


4
您需要说明在您的情况下“不起作用”的含义。还要发布不起作用的相关代码以及您可能遇到的任何错误消息。
codeMagic

2
获取这样的视图listView.getChildAt(pos - listView .getFirstVisiblePosition());<position是您单击的位置)更改视图,然后调用refreshDrawableState()该视图以进行更新
。.simple

Answers:


251

用这个 :

public View getViewByPosition(int pos, ListView listView) {
    final int firstListItemPosition = listView.getFirstVisiblePosition();
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;

    if (pos < firstListItemPosition || pos > lastListItemPosition ) {
        return listView.getAdapter().getView(pos, null, listView);
    } else {
        final int childIndex = pos - firstListItemPosition;
        return listView.getChildAt(childIndex);
    }
}

6
请添加标头计数:final int childIndex = pos + getHeaderViewsCount()-firstListItemPosition;
iwind 2014年

@iwind您能否详细说明为什么添加此内容?
VVB 2014年

1
@RIT如果ListView具有标题视图,则子级将从标题视图开始。因此,ItemChildIndex = HeadersCount + ItemPosition。
iwind 2014年

6
当将null传递给getView方法时,将强制它创建一个新视图,它将不使用已经存在的视图。
2015年

2
也许我不明白这个问题...但是他似乎正在按位置在列表视图项中寻找一个子视图...所以onItemClick(AdapterView <?>)适配器,View v,int pos,long id){ VIEWTYPE mView =(VIEWTYPE)v.findViewById(R.id.desiredview)} ...也许他正在要求一种非用户交互方式?
me_

14

您只能从ListView获得可见的View,因为ListView中的行视图是可重复使用的。如果使用,mListView.getChildAt(0)您将获得第一个可见视图。该视图与适配器在位置处的项目相关联mListView.getFirstVisiblePosition()


4

绘制ListView后,更改外观/行视图内容的首选方法是更改​​ListView绘制数据中的某些内容(传递到Adapter中的对象数组),并确保在getView()中进行说明函数,然后通过调用重绘ListView

notifyDataSetChanged();

编辑:虽然有一种方法可以执行此操作,但是如果您需要执行此操作,则可能是做错了什么。尽管我可以考虑的情况很少,但通常还是使用notifyDataSetChanged()内置机制。

编辑2:人们常犯的错误之一是试图提出自己的方式来响应用户单击/选择ListView中的一行,如本文的评论之一。有一种现有的方法可以做到这一点。这是如何做:

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    /* Parameters
    parent:     The AdapterView where the click happened.
    view:       The view within the AdapterView that was clicked (this will be a view provided by the adapter)
    position:   The position of the view in the adapter.
    id:         The row id of the item that was clicked. */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //your code here
    }
});

ListView具有许多内置功能,对于更简单的情况,无需重新发明轮子。由于ListView扩展了AdapterView,因此您可以设置相同的侦听器,例如上例中的OnItemClickListener


2
您的朋友,您是非常错误的:)您可以通过提供进行点击的孩子的ID来获得孩子,以下行将返回您进行点击的孩子。收到孩子后,您可以更改所需的任何内容,然后需要调用refreshDrawableState()该视图以进行更新:)listView.getChildAt(pos - listView .getFirstVisiblePosition());
AZ_

如果只需要获取用户单击的视图,则无需这样做。查看帖子的编辑内容。
C0D3LIC1OU5

请提供帖子链接以查看!
AZ_

看看我的答案的EDIT 2
C0D3LIC1OU5

1
您的回答很好。只是不能完全回答我的问题。实际上,您的答案更加准确。我的意思是,通过获取项目视图来更改视图状态/样式是错误的。如果通过获取项目视图来更改项目视图的状态/样式,则更改将在下次重新绘制/滚动时消失。很抱歉,人们误解了您,并为此不赞成您。
alashow

1
workignHoursListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent,View view, int position, long id) {
        viewtype yourview=yourListViewId.getChildAt(position).findViewById(R.id.viewid);
    }
});

0

这是VVB发布的功能的Kotlin版本。我在ListView适配器中使用了它,以实现getView()中的“当在当前行的最后一个EditText上按Enter键时,首先转到下一行EditText”功能。

在ListViewAdapter类中,有趣的getView(),如下所示添加lastEditText.setOnKeyListner:

lastEditText.setOnKeyListener { v, keyCode, event ->
    var setOnKeyListener = false
    if (keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_UP) {
        try {
            val nextRow = getViewByPosition(position + 1, parent as ListView) as LinearLayout
            val nextET = nextRow.findViewById(R.id.firstEditText) as EditText
            nextET.isFocusableInTouchMode = true
            nextET.requestFocus()
        } catch (e: Exception) {
            // do nothing
        }
        setOnKeyListener = true
    }
    setOnKeyListener
}

在有趣的getView()之后添加有趣的getViewByPosition(),如下所示:

private fun getViewByPosition(pos: Int, listView: ListView): View? {
    val firstListItemPosition: Int = listView.firstVisiblePosition
    val lastListItemPosition: Int = firstListItemPosition + listView.childCount - 1
    return if (pos < firstListItemPosition || pos > lastListItemPosition) {
        listView.adapter.getView(pos, null, listView)
    } else {
        val childIndex = pos + listView.headerViewsCount - firstListItemPosition
        listView.getChildAt(childIndex)
    }
}

-4
Listview lv = (ListView) findViewById(R.id.previewlist);

    final BaseAdapter adapter = new PreviewAdapter(this, name, age);

    confirm.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub


            View view = null;

            String value;
            for (int i = 0; i < adapter.getCount(); i++) {

                view = adapter.getView(i, view, lv);

                Textview et = (TextView) view.findViewById(R.id.passfare);


                value=et.getText().toString();

                 Toast.makeText(getApplicationContext(), value,
                 Toast.LENGTH_SHORT).show();
            }



        }
    });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.