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

Posted

技术标签:

【中文标题】android - listview 按位置获取项目视图【英文标题】:android - listview get item view by position 【发布时间】:2014-09-08 19:07:21 【问题描述】:

我有带有自定义适配器(基本适配器)的列表视图。我想按位置从列表视图中获取视图。我试过 mListView.getChildAt(position) ,但它不起作用。如何按位置获取项目视图?

【问题讨论】:

您需要解释在您的情况下“不工作”是什么意思。还要发布不起作用的相关代码以及您可能遇到的任何错误消息。 get view like this listView.getChildAt(pos - listView .getFirstVisiblePosition()); refreshDrawableState() 以更新它.. 简单:) 【参考方案1】:

使用这个:

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);
    

【讨论】:

请添加标题计数:final int childIndex = pos + getHeaderViewsCount() - firstListItemPosition; @iwind 你能详细说明为什么要添加这个吗? @RIT 如果 ListView 有标题视图,子视图将从标题视图开始。所以 ItemChildIndex= HeadersCount + ItemPosition. 当你将 null 传递给 getView 方法时,你会强制它创建一个新视图,它不会使用已经存在的视图。 也许我不理解这个问题......但他似乎正在按位置在列表视图项中寻找一个子视图......所以 onItemClick(AdapterView>) 适配器,查看 v , int pos, long id) VIEWTYPE mView = (VIEWTYPE) v.findViewById(R.id.desiredview)...也许他要求的是非用户交互方式?【参考方案2】:

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

【讨论】:

【参考方案3】:

在绘制 ListView 后更改行视图的外观/任何内容的首选方法是更改​​ ListView 从中提取的数据(传递到适配器的对象数组)中的某些内容,并确保在您的getView() 函数,然后通过调用重绘 ListView

notifyDataSetChanged();

编辑:虽然有办法做到这一点,但如果你需要这样做,可能会做错事。虽然我能想到的边缘情况很少,但通常使用notifyDataSetChanged() 和其他内置机制是一种可行的方法。

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

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,因此您可以设置相同的 Listeners,如上例中的 OnItemClickListener。

【讨论】:

你大错特错了我的朋友:) 你可以通过提供执行点击的孩子的 id 来获取孩子,以下行将返回你执行点击的孩子。一旦你得到那个孩子,你可以改变你想要的任何东西,然后你需要在那个视图上调用 refreshDrawableState() 来更新它:) listView.getChildAt(pos - listView .getFirstVisiblePosition()); 如果您只想获取用户点击的视图,则无需这样做。查看对帖子的修改。 请提供帖子链接查看! 看我回答的EDIT 2 你的回答很好。只是没有准确回答我的问题。事实上,你的答案更准确。我的意思是,通过获取项目视图来更改视图状态/样式是错误的。如果您通过获取项目视图来更改项目视图状态/样式,则更改将在下一次重绘/滚动中消失。很抱歉人们误解了你并因此投票给你。【参考方案4】:
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);
    
);

【讨论】:

【参考方案5】:

这是 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

在 fun getView() 之后添加 fun 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)
    

【讨论】:

【参考方案6】:
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();
            



        
    );

【讨论】:

以上是关于android - listview 按位置获取项目视图的主要内容,如果未能解决你的问题,请参考以下文章

从具有按钮的 ListView 获取列表项的位置

如何将ListView选中的item编号提取出来

Android Listview 行重复项

Android Widget:在 ListView 中获取位置

android在后台获取位置并更新listview

如何在android中获取ListView反向位置?