it-swarm.com.ru

Представление списка Android в представлении прокрутки

У меня есть макет Android, в котором есть scrollView с несколькими элементами. В нижней части scrollView у меня есть listView, который затем заполняется адаптером.

Проблема, с которой я сталкиваюсь, заключается в том, что Android исключает listView из scrollView, так как scrollView уже имеет функцию прокрутки. Я хочу, чтобы listView был таким же, как и содержимое, и чтобы представление главной прокрутки могло быть прокручиваемым.

Как я могу добиться этого поведения?

Вот мой основной макет:

<ScrollView
    Android:id="@+id/scrollView1"
    Android:layout_width="match_parent"
    Android:layout_height="0dp"
    Android:layout_weight="2"
    Android:fillViewport="true"
    Android:gravity="top" >

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

</ScrollView>

Затем я программно добавляю свои компоненты к линейному слою с идентификатором: foodItemActvity_linearLayout_fragments. Ниже приведено одно из представлений, загруженных в этот линейный макет. Это тот, кто доставляет мне неприятности со свитками.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:orientation="vertical" >

    <TextView
       Android:id="@+id/fragment_dds_review_textView_label"
       Android:layout_width="wrap_content"
       Android:layout_height="wrap_content"
       Android:text="Reviews:"
       Android:textAppearance="?android:attr/textAppearanceMedium" />

   <ListView
       Android:id="@+id/fragment_dds_review_listView"
       Android:layout_width="match_parent"
       Android:layout_height="wrap_content">
   </ListView>
</LinearLayout>

Мой адаптер затем заполняет этот список.

Вот изображение из средства просмотра иерархии Android, когда я щелкаю по основному scrollView:

 Android List View inside a scroll view

Как видите, это исключение из списка просмотра отзывов.

Я должен быть в состоянии прокрутить страницу вниз и увидеть 8 отзывов, но вместо этого он показывает только эти 3, и я могу прокрутить крошечную часть, где находятся отзывы. Я хочу глобальную прокрутку страницы

241
Zapnologica

Самое короткое и простое решение для ListView внутри проблемы ScrollView.

Вам не нужно делать ничего особенного в файле layout.xml и ничего не обрабатывать в родительском ScrollView. Вы должны обрабатывать только дочерний ListView. Вы также можете использовать этот код, чтобы использовать любой тип дочернего представления внутри ScrollView и выполнять сенсорные операции.

Просто добавьте эти строки кода в ваш класс Java:

ListView lv = (ListView) findViewById(R.id.layout_lv);
lv.setOnTouchListener(new OnTouchListener() {
    // Setting on Touch Listener for handling the touch inside ScrollView
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    // Disallow the touch request for parent scroll on touch of child view
    v.getParent().requestDisallowInterceptTouchEvent(true);
    return false;
    }
});

Если вы поместите ListView внутри ScrollView, то ListView не растянется до полной высоты. Ниже приведен метод для решения этой проблемы.

/**** Method for Setting the Height of the ListView dynamically.
 **** Hack to fix the issue of not showing all the items of the ListView
 **** when placed inside a ScrollView  ****/
public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null)
        return;

    int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.UNSPECIFIED);
    int totalHeight = 0;
    View view = null;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        view = listAdapter.getView(i, view, listView);
        if (i == 0)
            view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, LayoutParams.WRAP_CONTENT));

        view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
        totalHeight += view.getMeasuredHeight();
    }
    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
}

Чтобы использовать этот метод, просто передайте ListView внутри этого метода:

ListView list = (ListView) view.findViewById(R.id.ls);
setListViewHeightBasedOnChildren(list);

Для использования с ExpandableListView - кредит Бенни

ExpandableListView: view = listAdapter.getView(0, view, listView);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.MATCH_PARENT, View.MeasureSpec.EXACTLY);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec, heightMeasureSpec);

Для ListView с переменной высотой элементов используйте ссылку ниже:

ListView внутри ScrollView не прокручивается на Android

Для библиотеки, чтобы непосредственно реализовать в вашем коде - кредит Паоло Ротоло

https://github.com/PaoloRotolo/ExpandableHeightListView

533
arshu

Ответ прост, и я удивлен, что здесь еще нет ответа.

Используйте Header View или/и Footer View в самом списке . Не смешивайте ScrollView с ListView или что-либо, что может прокручиваться. Он предназначен для использования с верхними и нижними колонтитулами :)

По сути, возьмите все содержимое над ListView, поместите его в другой файл .xml в качестве макета, а затем в коде надуйте его и добавьте в список в качестве представления заголовка.

то есть.

View header = getLayoutInflater().inflate(R.layout.header, null);
View footer = getLayoutInflater().inflate(R.layout.footer, null);
listView.addHeaderView(header);
listView.addFooterView(footer);
213
ericosg

Я знаю, что это было так долго, но я тоже получил эту проблему, попробовал это решение, и оно работает. Поэтому я думаю, что это может помочь и другим.

Я добавляю Android: fillViewport = "true" в XML-макет для scrollView . Так что в целом мой ScrollView будет выглядеть следующим образом.

