Vraag Android - Get ListView item height?


Is er een manier om de hoogte van ListViewItem in code te krijgen, wanneer er geen daadwerkelijke items in de lijst staan?

Mijn ListViewItem-indeling:

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

Ik heb geprobeerd het via Inflater te krijgen:

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

Maar het is terugkeer 0;

Bedankt!


18
2017-07-29 10:17


oorsprong


antwoorden:


In Android is aan een weergave alleen de breedte en hoogte toegewezen wanneer de weergave is voltooid. Dus tenzij je lijst wordt weergegeven ten minste zodra je listItemHeight niet krijgt. Oplossing voor uw probleem kan zijn dat u min. Hoogte van lijstitem instelt, zodat u ten minste iets heeft om mee te werken in plaats van harde coderingshoogte en -breedte.


4
2017-07-29 13:23



Probeer dit, het zal voor u werken.

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
2017-09-20 13:39



geoptimaliseerde versie van Dwivedi Jicode met verdelers hoogte en zonder onnodige params:

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

10
2017-10-07 12:57



Zoals hierboven al opgemerkt is78 lossen geen van deze oplossingen het ECHTE probleem op dat de hoogte bepaalt van de rij van het lijstitem VOORDAT het wordt weergegeven. Ik had hetzelfde probleem als ik sommige afbeeldingen naar de hoogte van mijn ListView-artikelrijen wilde schalen en ze niet naar een vaste waarde wilde schalen. Als het thema ervoor zou zorgen dat de tekst in andere delen van mijn rijlay-out in hoogte zou variëren, wilde ik de hoogte, zodat ik in mijn getView-routine van mijn adapter de grootte van de bmap dienovereenkomstig kon aanpassen. Ik worstelde met het probleem dat getHeight en alle gemeten hoogtes nul rapporteren totdat de rij is weergegeven. Voor mij was het te laat om de hoogten te zien die later klopten.

Mijn oplossing is om een ​​onLayoutChangedListener () de eerste keer te maken via getView en alleen voor rij 0. De listener wordt geactiveerd zodra getView voor de eerste positie (0) het uitvoeren voltooit en op dat moment geeft de parameter 'bottom' aan u de hoogte van de rij. Ik registreer dit in een aangepaste adapterklasvariabele, zodat het beschikbaar is als een hoogteparameter zonder de hoogte opnieuw te hoeven ophalen.

De luisteraar registreert zichzelf als onderdeel van de uitvoering ervan. Dit levert de juiste hoogte op voor rijen 1-N maar niet voor rij nul. Voor rij nul deed ik iets heel ergs. Ik had mijn luisteraar getView AGAIN laten ophalen voor rij 0 na het instellen van een andere aangepaste adapterklasvariabele om de recursie te regelen. De tweede keer dat getView (0) wordt uitgevoerd, wordt de luisteraar niet ingesteld en wordt een geldige parameter voor de hoogte gevonden om mee te werken en is alles goed.

De code staat hieronder - het is niet nodig om me te vertellen hoe verschrikkelijk dit is - als android het niet zo erg hoefde te maken om te vertellen hoe groot de weergave die ik maak, is wanneer ik klaar ben met het invullen van de weergave op basis van de renderparms voor de oppervlak zou ik deze lelijkheid niet hoeven te doen, maar het werkt. Sorry als het formatteren van de code vreselijk is ...

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
2018-01-05 23:23