如何滚动内含ListView的NestedScrollView?

问题描述 投票:0回答:2

我正在创建一个活动,在该活动中我需要显示几个元素和一个列表视图,我希望当用户滚动时,我想滚动所有活动,不仅是列表视图,为此,我实现了NestedScrollView,但是滚动不起作用,它保持不滚动状态,我需要一个属性吗?还是有更好的方法来做我需要做的事?

我附上我的XML代码:

<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

       <!-- Other items -->

        <ListView
            android:id="@+id/lvAC"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />


    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.core.widget.NestedScrollView>
android android-layout android-listview
2个回答
0
投票

在ScrollView内嵌套ListView是有问题的,因为它会导致多个垂直滚动行为,这会使用户感到困惑。而是使用一个可以提供多个ViewType的RecyclerView。

您的RecyclerView适配器应实现getItemViewType,并返回您需要显示的不同视图的数量。例如,如果您有:

<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!-- Other items -->
        <View
            android:id="@+id/view1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            />
        <View
            android:id="@+id/view2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/view1"
            app:layout_constraintStart_toStartOf="parent"
            />

        <ListView
            android:id="@+id/lvAC"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintTop_toBottomOf="@id/view2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />


    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.core.widget.NestedScrollView>

您应该具有如下布局:

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    />

并且您的适配器应该类似于:

class MyViewHolder(val rootView: View) : RecyclerView.ViewHolder(rootView)

class MyAdapter(val items: List<Any>) : RecyclerView.Adapter<MyViewHolder>() {


    companion object {
        const val TYPE_VIEW1 = 1
        const val TYPE_VIEW2 = 2
        const val TYPE_ITEMS = 3
    }

    override fun getItemViewType(position: Int): Int = when (position) {
        0 -> TYPE_VIEW1
        1 -> TYPE_VIEW2
        else -> TYPE_ITEMS
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder = when (viewType) {
        TYPE_VIEW1 -> MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_view1, parent, false))
        TYPE_VIEW2 -> MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_view2, parent, false))
        else -> MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_other, parent, false))
    }

    override fun getItemCount(): Int = 2 + items.size

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

0
投票

尝试这种方式:

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    >
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <View
            android:id="@+id/view"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="@drawable/ic_launcher_background"/>


        <ListView
            android:id="@+id/lvAC"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/view"
            android:nestedScrollingEnabled="true"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

并将此方法设置为您的listview

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();
    }
© www.soinside.com 2019 - 2024. All rights reserved.