<ScrollView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:id="@+id/scrollView6" 
    Android:fillViewport="true">

И это работает как волшебство для меня. ListView, расположенный внутри моего ScrollView, снова расширяется до своего размера.

Вот полный пример кода для ScrollView и ListView.

<ScrollView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:id="@+id/scrollView6" Android:fillViewport="true">
    <LinearLayout
        Android:orientation="vertical"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">
        ....
        <ListView
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:id="@+id/lv_transList" Android:layout_gravity="top"
            Android:layout_marginTop="5dp"/>
        ....
    </LinearLayout>
</ScrollView>
33
acyn

Вы создаете пользовательский ListView, который не прокручивается

  public class NonScrollListView extends ListView {

            public NonScrollListView(Context context) {
                super(context);
            }
            public NonScrollListView(Context context, AttributeSet attrs) {
                super(context, attrs);
            }
            public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
            }
            @Override
            public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                    int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                            Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
                    super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
                    ViewGroup.LayoutParams params = getLayoutParams();
                    params.height = getMeasuredHeight();    
            }
        }

В вашем файле ресурсов макета

     <?xml version="1.0" encoding="utf-8"?>
        <ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:fadingEdgeLength="0dp"
            Android:fillViewport="true"
            Android:overScrollMode="never"
            Android:scrollbars="none" >

            <RelativeLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content" >

                <!-- com.Example Changed with your Package name -->

                <com.Example.NonScrollListView
                    Android:id="@+id/lv_nonscroll_list"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content" >
                </com.Example.NonScrollListView>

                <RelativeLayout
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:layout_below="@+id/lv_nonscroll_list" >

                    <!-- Your another layout in scroll view -->

                </RelativeLayout>
            </RelativeLayout>

        </ScrollView>

В файле Java Создайте объект вашего customListview вместо ListView, например: NonScrollListView non_scroll_list = (NonScrollListView) findViewById (R.id.lv_nonscroll_list);

15
Dedaniya HirenKumar
    public static void setListViewHeightBasedOnChildren(ListView listView) {
    // 获取ListView对应的Adapter
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        return;
    }

    int totalHeight = 0;
    for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0); // 计算子项View 的宽高
        totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight
            + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    // listView.getDividerHeight()获取子项间分隔符占用的高度
    // params.height最后得到整个ListView完整显示需要的高度
    listView.setLayoutParams(params);
}

вы можете использовать этот код для просмотра списка в scrollview

8
Su Zhenpeng

Вы можете решить эту проблему, добавив Android:fillViewport="true" к вашему ScrollView.

<ScrollView
      Android:layout_width="match_parent"
      Android:layout_height="match_parent"
      Android:background="@color/white"
      Android:fillViewport="true"
      Android:scrollbars="vertical">

<ListView
      Android:id="@+id/statusList"
      Android:layout_width="fill_parent"
      Android:layout_height="wrap_content"
      Android:animationCache="false"
      Android:divider="@null"
      Android:scrollingCache="false"
      Android:smoothScrollbar="true" />

</ScrollView>


до использования этого свойства был виден только один дочерний элемент моего списка. после этого все строки или дочерние элементы списка становятся видимыми.

8
MV53

Этот код решит вашу проблему, если вы внедрили в код только ListView.

Если вы используете RelativeLayout в качестве дочернего элемента ListView, этот код возвращает здесь исключение NullPointerException listItem.measure (0, 0); , из-за RelativeLayout. И решение помещает ваш RelativeLayout в LinearLayout, и он будет работать нормально.

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();
}
6
krunal shah

Я оставлю это здесь на случай, если кто-то столкнется с той же проблемой. Мне пришлось поместить ListView внутри ScrollView. ListView с заголовком не был вариантом по ряду причин. Также не было возможности использовать LinearLayout вместо ListView. Поэтому я следовал принятому решению, но оно не работало, потому что элементы в списке имели сложную компоновку с несколькими строками, а каждый элемент списка имел переменную высоту. Высота была измерена не правильно. Решением было измерить каждый элемент внутри метода getView () адаптера ListView.

