ListView addHeaderView导致位置增加1?

d1r*_*1rk 95 android listview listadapter

下面是一个带有ListView的代码片段.我添加了一个emptyView和一个headerView.添加headerView会导致onItemClick中的位置增加1.

因此,如果没有headerView,第一个列表元素将具有位置0,而headerView将第一个列表元素的位置为1!

这会导致我的适配器出错,例如在调用getItem()和使用其他方法时,请参见下文.奇怪的是:在适配器的getView()方法中,即使添加了headerView,也要求第一个列表元素的位置为0!

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ListView list = (ListView) viewSwitcher.findViewById(R.id.list);
    View emptyView = viewSwitcher.findViewById(R.id.empty);
    list.setEmptyView(emptyView);

    View sectionHeading = inflater.inflate(R.layout.heading, list, false);
    TextView sectionHeadingTextView = (TextView) sectionHeading.findViewById(R.id.headingText);
    sectionHeadingTextView.setText(headerText);
    list.addHeaderView(sectionHeading);

    list.setAdapter(listAdapter);

    list.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listAdapter.getItem(position);
            //Do something with it
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

一些适配器方法:

@Override
public int getViewTypeCount() {
    return TYPE_COUNT;
}

@Override
public int getItemViewType(int position) {
    return (position < items.size()) ? ITEM_NORMAL : ITEM_ADVANCED;
}

    @Override
public Product getItem(int position) {
    return items.get(position);
}
@Override
public boolean areAllItemsEnabled() {
    return false;
}

@Override
public boolean isEnabled(int position) {
    return (position < items.size());
}
Run Code Online (Sandbox Code Playgroud)

这是添加headerView时的正常行为吗?以及如何克服我的适配器中的问题?

Ian*_*ick 113

我刚刚遇到这个问题,最好的方法似乎是使用ListView.getItemAtPosition(position)而不是ListAdapter.getItem(position)作为ListView标题的版本帐户,即: -

改为:

myListView.getItemAtPosition(position)
Run Code Online (Sandbox Code Playgroud)

  • 这对我来说实际上没什么用,而使用@whuandroid装饰/包装适配器解决方案呢. (3认同)
  • 你也必须在这种情况下施放物品. (3认同)

far*_*d_z 31

如果您不关心单击标题,请从位置减去标题视图的数量以获取适配器的位置:

        listView.addHeaderView(inflater.inflate(
                R.layout.my_hdr_layout, null), null, false);
        listView.setAdapter(m_adapter);
        listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            position -= listView.getHeaderViewsCount();
            final MyObject object = m_adapter.getItem(position);

        }
    });
Run Code Online (Sandbox Code Playgroud)


aks*_*ath 27

如果您将标题添加到ListView列表中的第一个项目.您可以通过覆盖getCount()更少返回一个项目来补偿这一点,但确保您处理getItem(),getItemId()依此类推,因为标题将是位置0中的项目.

  • "添加的标题视图的数量"可以通过以下方式获得:`ListView.getHeaderViewsCount()` (22认同)
  • 重写getCount()以返回一个较少的项不起作用,因为那时我错过了列表的最后一个列表项.如果列表中只有1个项目,则永远不会调用getView().此外,适配器与列表视图分离,并且不知道是否有添加到列表视图的标头. (6认同)
  • 我想最简单的方法是按照你的建议在OnItemClickListener中设置position = position-(添加的标题视图的数量).我更改了我的适配器以处理headerview本身,因此我不必在listview上调用addHeaderView.虽然适配器有点复杂. (3认同)
  • 在ListItemClick中设置position = position - 1如果附加了一个标题,我认为这就是我在遇到这个特殊问题时所做的,它不是很整齐,但是我能想到的唯一方法 (2认同)
  • 我不知道这是正确的答案.@Ian Warwick发布了正确的版本,不过我认为有点晚了. (2认同)

phi*_*ipp 14

实现时,AdapterView.OnItemClickListener我们只从位置中减去标题.

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    position -= mListView.getHeaderViewsCount();
    // what ever else follows...
}
Run Code Online (Sandbox Code Playgroud)


Ram*_*ula 13

无需更改任何代码.只需使用下面的代码.

 list.setOnItemClickListener(new OnItemClickListener() {
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      parent.getAdapter().getItem(position);
         //Do something with it
     }
});
Run Code Online (Sandbox Code Playgroud)


cyc*_*oid 9

不要使用适配器,请使用getAdapter中的"装饰"适配器.


Hei*_*sch 5

对此的一个解决方案是将id映射到索引.基本上make id返回列表中的索引,点击监听器会执行以下操作:

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listAdapter.getItem((int) id);
}
Run Code Online (Sandbox Code Playgroud)