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

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

【问题讨论】:

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

标签: android android-listview android-view android-adapter


【解决方案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();
                    }
        
        
        
                }
            });
        

        【讨论】:

          猜你喜欢
          • 2021-03-10
          • 2015-02-16
          • 1970-01-01
          • 1970-01-01
          • 2012-01-31
          • 2013-12-30
          • 1970-01-01
          • 2015-05-18
          • 1970-01-01
          相关资源
          最近更新 更多