@Override
public View getView(int position, View view, ViewGroup parent) {
    ViewHolder holder;
    if (view == null) {
        . . .
        view.setTag(holder);
    } else holder = (ViewHolder)view.getTag();
    . . .

    // measure ListView item (to solve 'ListView inside ScrollView' problem)
    view.measure(View.MeasureSpec.makeMeasureSpec(
                    View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    return view;
}
5
Alexander Zhak

Вы можете легко поместить ListView в ScrollView! Просто нужно изменить высоту ListView программно , например так:

    ViewGroup.LayoutParams listViewParams = (ViewGroup.LayoutParams)listView.getLayoutParams();
    listViewParams.height = 400;
    listView.requestLayout();

Это работает отлично!

4
Taras Okunev

Сделано после большого количества исследований и разработок:

фрагмент_он.xml должен выглядеть так:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:id="@+id/scrollViewParent"
    Android:orientation="vertical" >

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

        <RelativeLayout
            Android:layout_width="match_parent"
            Android:layout_height="400dip" >

            <ListView
                Android:id="@+id/listView"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent" />

            <View
                Android:id="@+id/customView"
                Android:layout_width="fill_parent"
                Android:layout_height="fill_parent"
                Android:background="@Android:color/transparent" />
        </RelativeLayout>

        <!-- Your other elements are here -->

    </LinearLayout>

</ScrollView>

Ваш Java-класс FragmentOne.Java выглядит так:

private ListView listView;
private View customView

onCreateView

listView = (ListView) rootView.findViewById(R.id.listView);
scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent);
customView = (View)rootView.findViewById(R.id.customView);

customView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        // Disallow ScrollView to intercept touch events.
                        scrollViewParent.requestDisallowInterceptTouchEvent(true);
                        // Disable touch on transparent view
                        return false;

                    case MotionEvent.ACTION_UP:
                        // Allow ScrollView to intercept touch events.
                        scrollViewParent.requestDisallowInterceptTouchEvent(false);
                        return true;

                    case MotionEvent.ACTION_MOVE:
                        scrollViewParent.requestDisallowInterceptTouchEvent(true);
                        return false;

                    default:
                        return true;
                }
            }
        });
4
Hiren Patel

Ничего не делать в родительском ScrollView. Сделайте это только для дочернего ListView. Все будет отлично работать. 

mListView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mScrollView.requestDisallowInterceptTouchEvent(true);
               int action = event.getActionMasked();
                switch (action) {
                    case MotionEvent.ACTION_UP:
                        mScrollView.requestDisallowInterceptTouchEvent(false);
                        break;
                }
                return false;
            }
        });
4
Sibin

У меня была похожая проблема с проблемой, поставленной Исходным плакатом - как сделать прокрутку просмотра списка внутри просмотра прокрутки - и этот ответ решил мою проблему . Отключить прокрутку ListView, содержащегося в ScrollView

Я не вызывал новые фрагменты в существующие макеты или что-то в этом роде, как это делал OP, поэтому мой код выглядел бы примерно так:

<ScrollView
    Android:id="@+id/scrollView1"
    Android:layout_width="match_parent"
    Android:layout_height="0dp"
    Android:layout_weight="2"
    Android:fillViewport="true"
    Android:gravity="top" >

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


    <TextView
       Android:id="@+id/fragment_dds_review_textView_label"
       Android:layout_width="wrap_content"
       Android:layout_height="wrap_content"
       Android:text="Reviews:"
       Android:textAppearance="?android:attr/textAppearanceMedium" />

   <ListView
       Android:id="@+id/my_listView"
       Android:layout_width="match_parent"
       Android:layout_height="wrap_content">
   </ListView>

</LinearLayout>

</ScrollView>

По сути, я проверяю длину списка перед тем, как я его вызываю, и когда я его называю, я делаю его таким же длинным. В вашем классе Java используйте эту функцию:

