web-dev-qa-db-ja.com

Android-ListViewアイテムの高さを取得しますか?

リストに実際のアイテムがない場合に、コードでListViewItemの高さを取得する方法はありますか?

私のListViewItemレイアウト:

<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="?android:attr/listPreferredItemHeight">
...
</LinearLayout>  

Inflaterを使用して取得しようとしました:

View convertView = LayoutInflater.from( this )
    .inflate( R.layout.mail_list_row, null );
int itemHeight = convertView.getHeight();

しかし、それは0を返します。

ありがとう!

18
Maksym Gontar

In Androidビューには、レンダリングが完了したときにのみ幅と高さが割り当てられます。したがって、リストが少なくとも一度レンダリングされない限り、listItemHeightは取得されません。問題の解決策は、いくつかを設定することです。最小リストアイテムの高さ。ハードコーディングの高さと幅の代わりに、少なくとも何かを操作できるようにします。

4
Amit Chintawar

これを試してみてください、それはあなたのために働きます。

private static final int UNBOUNDED = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

// To calculate the total height of all items in ListView call with items = adapter.getCount()
public static int getItemHeightofListView(ListView listView, int items) {
    ListAdapter adapter = listView.getAdapter();

    int grossElementHeight = 0;
    for (int i = 0; i < items; i++) {
        View childView = adapter.getView(i, null, listView);
        childView.measure(UNBOUNDED, UNBOUNDED);
        grossElementHeight += childView.getMeasuredHeight();
    }
    return grossElementHeight;
}
42
Dwivedi Ji

Dwivedi Jiのコードの最適化されたバージョンで、仕切りの高さがあり、不要なパラメーターはありません。

private int calculateHeight(ListView list) {

    int height = 0;

    for (int i = 0; i < list.getCount(); i++) {
        View childView = list.getAdapter().getView(i, null, list);
        childView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        height+= childView.getMeasuredHeight();
    }

    //dividers height
    height += list.getDividerHeight() * list.getCount();

    return height;
}
11
ashakirov

上記のhariseldon78が指摘しているように、これらのソリューションはいずれも、レンダリングされる前にリストアイテム行の高さを決定するというREALの問題を修正しません。一部の画像をListViewアイテムの行の高さに拡大縮小したいのと同じ問題があり、固定値に拡大縮小したくありませんでした。テーマによって行レイアウトの他の部分のテキストの高さが変化する場合は、アダプターのgetViewルーチンでそれに応じてbmapのサイズを変更できるように高さが必要でした。行がレンダリングされるまで、getHeightとすべての測定された高さがゼロを報告するという問題に苦労していました。後で高さが正しいのを見るのは遅すぎました。

私の解決策は、最初にgetViewを介して行0に対してのみonLayoutChangedListener()を作成することです。リスナーは、最初の位置(0)のgetViewの実行が完了するとすぐにトリガーされ、その時点で「bottom」パラメーターが通知します。行の高さ。これをカスタムアダプタクラス変数に記録して、高さを再度取得しなくても高さパラメータとして使用できるようにします。

リスナーは、実行の一部として自分自身の登録を解除します。これにより、行1〜Nに適切な高さが提供されますが、行0には提供されません。行0の場合、私は本当に厄介なことをしました。再帰を制御するために別のカスタムアダプタクラス変数を設定した後、リスナーに行0に対してgetViewAGAINを呼び出させました。 getView(0)を2回実行すると、リスナーはセットアップされず、操作する高さの有効なパラメーターが検出され、すべて問題ありません。

コードは以下のとおりです-これがどれほどひどいのかを教えてください-if Androidは、入力が完了したときに作成しているビューの大きさを判断するのが難しいほどおかしくなりませんでしたビューはサーフェスのレンダリングパラメータに基づいていますが、この醜さを行う必要はありませんが、機能します。コードのフォーマットがひどい場合は申し訳ありません...

int mHeight = 0;

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
... usual boiler plate stuff
    // JUST THE FIRST TIME
    if (position == 0 && mHeight == 0) {
        final View ref = convertView;
        convertView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            public void onLayoutChange(View v, int left, int top, int right,
                   int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                    ref.removeOnLayoutChangeListener(this);
                    mHeight = bottom;
                    firstTime = false;

                    //  NOW LETS REGET THE FIRST VIEW WITH THE HEIGHT CORRECT
                    int visiblePosition = getListView().getFirstVisiblePosition();
                    View view = getListView().getChildAt(0 - visiblePosition);
                    getListAdapter().getView(0, view, getListView());
                    // RECURSION LOL
            }
        });
    }

    // Configure the view for this row
    ....

    // HOW BIG IS THE VIEW?
    // NOW IF NOT FIRSTTIME (MHEIGHT != 0)
    if (mHeight != 0) {
        // DO OUR IMAGE SETUP HERE CAUSE mHeight is RIGHT!
        Log.d(TAG, "mHeight=" + mHeight);
    }

        return convertView;
}
2
Mike Kogan