web-dev-qa-db-ja.com

ListView addHeaderViewにより、位置が1つ増えますか?

以下は、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を追加するときの通常の動作ですか??そして、私のアダプターの問題を克服する方法は?

94
d1rk

私はこの問題に出くわしましたが、最良の方法はListViewバージョンがヘッダーを説明するときにListView.getItemAtPosition(position)の代わりにListAdapter.getItem(position)を使用するようです。

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

myListView.getItemAtPosition(position)
112
Ian Warwick

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

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

        }
    });
31
farid_z

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

27
akshaydashrath

AdapterView.OnItemClickListenerを実装するときは、位置からヘッダーを差し引くだけです。

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

コードを変更する必要はありません。以下のコードを使用するだけです。

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

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

9
cycDroid

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

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listAdapter.getItem((int) id);
}
5
Heinrisch

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

ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false);
list.addHeaderView(headerView);
headerView.setEnabled(false);
headerView.setOnClickListener(null);
3

GetSelectedItemPosition()を使用します。アダプターのデータセット内で現在選択されているアイテムの位置を返します。この方法では、ヘッダーまたはフッターのサイズを心配する必要はありません。

0
luhaiwork

@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);
        }
    }
});
0
Peter Shannon

これは誰かを助け、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);
0
truespan