public static void justifyListViewHeightBasedOnChildren (ListView listView) {

    ListAdapter adapter = listView.getAdapter();

    if (adapter == null) {
        return;
    }
    ViewGroup vg = listView;
    int totalHeight = 0;
    for (int i = 0; i < adapter.getCount(); i++) {
        View listItem = adapter.getView(i, null, vg);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

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

И вызвать функцию следующим образом:

justifyListViewHeightBasedOnChildren(listView);

Результатом является представление списка без полосы прокрутки, отображаемой по всей длине просмотра списка, которое прокручивается с помощью полосы прокрутки просмотра прокрутки.

3
CHarris

Вы можете поместить все в линейное расположение. То есть создайте линейный макет, и у него будет 2 дочерних элемента, scrollview и другой линейный макет. Дайте им весовые параметры макета и вот вам:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical" >

<ScrollView
    Android:layout_width="fill_parent"
    Android:layout_height="0dip" Android:layout_weight="0.8">

    <LinearLayout
        Android:id="@+id/seTaskActivityRoot"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:background="@color/white"
        Android:orientation="vertical" >

        <TextView
            Android:id="@+id/textView1"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="@string/taskName" />


        <Spinner
            Android:id="@+id/seTaskPrioritiesSP"
            Android:layout_width="fill_parent"
            Android:layout_height="wrap_content"
            Android:layout_weight="1" />

        <TextView
            Android:id="@+id/textView4"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="@string/taskTargetInNumeric" />

        <Spinner
            Android:id="@+id/seTaskUnitsSP"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_weight="1" />

        <TextView
            Android:id="@+id/textView6"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:text="@string/newTaskCurrentStatus" />

        <EditText
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:ems="10"
            Android:hint="@string/addTaskCurrentStatus"
            Android:inputType="numberDecimal" />


    </LinearLayout>
</ScrollView>

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="0dip"
    Android:orientation="vertical" Android:layout_weight="0.2">

    <TextView
        Android:id="@+id/textView8"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="TextView" />

    <ListView
        Android:id="@+id/logList"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

3
Jeyhun Karimov

Как уже упоминали другие, не используйте ListView внутри ScrollView.

Чтобы обойти это, вы можете использовать LinearLayout, но чтобы все было аккуратно - заполните LinearLayout адаптером, так же, как вы делаете с ListView

Вы можете использовать этот класс в качестве замены LinearLayout, которая поддерживает адаптеры

import Android.content.Context;
import Android.database.DataSetObserver;
import Android.util.AttributeSet;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.BaseAdapter;
import Android.widget.LinearLayout;

public class AdaptableLinearLayout extends LinearLayout {

private BaseAdapter mAdapter;

private int mItemCount = 0;

private boolean mDisableChildrenWhenDisabled = false;

private int mWidthMeasureSpec;
private int mHeightMeasureSpec;


public AdaptableLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
}

public BaseAdapter getAdapter() {
    return mAdapter;
}

public void setAdapter(BaseAdapter adapter) {
    mAdapter = adapter;
    adapter.registerDataSetObserver(new DataSetObserver() {
        @Override
        public void onChanged() {
            updateLayout();
            super.onChanged();
        }

        @Override
        public void onInvalidated() {
            updateLayout();
            super.onInvalidated();
        }
    });
    updateLayout();
}

private void updateLayout() {
    mItemCount = mAdapter.getCount();
    requestLayout();
    invalidate();
}

/**
 * set size for the current View
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    mWidthMeasureSpec = widthMeasureSpec;
    mHeightMeasureSpec = heightMeasureSpec;

    removeAllViewsInLayout();
    for (int i = 0; i < mItemCount; i++) {
        makeAndAddView(i);
    }
}

private View makeAndAddView(int position) {
    View child;

    // Nothing found in the recycler -- ask the adapter for a view
    child = mAdapter.getView(position, null, this);

    // Position the view
    setUpChild(child, position);

    return child;

}

private void setUpChild(View child, int position) {

    ViewGroup.LayoutParams lp = child.getLayoutParams();
    if (lp == null) {
        lp = generateDefaultLayoutParams();
    }
    addViewInLayout(child, position, lp);

    // Get measure specs
    int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, getPaddingTop() + getPaddingBottom(), lp.height);
    int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), lp.width);

    // Measure child
    child.measure(childWidthSpec, childHeightSpec);

    int childLeft;
    int childRight;

    // Position vertically based on gravity setting
    int childTop = getPaddingTop() + ((getMeasuredHeight() - getPaddingBottom() - getPaddingTop() - child.getMeasuredHeight()) / 2);
    int childBottom = childTop + child.getMeasuredHeight();

    int width = child.getMeasuredWidth();
    childLeft = 0;
    childRight = childLeft + width;

    child.layout(childLeft, childTop, childRight, childBottom);

    if (mDisableChildrenWhenDisabled) {
        child.setEnabled(isEnabled());
    }
}
}
3
AAverin

Вы никогда не должны использовать ScrollView с ListView, потому что ListView заботится о своей собственной вертикальной прокрутке. Что наиболее важно, выполнение этого снимает все важные оптимизации в ListView для работы с большими списками, поскольку фактически заставляет ListView отображать весь список элементов, чтобы заполнить бесконечный контейнер, предоставляемый ScrollView.

http://developer.Android.com/reference/Android/widget/ScrollView.html

3
Muhammad Asim

Обновление

<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="2"
Android:fillViewport="true"
Android:gravity="top" >

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

в 

<ScrollView
Android:id="@+id/scrollView1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="2"
Android:fillViewport="true"
Android:gravity="top" >

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

Дело в том, что вы пытаетесь установить высоту 0dp (исправлено)

2
Rajnish Mishra

нашел решение для scrollview -> viewpager -> FragmentPagerAdapter -> фрагмент -> динамический список, но я не автор есть некоторые ошибки, но, по крайней мере, это работает

public class CustomPager extends ViewPager {

    private View mCurrentView;

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

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

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mCurrentView == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }
        int height = 0;
        mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        int h = mCurrentView.getMeasuredHeight();
        if (h > height) height = h;
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void measureCurrentView(View currentView) {
        mCurrentView = currentView;
        this.post(new Runnable() {
            @Override
            public void run() {
                requestLayout();
            }
        });
    }

    public int measureFragment(View view) {
        if (view == null)
            return 0;

        view.measure(0, 0);
        return view.getMeasuredHeight();
    }
}


public class MyPagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragments;
    private int mCurrentPosition = -1;


    public MyPagerAdapter(FragmentManager fm) {
        super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
        this.fragments = new ArrayList<Fragment>();
        fragments.add(new FirstFragment());
        fragments.add(new SecondFragment());
        fragments.add(new ThirdFragment());
        fragments.add(new FourthFragment());
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        super.setPrimaryItem(container, position, object);
        if (position != mCurrentPosition) {
            Fragment fragment = (Fragment) object;
            CustomPager pager = (CustomPager) container;
            if (fragment != null && fragment.getView() != null) {
                mCurrentPosition = position;
                pager.measureCurrentView(fragment.getView());
            }
        }
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}

макет фрагментов может быть любым

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" Android:layout_width="match_parent"
Android:orientation="vertical"
    Android:layout_height="match_parent" tools:context="nevet.me.wcviewpagersample.FirstFragment">


    <ListView
        Android:id="@+id/lv1"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="#991199"/>
</LinearLayout>

тогда где-то просто

lv = (ListView) view.findViewById(R.id.lv1);
        lv.setAdapter(arrayAdapter);
        setListViewHeightBasedOnChildren(lv);
    }

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

        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
                View.MeasureSpec.UNSPECIFIED);
        int totalHeight = 0;
        View view = null;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            view = listAdapter.getView(i, view, listView);
            if (i == 0)
                view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
                        LinearLayout.LayoutParams.WRAP_CONTENT));

            view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
            totalHeight += view.getMeasuredHeight();
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();
    }
2
bedman

Мое требование - включить ListView элементов одинакового размера в ScrollView. Я попробовал несколько других решений, перечисленных здесь, но ни одно из них не соответствовало правильному размеру ListView (слишком мало места или слишком много) Вот что сработало для меня:

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

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    listView.measure(0, 0);
    params.height = listView.getMeasuredHeight() * listAdapter.getCount() + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
}

Надеюсь, это кому-нибудь поможет.

2
Malcolm Bryant

В xml:

<com.example.util.NestedListView
                    Android:layout_marginTop="10dp"
                    Android:id="@+id/listview"
                    Android:layout_width="fill_parent"
                    Android:layout_height="fill_parent"
                    Android:divider="@null"

                    Android:layout_below="@+id/rl_delivery_type" >
                </com.example.util.NestedListView>

В Java:

public class NestedListView extends ListView implements View.OnTouchListener, AbsListView.OnScrollListener {

    private int listViewTouchAction;
    private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99;

    public NestedListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        listViewTouchAction = -1;
        setOnScrollListener(this);
        setOnTouchListener(this);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
            if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
                scrollBy(0, -1);
            }
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int newHeight = 0;
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (heightMode != MeasureSpec.EXACTLY) {
            ListAdapter listAdapter = getAdapter();
            if (listAdapter != null && !listAdapter.isEmpty()) {
                int listPosition = 0;
                for (listPosition = 0; listPosition < listAdapter.getCount()
                        && listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) {
                    View listItem = listAdapter.getView(listPosition, null, this);
                    //now it will not throw a NPE if listItem is a ViewGroup instance
                    if (listItem instanceof ViewGroup) {
                        listItem.setLayoutParams(new LayoutParams(
                                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
                    }
                    listItem.measure(widthMeasureSpec, heightMeasureSpec);
                    newHeight += listItem.getMeasuredHeight();
                }
                newHeight += getDividerHeight() * listPosition;
            }
            if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) {
                if (newHeight > heightSize) {
                    newHeight = heightSize;
                }
            }
        } else {
            newHeight = getMeasuredHeight();
        }
        setMeasuredDimension(getMeasuredWidth(), newHeight);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) {
            if (listViewTouchAction == MotionEvent.ACTION_MOVE) {
                scrollBy(0, 1);
            }
        }
        return false;
    }
}
1
Makvin

Хорошо, вот мой ответ. Метод, который фиксирует высоту ListView, достаточно закрыт, но не идеален. В случае, если большинство предметов имеют одинаковую высоту, это работает хорошо. Но если это не так, то есть большая проблема. Я пытался много раз, и когда я поместил в список значения listItem.getMeasureHeight и listItem.getMeasuerWidth, я увидел, что значения ширины сильно меняются, чего здесь не ожидается, поскольку все элементы в одном и том же ListView должны имеют одинаковую ширину. И там ошибка: 

Некоторые использовали меру (0, 0), которая фактически делала представление свободным как в направлении, так и в ширину. Некоторые пытались получить ширину listView, но потом возвращали 0, бессмысленно. 

Когда я продолжаю читать о том, как Android отображает представление, я понимаю, что все эти попытки не могут найти ответ, который я искал, если эти функции не выполняются после отображения представления. 

На этот раз я использую getViewTreeObserver в ListView, который я хочу зафиксировать высоту, а затем addOnGlobalLayoutListener. Внутри этого метода я объявляю новый OnGlobalLayoutListener, в котором на этот раз getWidth возвращает фактическую ширину ListView. 

private void getLayoutWidth(final ListView lv, final int pad){
        //final ArrayList<Integer> width = new ArrayList<Integer>();

        ViewTreeObserver vto = lv.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                lv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                //width.add(layout.getMeasuredWidth());
                int width = lv.getMeasuredWidth();
                ListUtils.setDynamicHeight(lv, width, pad);
            }
        });
    }

public static class ListUtils {
        //private static final int UNBOUNDED = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        public static void setDynamicHeight(ListView mListView, int width, int pad) {
            ListAdapter mListAdapter = mListView.getAdapter();
            mListView.getParent();
            if (mListAdapter == null) {
                // when adapter is null
                return;
            }
            int height = 0;


            int desiredWidth = View.MeasureSpec.makeMeasureSpec(width - 2*pad, View.MeasureSpec.EXACTLY);
            for (int i = 0; i < mListAdapter.getCount(); i++) {
                View listItem = mListAdapter.getView(i, null, mListView);

                listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
                //listItem.measure(UNBOUNDED, UNBOUNDED);
                height += listItem.getMeasuredHeight() + 2*pad;
                Log.v("ViewHeight :", mListAdapter.getClass().toString() + " " + listItem.getMeasuredHeight() + "--" + listItem.getMeasuredWidth());
            }
            ViewGroup.LayoutParams params = mListView.getLayoutParams();
            params.height = height + (mListView.getDividerHeight() * (mListAdapter.getCount() - 1));
            mListView.setLayoutParams(params);
            mListView.requestLayout();
        }
    }

Панель значений - это заполнение, которое я установил в макете ListView. 

1
Nguyen Quang Anh

с помощью этого ListView работал для меня

   package net.londatiga.Android.widget;

      import Android.util.AttributeSet;
      import Android.view.ViewGroup;
      import Android.widget.ListView;
      import Android.content.Context;

   public class ExpandableHeightListView extends ListView
      {

    boolean expanded = false;

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

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

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

public boolean isExpanded()
{
    return expanded;
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    // HACK! TAKE THAT Android!
    if (isExpanded())
    {
        // Calculate entire height by providing a very large height hint.
        // But do not use the highest 2 bits of this integer; those are
        // reserved for the MeasureSpec mode.
        int expandSpec = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);

        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
    else
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

public void setExpanded(boolean expanded)
{
    this.expanded = expanded;
}
}

и в XML

            <com.pakagename.ExpandableHeightListView
                Android:id="@+id/expandableHeightListView"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content" >
            </com.Example.ExpandableHeightListView>

и в MainActivity 

  ExpandableHeightListView listView = new ExpandableHeightListView(this);
    listview=(ExpandableHeightListView)findViewById(R.id.expandableHeightListView);
   listView.setAdapter(adapter); //set your adaper
   listView.setExpanded(true);

Обратитесь к этой статье для получения дополнительной информации, а также чтобы узнать, как сохранить gridview в представлении прокрутки

1
Manohar Reddy

Если по какой-то причине вы не хотите использовать addHeaderView и addFooterView, например, если у вас есть несколько списков, хорошей идеей будет повторное использование ListAdapter для заполнения простого LinearLayout, чтобы не было функции прокрутки.

Если у вас уже есть целый фрагмент, полученный из ListFragment, и вы хотите преобразовать его в похожий фрагмент с простой LinearLayout без прокрутки (например, чтобы поместить его в ScrollView), вы можете реализовать фрагмент адаптера следующим образом:

// converts listFragment to linearLayout (no scrolling)
// please call init() after fragment is inflated to set listFragment to convert
public class ListAsArrayFragment extends Fragment {
    public ListAsArrayFragment() {}

    private ListFragment mListFragment;
    private LinearLayout mRootView;


    // please call me!
    public void init(Activity activity, ListFragment listFragment){
        mListFragment = listFragment;
        mListFragment.onAttach(activity);
        mListFragment.getListAdapter().registerDataSetObserver(new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                refreshView();
            }
        });
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // create an empty vertical LinearLayout as the root view of this fragment
        mRootView = new LinearLayout(getActivity());
        mRootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        mRootView.setOrientation(LinearLayout.VERTICAL);
        return mRootView;
    }

    // reusing views for performance
    // todo: support for more than one view type
    ArrayList<View> mViewsToReuse = new ArrayList<>();
    ArrayList<View> mCurrentViews = new ArrayList<>();

    // re-add views to linearLayout
    void refreshView(){

        // remove old views from linearLayout and move them to mViewsToReuse
        mRootView.removeAllViews();
        mViewsToReuse.addAll(mCurrentViews);
        mCurrentViews.clear();

        // create new views
        for(int i=0; i<mListFragment.getListAdapter().getCount(); ++i){
            View viewToReuse = null;
            if(!mViewsToReuse.isEmpty()){
                viewToReuse = mViewsToReuse.get(mViewsToReuse.size()-1);
                mViewsToReuse.remove(mViewsToReuse.size()-1);
            }
            final View view = mListFragment.getListAdapter().getView(i, viewToReuse, mRootView);
            ViewGroup.LayoutParams oldParams = view.getLayoutParams();
            view.setLayoutParams(new LinearLayout.LayoutParams(oldParams.width, oldParams.height));
            final int finalI = i;

            // pass click events to listFragment
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mListFragment.onListItemClick(null, view, finalI, finalI);
                }
            });
            mRootView.addView(view);
            mCurrentViews.add(view);
        }
    }

Вы также можете переслать onCreate, onPause, onResume и т.д. В исходный фрагмент в зависимости от ваших потребностей или попробовать наследование вместо композиции (но переопределите некоторые методы, чтобы исходный фрагмент фактически не был присоединен к иерархии макета); но я хотел как можно больше изолировать исходный фрагмент, потому что нам нужно только извлечь его ListAdapter. Если вы называете оригинальный фрагмент setListAdapter в onAttach, этого, вероятно, достаточно.

Вот как использовать ListAsArrayFragment для включения OriginalListFragment без прокрутки. В родительской активности onCreate:

ListAsArrayFragment fragment = (ListAsArrayFragment) getFragmentManager().findFragmentById(R.id.someFragmentId);
OriginalListFragment originalFragment = new OriginalListFragment();
fragment.init(this, originalFragment);

// now access originalFragment.getListAdapter() to modify list entries
// and remember to call notifyDatasetChanged()
1
atablash

нашел решение для scrollview -> viewpager -> FragmentPagerAdapter -> фрагмент -> динамический список, но я не автор 

public class CustomPager extends ViewPager {

    private View mCurrentView;

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

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

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mCurrentView == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }
        int height = 0;
        mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        int h = mCurrentView.getMeasuredHeight();
        if (h > height) height = h;
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void measureCurrentView(View currentView) {
        mCurrentView = currentView;
        this.post(new Runnable() {
            @Override
            public void run() {
                requestLayout();
            }
        });
    }

    public int measureFragment(View view) {
        if (view == null)
            return 0;

        view.measure(0, 0);
        return view.getMeasuredHeight();
    }
}


public class MyPagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragments;
    private int mCurrentPosition = -1;


    public MyPagerAdapter(FragmentManager fm) {
        super(fm);//or u can set them separately, but dont forget to call notifyDataSetChanged()
        this.fragments = new ArrayList<Fragment>();
        fragments.add(new FirstFragment());
        fragments.add(new SecondFragment());
        fragments.add(new ThirdFragment());
        fragments.add(new FourthFragment());
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        super.setPrimaryItem(container, position, object);
        if (position != mCurrentPosition) {
            Fragment fragment = (Fragment) object;
            CustomPager pager = (CustomPager) container;
            if (fragment != null && fragment.getView() != null) {
                mCurrentPosition = position;
                pager.measureCurrentView(fragment.getView());
            }
        }
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}

макет фрагментов может быть любым

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools" Android:layout_width="match_parent"
Android:orientation="vertical"
    Android:layout_height="match_parent" tools:context="nevet.me.wcviewpagersample.FirstFragment">


    <ListView
        Android:id="@+id/lv1"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="#991199"/>
</LinearLayout>

тогда где-то просто

 lv = (ListView) view.findViewById(R.id.lv1);
        lv.setAdapter(arrayAdapter);
        setListViewHeightBasedOnChildren(lv);
    }

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

        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
                View.MeasureSpec.UNSPECIFIED);
        int totalHeight = 0;
        View view = null;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            view = listAdapter.getView(i, view, listView);
            if (i == 0)
                view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
                        LinearLayout.LayoutParams.WRAP_CONTENT));

            view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
            totalHeight += view.getMeasuredHeight();
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();
    }
1
qwerty

Это сработало для меня ( link1 , link2 ):

  • Вы создаете пользовательский ListView, который не прокручивается

    public class NonScrollListView extends ListView {
    
            public NonScrollListView(Context context) {
                super(context);
            }
            public NonScrollListView(Context context, AttributeSet attrs) {
                super(context, attrs);
            }
            public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
            }
            @Override
            public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                int heightMeasureSpec_custom = View.MeasureSpec.makeMeasureSpec(
                        Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);
                super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
                ViewGroup.LayoutParams params = getLayoutParams();
                params.height = getMeasuredHeight();
            }
        }
    
  • В вашем файле макета

    <ScrollView 
     xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:fillViewport="true">
    
        <RelativeLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content" >
    
            <!-- com.Example Changed with your Package name -->
    
            <com.thedeveloperworldisyours.view.NonScrollListView
                Android:id="@+id/lv_nonscroll_list"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content" >
            </com.thedeveloperworldisyours.view.NonScrollListView>
    
            <RelativeLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_below="@+id/lv_nonscroll_list" >
    
                <!-- Your another layout in scroll view -->
    
            </RelativeLayout>
        </RelativeLayout>
    
    </ScrollView>
    
  • Создайте объект вашего customListview вместо ListView, например:

     NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);
    
1
Manuel Schmitzberger

НИКОГДА не помещайте ListView внутри ScrollView! Вы можете найти больше информации по этой теме в Google . В вашем случае используйте LinearLayout вместо ListView и добавьте элементы программно.

1
SimonSays

Просто вызовите эту функцию после назначения адаптера для просмотра списка 

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

        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
                View.MeasureSpec.UNSPECIFIED);
        int totalHeight = 0;
        View view = null;
        for (int i = 0; i < listAdapter.getCount(); i++) {
            view = listAdapter.getView(i, view, listView);
            if (i == 0) view.setLayoutParams(new
                    ViewGroup.LayoutParams(desiredWidth,
                    ViewGroup.LayoutParams.WRAP_CONTENT));

            view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
            totalHeight += view.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();

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

        listView.setLayoutParams(params);
        listView.requestLayout();
    } 
0
farshid bohlooli
  • Невозможно использовать представление прокрутки в представлении списка, так как представление списка уже имеет свойство прокрутки.
  • Чтобы использовать просмотр списка внутри Scroll-view, вы можете выполнить следующие шаги, которые работали для меня:

    1) Создать NonScrollListView Java-файл, который отключает свойство прокрутки по умолчанию для просмотра списка. и код ниже

    package your-package-structure;
    
    import Android.content.Context;
    import Android.util.AttributeSet;
    import Android.view.ViewGroup;
    import Android.widget.ListView;
    
    public class NonScrollListView extends ListView {
    
      public NonScrollListView(Context context) {
          super(context);
      }
      public NonScrollListView(Context context, AttributeSet attrs) {
          super(context, attrs);
      }
      public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
          super(context, attrs, defStyle);
      }
      @Override
      public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
      }
    }
    

    2) Теперь создайте XML-файл, который имеет NestedScrollView, и внутри него используйте NonScrollListView для перечисления ваших элементов. Это заставит весь ваш экран прокручивать все просмотры.

     

            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_weight="1"
                Android:orientation="vertical">
                <ViewFlipper
    
                    Android:id="@+id/v_flipper"
                    Android:layout_width="match_parent"
                    Android:layout_height="130dp">
                </ViewFlipper>
                <TextView
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
    
                    Android:text="SHOP"
                    Android:textSize="15dp"
                    Android:textStyle="bold"
                    Android:gravity="center"
                    Android:padding="5dp"
                    Android:layout_marginTop="15dp"
                    Android:layout_marginBottom="5dp"
                    Android:layout_marginLeft="8dp"
                    Android:layout_marginRight="8dp"/>
                <View
                    Android:layout_width="match_parent"
                    Android:layout_height="1dp"
    
                    Android:layout_marginBottom="8dp"
                    Android:layout_marginLeft="8dp"
                    Android:layout_marginRight="8dp"
                    Android:background="#ddd"/>
            </LinearLayout>
            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:orientation="vertical"
                Android:layout_weight="1"
                >
                <com.abc.xyz.NonScrollListView
                    Android:id="@+id/listview"
    
                    Android:divider="@null"
                    Android:layout_width="match_parent"
                    Android:layout_marginBottom="10dp"
                    Android:layout_height="match_parent"
                    Android:padding="8dp">
                </com.abc.xyz.NonScrollListView>
            </LinearLayout>
    
           <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
    
                Android:gravity="bottom">
                <include layout="@layout/footer" />
            </LinearLayout>
    
        </LinearLayout>
    

     

    3) Теперь в Java-классе, т.е. home.Java, определите NonScrollListView вместо Listview.

    package comabc.xyz.landscapeapp;
    import Android.content.Intent;
    import Android.support.annotation.NonNull;
    import Android.support.annotation.Nullable;
    import Android.support.v4.app.Fragment;
    import Android.os.Bundle;
    import Android.support.v4.app.FragmentTransaction;
    import Android.util.Log;
    import Android.view.LayoutInflater;
    import Android.view.View;
    import Android.view.ViewGroup;
    import Android.widget.AdapterView;
    import Android.widget.Button;
    import Android.widget.ImageView;
    
    import Android.widget.ListView;
    import Android.widget.Toast;
    import Android.widget.Toolbar;
    import Android.widget.ViewFlipper;
    

    общественный класс расширяет дом Фрагмент { int pos = 0; ViewFlipper v_flipper;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_home, container, false);
        return view;
    }
    
    @Override
    public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
        NonScrollListView listView = (NonScrollListView) view.findViewById(R.id.listview);
        customAdapter customAdapter = new customAdapter(getActivity());
        listView.setAdapter(customAdapter);
        listView.setFocusable(false);
    
        customAdapter.notifyDataSetChanged();
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("listview click", "onItemClick: ");
               /* FragmentTransaction fr = getFragmentManager().beginTransaction().replace(R.id.fragment_container, new productdisplay());
    
                fr.putExtra("Position", position);
                fr.addToBackStack("tag");
                fr.commit();*/
                Intent intent = new Intent(getActivity(), productdisplay.class);
                intent.putExtra("Position", position);
                startActivity(intent);
            }
        });
    
    
        //image slider
        int images[] = {R.drawable.slide1, R.drawable.slide2, R.drawable.slide3};
        v_flipper = view.findViewById(R.id.v_flipper);
        for (int image : images) {
            flipperImages(image);
    
        }
    }
    
    private void flipperImages(int image) {
        ImageView imageView = new ImageView(getActivity());
        imageView.setBackgroundResource(image);
    
        v_flipper.addView(imageView);
        v_flipper.setFlipInterval(4000);
        v_flipper.setAutoStart(true);
    
        v_flipper.setInAnimation(getActivity(), Android.R.anim.slide_in_left);
        v_flipper.setOutAnimation(getActivity(), Android.R.anim.slide_out_right);
    }
    }
    

    Примечание: я использовал Fragments здесь.

0
user8235005

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

0
Shibu Tamang