Непрокручиваемый ListView внутри ScrollView

Я пытаюсь сделать макет примерно так:

Проблема в том, что я не хочу, чтобы ListViews можно было прокручивать. Я хочу, чтобы они были такими же высокими, как они должны, и чтобы весь экран можно было прокручивать. Если я установлю высоту ListView на wrap_content, это не сработает. Единственный способ заставить его работать - это установить конкретную высоту, но я не знаю, сколько предметов будет в ListView.

Я знаю, что не должен помещать ListView внутрь ScrollView - но я не хочу, чтобы ListView можно было прокручивать, просто чтобы показать все элементы.

Может быть, есть лучший способ заставить это работать?

Ответ 1

Вы создаете пользовательский 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

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

Ответ 2

Нет необходимости использовать listview вообще.

Если вы действительно думаете об этом, в вашем случае listview можно заменить на LinearLayout. Adapter будет таким же, но вместо того, чтобы присоединять адаптер к вашему listview, просто вызовите функцию getView адаптера в цикле for для ваших данных и добавьте полученные виды в вашу вертикаль linearlayout.

Однако этот подход рекомендуется только в том случае, если в вашем списке есть небольшое количество элементов, и отображаемое представление этих элементов не требует большого объема памяти.

Ответ 3

Лучший способ сделать это (в 2017 году) - использовать RecyclerView с NestedScrollView.

Никаких взломов не требуется, и он работает из коробки, как вы хотите.

Ответ 4

Ну, есть крутой парень Android по имени Марк Мерфи, известный как CommonsWare, и он создал очень полезный компонент под названием CWAC Merge Adapter, который позволяет вам делать то, что вам нужно. Вам нужно будет добавлять представления динамически, а не из XML; но, учитывая ваш простой пользовательский интерфейс, это не должно быть проблемой. Я использую его для таких случаев, когда я понятия не имею, какие данные я должен прокручивать.

Если вы не хотите его использовать (возможно, по причинам лицензирования), вы можете иметь один список (вместо двух последовательных списков) и переопределять getItemViewsCount, getItemViewType и getView в чтобы дать выше макет. Если вы ищете android listview different rows в Google, вы найдете полезную информацию. Например эта ссылка или этот.

Однако я бы пошел на слияние-адаптер.

Ответ 5

У меня есть простое решение, если возможно рассчитать высоту вашего объекта/ширину... Вам просто нужно создать родительский Linringayout из ListView, а затем зафиксировать родительскую высоту из Java.

введите описание изображения здесь

Предположим, вам нужно создать этот вид... Теперь размер макета родителя определяется из java...

final LinearLayout parent=(LinearLayout)findViewById(R.id.parent);
final ListView  listview=(ListView)findViewById(R.id.listview);
parent.setLayoutParams(new LinearLayout.LayoutParams(parent.getLayoutParams().width, dpToPx( number_of_item_in_list * per_item_size_in_dp )));
//number_of_item_in_list is list side ~ listArray.size();
//per_item_size_in_dp = calculate item size in dp. Ex: 80dp

public static int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

что все:)

Ответ 6

Выберите ListView, который вы хотите прокручивать, и после этого добавьте метод setOnTouchListener для автоматической установки прокрутки внутри ListView

final ListView listview = (ListView) findViewById(R.id.list);


    listview.setOnTouchListener(new ListView.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.
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    break;

                case MotionEvent.ACTION_UP:
                    // Allow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
            }

            // Handle ListView touch events.
            v.onTouchEvent(event);
            return true;
        }
    });
    listview.setClickable(true);

Я надеюсь, что это сработает для вас

Ответ 7

Мое мнение: вы не можете использовать listview внутри scrollview. Вместо этого вы можете создать отдельные XML файлы для них и добавить их в представление списка Использование addHeaderview и addFooterview

Например,

View view=getLayoutInflater().inflate(R.layout.yourlayout,null);
lv=(ListView)listview.findViewById(R.id.listView);
lv.addHeaderView(view);

Он отлично работает на 100%.