98

以下は、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
        }
    });
}

いくつかのアダプターメソッド:

@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());
}

これは、headerViewを追加するときの正常な動作ですか?そして、私のアダプターの問題を克服する方法は?

4

11 に答える 11

113

私はこの問題に遭遇したばかりで、ヘッダーのバージョンアカウントとしてではListView.getItemAtPosition(position)なく、を使用するのが最善の方法のようです。ListAdapter.getItem(position)ListView

代わりにこれを行います:

myListView.getItemAtPosition(position)
于 2012-11-15T16:56:11.873 に答える
32

ヘッダーへのクリックを気にしない場合は、位置からヘッダー ビューの数を引いて、アダプターの位置を取得します。

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

        }
    });
于 2013-04-17T14:10:33.100 に答える
27

にヘッダーを追加するListViewと、リストの最初の項目になります。getCount()をオーバーライドして 1 つ少ないアイテムを返すことでこれを補うことができますが、ヘッダーが位置 0 のアイテムになるためgetItem()、などを処理するようにしてください。getItemId()

于 2012-06-19T17:55:30.710 に答える
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
     }
});
于 2013-02-27T05:26:15.007 に答える
9

アダプターを使用しないでください。getAdapter の「装飾された」アダプターを使用してください。

于 2013-01-20T04:03:06.763 に答える
5

これに対する 1 つの解決策は、id を index にマップすることです。基本的に、id がリスト内のインデックスを返すようにすると、クリック リスナーは次のようになります。

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listAdapter.getItem((int) id);
}
于 2012-11-21T08:48:57.510 に答える
3

こんにちは、この方法でこれを解決できます。最初にヘッダービューを作成し、リストに挿入し、最後のステップでsetOnClickListenerを使用できません。その作品は私のために働きます。フィードバック歓迎

ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false);
list.addHeaderView(headerView);
headerView.setEnabled(false);
headerView.setOnClickListener(null);
于 2016-05-23T13:16:46.570 に答える
0

@Ramesh が追加しなかった多くの新しいものを追加するのではなく、いくつかの追加のコンテキストを追加します。

personList.setOnItemClickListener(new OnItemClickListener() {
    @SuppressWarnings("unchecked")
    public void onItemClick( AdapterView<?> parent, View view, int position, long duration) {
        Map<String, Object> person = (Map<String, Object>) parent.getAdapter().getItem(position);
        if (person != null){

            // If the header was clicked on a null  is returned

            OnPersonUiChangeListener listener = (OnPersonUiChangeListener) getActivity();
            listener.onSelectedPersonChanged(person);
        }
    }
});
于 2013-11-26T03:35:18.287 に答える
0

getSelectedItemPosition() を使用します。アダプタのデータ セット内で現在選択されている項目の位置を返します。このメソッドは、ヘッダーまたはフッターのサイズを気にする必要はありません。

于 2015-12-11T02:39:44.293 に答える
0

これは、Farid_z と Philipp の回答を改善して、誰かを助けるかもしれません。setItemChecked と setTitle を次のように正しく適用できます。

        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
        position += 1;
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        position -= 1;
        setTitle(mNavigationDrawerItemTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
于 2016-10-09T11:32:03.120 に答える