web-dev-qa-db-fra.com

Listview même hauteur que le contenu

J'ai utilisé une vue de liste personnalisée. Le contenu vient de dynamique Je veux la même hauteur de listview que le contenu.

J'ai utilisé wrap_content mais cela n'aide pas Si je supprime scrollview puis son travail

Code. "Le ScrollView à défilement vertical ne doit pas contenir un autre widget à défilement vertical (ListView)"

<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="@drawable/background_img"
    Android:scrollbars="none" >

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="fill_parent"
    Android:orientation="vertical" >

<ListView
            Android:id="@+id/lstsemtrack"
            Android:layout_width="fill_parent"
            Android:layout_height="wrap_content"
        Android:divider="#f2e4e4"
        Android:dividerHeight="1dip"
             >
        </ListView>

Liste des articles

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical"
    Android:padding="10dip"
    Android:scrollbars="none" >

    <LinearLayout
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:orientation="horizontal"
        Android:weightSum="4" >

        <TextView
            Android:id="@+id/txtBiology"
            style="@style/sem_rowtext"
            Android:layout_width="0dip"
            Android:layout_height="wrap_content"
            Android:layout_gravity="center_vertical"
            Android:layout_marginRight="5dip"
            Android:layout_weight="1"
            Android:text="Biology" />

        <TextView
            Android:id="@+id/txtClass"
            style="@style/sem_rowtext"
            Android:layout_width="0dip"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="Biology - 101" />

        <TextView
            Android:id="@+id/txtGrade"
            style="@style/sem_rowtext"
            Android:layout_width="0dip"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="Grade" />

        <TextView
            Android:id="@+id/txtGrade"
            style="@style/sem_rowtext"
            Android:layout_width="0dip"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="Remove" />
    </LinearLayout>

</LinearLayout>

sortie comme ci-dessous, je veux même que le contenu pas de scrollview

enter image description here

16
Nick

Utilisez ce code

public class MyListView  extends ListView {

    public MyListView  (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyListView  (Context context) {
        super(context);
    }

    public MyListView  (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}
38
Raj008

Vous ne devez pas placer un ListView dans un ScrollView car ListView lui-même est un groupe de vues qui affiche une liste d'éléments défilables. Si vous l'utilisez dans scrollview, il ne recevra pas d'événements de défilement car ils sont tous gérés par le ScrollView parent. L'utilisation d'un ListView pour qu'il ne défile pas est extrêmement coûteuse et va à l'encontre de l'objectif de ListView. Vous ne devez PAS faire cela. Utilisez simplement un LinearLayout à la place.

Cependant, si vous voulez vraiment le faire, vous pouvez y jeter un œil: Comment puis-je mettre un ListView dans un ScrollView sans qu'il ne s'effondre?

12
Permita

Dans votre disposition parent, définissez la hauteur sur wrap_content. Cela devrait fonctionner.

8
VikramV

D'autres suggestions ne fonctionneront pas, car il n'y a aucun moyen de déterminer la hauteur du contenu de ListView tant qu'il n'est pas affiché à l'écran (sauf si vous avez bien sûr une hauteur fixe, utilisez-la également comme hauteur de votre ListView).

Ce que vous pouvez faire est de définir la hauteur du ListView APRÈS avoir dessiné les éléments à l'intérieur. Vous pouvez le faire dans onWindowFocusChanged dans votre activité. Par exemple:

public void onWindowFocusChanged(boolean hasFocus) {
    // get content height
    int contentHeight = listView.getChildAt(0).getHeight();

    // set listview height
    LayoutParams lp = listView.getLayoutParams();
    lp.height = contentHeight;
    listView.setLayoutParams(lp);
}
4
josephus

Utiliser sa propre liste personnalisée
Créez une classe CustomListView.Java et étendez ListView comme ceci ..

public class CustomListView extends ListView {

private Android.view.ViewGroup.LayoutParams params;
private int prevCount = 0;

public CustomListView(Context context, AttributeSet attrs)
{
    super(context, attrs);
}

@Override
protected void onDraw(Canvas canvas)
{
    if (getCount() != prevCount) 
    {
        int height = getChildAt(0).getHeight() + 1 ;
        prevCount = getCount();
        params = getLayoutParams();
        params.height = getCount() * height;
        setLayoutParams(params);
    }

    super.onDraw(canvas);
}

}

Ensuite, utilisez-le en xml

 <yourPackageName.CustomListView
        Android:id="@+id/lstsemtrack"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:divider="#f2e4e4"
        Android:dividerHeight="1dip">
 </yourPackageName.ListView>
2
user4696837

Comme indiqué par Permita, vous ne devriez pas avoir un ListView dans un Scrollview. Vous devez utiliser par exemple un LinearLayout à la place.

Dans certains cas, vous avez déjà créé des adaptateurs personnalisés que vous souhaitez réutiliser. Dans ce cas, ces extraits de code peuvent être utiles.

Vue ancienne:

...
<ListView Android:id="@+id/myListView" ... />
...

Nouvelle vue:

...
<LinearLayout
    Android:orientation="vertical"
    Android:id="@+id/myLinearLayout"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content" />
...

Ancien code: (dans la boîte de dialogue/fragment/activité)

YourAdapter listAdapter;
...
ListView listView = (ListView)rootView.findViewById(R.id.myListView);
...
if (listView != null) {
    if (listAdapter == null) {
        listAdapter = new YourAdapter(...);
        listView.setAdapter(listAdapter);
    } else {
        listAdapter.notifyDataSetChanged();
    }
}

Nouveau code: (faire nous-mêmes des choses "listview", pour réutiliser les vues si possible)

YourAdapter listAdapter;
...
LinearLayout linearLayout = (LinearLayout) rootView.findViewById(R.id.myLinearLayout);
...
if (linearLayout != null) {
    if (listAdapter == null) listAdapter = new YourAdapter(...);
    for (int pos = 0; pos < listAdapter.getCount(); pos++) {
        View existingView = linearLayout.getChildAt(pos);
        if (existingView != null) listAdapter.getView(pos, existingView, linearLayout);
        else linearLayout.addView(listAdapter.getView(pos, null, linearLayout));
    }
    while (linearLayout.getChildCount() > listAdapter.getCount()) linearLayout.removeViewAt(listAdapter.getCount());
}

MISE À JOUR: Ou ajoutez simplement ceci à votre adaptateur et appelez-le au lieu de setAdapter dans la vue de liste et et notifiezDataUpdated sur l'adaptateur:

public void updateOnLinearView(ViewGroup parentView) {
    // Note reusing child views if there are any
    for (int pos = 0; pos < getCount(); pos++) {
        View existingView = parentView.getChildAt(pos);
        if (existingView != null) getView(pos, existingView, parentView);
        else parentView.addView(getView(pos, null, parentView));
    }
    while (parentView.getChildCount() > getCount())
        parentView.removeViewAt(getCount());
}
2
Erik Melkersson

quelques choses à noter ici ..

  1. N'utilisez pas ListView dans ScrollView
  2. Vous devrez calculer dynamiquement les éléments listView pour en obtenir la hauteur.

Voici une fonction pour le faire ..

public void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        return;
    }

    int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        if (listItem instanceof ViewGroup)
            listItem.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);

}

Vous devrez appeler le même

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
setListViewHeightBasedOnChildren(listview)
    }
0
Smaran

essayez d'habiller votre vue de liste avec un LinearLayout et définissez la hauteur du LinearLayout sur wrap_content.

0
Gil Moshayof