Подтвердить что ты не робот

Почему элементы ListView не растут, чтобы обернуть их содержимое?

У меня довольно сложный ListView с переменной высотой элемента списка. При определенных условиях мне нужно отобразить дополнительное представление в элементе списка, который по умолчанию скрыт (View.GONE). Включив его (View.VISIBLE), элемент списка растет по высоте (или, по крайней мере, он должен).

Проблема: Несмотря на то, что я объявляю макет корня элемента wrap_content и каждый компонент в элементе fill_parent, представление, которое я скрываю/показываю, которое должно изменить высоту элемента, просто обрезается внизу, а не его родителем (макет элемента) растущий в высоту, чтобы полностью отобразить его.

Есть ли какие-либо ошибки, связанные с ListViews и макетами элементов и высотой элемента, которые я, возможно, пропустил?

Дополнительные наблюдения:

В целях тестирования я теперь уменьшил макет элемента списка, чтобы просто добавить корень LinearLayout и ImageView. Когда я устанавливаю высоту LinearLayout, например, 200dip и ImageView для fill_parent, я бы ожидал, что ImageView будет расти до тех пор, пока он не достигнет предела 200dip, установленного его родителем.

Однако вместо этого изображение будет только высотой, чем его растровый ресурс (как если бы я установил его для wrap_content), и весь элемент списка будет иметь одинаковую высоту (то есть, как если бы я установил его в wrap_content, тоже).

Если, однако, я устанавливаю высоту изображения, например. 200dip, тогда элемент списка будет расти в высоту, и будет также макет элемента.

Другими словами, layout_height макета элемента списка полностью игнорируется, и поэтому любое значение высоты изображения в ImageView отличается от значения жесткого кодированного пикселя.

4b9b3361

Ответ 1

Мне удалось это исправить, но я не понимаю, почему.

Как я уже упоминал, я установил layout_height в макете элемента списка wrap_content (поскольку fill_parent здесь не имеет смысла, учитывая, что ListView бесконечно высокий).

Однако я установил layout_height всех видов внутри этого макета на fill_parent. Проблема исчезла при установке на них wrap_content.

Это вызывает еще два вопроса:

1) Какова семантика представления с запросом fill_parent, когда родительский wraps_content? Какой запрос размера имеет приоритет?

2) Как бы мне сделать вид, чтобы заполнить элемент списка, если fill_parent, по-видимому, не работает?

Спасибо за ваши ребята.

Ответ 2

Попробуйте следующее: http://www.java2s.com/Code/Android/UI/setListViewHeightBasedOnChildren.htm

public class Utils {

    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter(); 
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = 0;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

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

Ответ 3

Как вы накачиваете свои строки?

Если вы не используете его прямо сейчас, попробуйте использовать LayoutInflater#inflate(layoutId, parent, false) (где parent - это AdapterView, предоставленный getView() или newView()):

v = getLayoutInflater().inflate(R.layout.list_item, parent, false);

Ответ 4

Проблемы с макетом могут быть вызваны тем, что ScrollView является оберткой

Я наткнулся на какую-то заметку в http://developer.android.com/reference/android/widget/ExpandableListView.html

"... Примечание. Вы не можете использовать значение wrap_content для атрибута android: layout_height ExpandableListView в XML, если размер родителя также не определен строго (например, если родительский элемент был ScrollView, вы не можете указать wrap_content, поскольку он также может быть любой длины. Однако вы можете использовать wrap_content, если родитель ExpandableListView имеет определенный размер, например 100 пикселей.

Я удалил обертку. ScrollView и линейный макет начали работать исправно. Теперь его только понять, как обернуть материал в ScrollView. Помоги мне Бог

Но в любом случае это действительно странное поведение. Я думаю, что fill_parent - это не совсем правильная формулировка. При использовании инструмента heirarchyviewer я всегда вижу значения WRAP_CONTENT и MATCH_PARENT для layout_width и leayout_height. Так что, вероятно, fill_parent на самом деле означает match_parent, что ставит меня в когнитивный диссонанс.

Ответ 5

Я использую "AbsListView.LayoutParams" для настройки ширины и высоты вручную внутри "Adapter.getView()".

Ответ 6

Если вы используете пользовательский View в качестве элемента списка, размер которого изменяется, вы можете взять ответ PeBek и сделать это, когда вы построите View

addOnLayoutChangeListener(
            new OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View _, int __, int ___, int ____, int bottom, int _____, int ______,
                                           int _______, int old_bottom) {
                    final ListView list_view = (ListView) getParent();
                    final ViewGroup.LayoutParams params = list_view.getLayoutParams();
                    params.height += bottom - old_bottom;
                    list_view.setLayoutParams(params);
                    list_view.requestLayout();
                }
            });

Когда размер View будет изменен, этот метод обратного вызова будет запущен, и он обновит высоту ListView, чтобы включить изменение высоты (дно треугольника). Другие значения, если они окажутся полезными для вас, - это View (ссылка на представление), left, top, right, bottom, old_left, old_top, old_right, old_bottom. Он работает для расширения и свертывания представления.

API 11 требуется для OnLayoutChangeListener, не знаю, есть ли способ, совместимый с обратной совместимостью.

Ответ 7

У меня была та же проблема: я хотел бы иметь список внутри своей деятельности, который заполняет весь экран, когда устройство находится в вертикальном положении, чем в горизонтальной ориентации. Я решаю проблему, используя al Linear Layout, которые имеют высоту, которая должна заполнять_parent, и устанавливая высоту элемента в списке на 0dp, в то время как layout_weight устанавливается на 1.

android:layout_weight="1"
android:layout_height="0dp"

Ответ 8

это работает для меня

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:padding="@dimen/activity_vertical_margin">

    <TextView
        android:id="@+id/tv_status"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="17sp"
        android:text="@string/text_list_devices" />

    <ListView
        android:id="@+id/lv_paired"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/activity_vertical_margin"
        android:cacheColorHint="#00000000"
        android:layout_above="@+id/signup_t"
        android:layout_below="@id/tv_status"
        />

    <Button

        android:id="@+id/signup_t"
        style="?android:textAppearanceSmall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textColor="@android:color/white"
        android:layout_alignParentBottom="true"
        android:text="Print All Records"
        android:typeface="sans"
        android:layout_marginLeft="45dp"
        android:layout_marginRight="45dp"
        android:textSize="24sp"
        android:background="@drawable/selector_for_button"
        android:textStyle="bold" />
</RelativeLayout>