You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LinearLayout无法整体滚动:ListView与PDFView需同步滚动问题

我来帮你分析下当前布局的问题,然后给出能实现「单独滚动/同步滚动」切换的解决方案:

首先你的布局里有两个核心问题导致无法同步滚动:

  1. ScrollView嵌套可滚动控件:ListView和PDFView本身都是自带滚动逻辑的容器,嵌套在ScrollView里会触发滚动事件冲突,两者的滚动逻辑互相干扰,自然没法同步。
  2. ListView固定高度限制:你给ListView设置了android:layout_height="70dp",这让它只能在固定高度内小范围滚动,没法和PDFView的整体滚动区域匹配。
解决方案

第一步:重构布局结构

先把外层的ScrollView去掉,改用LinearLayout作为容器承载列表和PDFView,同时建议用RecyclerView替代ListView——RecyclerView对wrap_content的支持更友好,不用额外自定义测量逻辑。

重构后的布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".uiFragments.HerstellerunterlagenInstandhalterFragment">

    <!-- 顶部切换按钮,用于控制同步滚动开关 -->
    <Button
        android:id="@+id/btn_toggle_sync"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开启同步滚动"
        android:layout_gravity="center_horizontal"
        android:layout_margin="10dp"/>

    <!-- 用RecyclerView替代ListView,解决wrap_content高度问题 -->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview_anlagenuebersicht_instandhalter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="1dp"
        android:background="@android:color/white"
        android:listSelector="@drawable/bkg" />

    <!-- PDFView占据剩余屏幕空间 -->
    <com.github.barteksc.pdfviewer.PDFView
        android:id="@+id/pdfView_anlage"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_marginTop="10dp" />

</LinearLayout>

第二步:实现滚动模式切换逻辑

我们通过一个开关变量控制是否开启同步滚动,然后监听两个控件的滚动事件,互相同步滚动位置。

1. 初始化控件与滚动监听

在你的Fragment的onViewCreated方法里添加以下代码:

private var isSyncScrollEnabled = false // 同步滚动状态开关
private lateinit var recyclerView: RecyclerView
private lateinit var pdfView: PDFView

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    recyclerView = view.findViewById(R.id.recyclerview_anlagenuebersicht_instandhalter)
    pdfView = view.findViewById(R.id.pdfView_anlage)
    val toggleBtn = view.findViewById<Button>(R.id.btn_toggle_sync)

    // 初始化RecyclerView(替换成你自己的Adapter和数据)
    recyclerView.layoutManager = LinearLayoutManager(requireContext())
    recyclerView.adapter = YourAnlagenAdapter(yourDataList)

    // 初始化PDFView(替换成你的PDF加载逻辑)
    pdfView.fromAsset("your_target_pdf.pdf")
        .enableSwipe(true)
        .onScroll { _, offsetY ->
            // 当PDFView滚动时,同步RecyclerView的位置(仅在同步模式开启时)
            if (isSyncScrollEnabled) {
                recyclerView.scrollBy(0, offsetY - recyclerView.scrollY)
            }
        }
        .load()

    // 给RecyclerView添加滚动监听
    recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            // 当RecyclerView滚动时,同步PDFView的位置(仅在同步模式开启时)
            if (isSyncScrollEnabled) {
                pdfView.scrollBy(0, dy)
            }
        }
    })

    // 切换同步滚动模式的按钮逻辑
    toggleBtn.setOnClickListener {
        isSyncScrollEnabled = !isSyncScrollEnabled
        toggleBtn.text = if (isSyncScrollEnabled) "关闭同步滚动" else "开启同步滚动"
    }
}

2. (可选)如果坚持用ListView的适配方案

如果你不想换成RecyclerView,需要自定义一个支持wrap_content的ListView,否则ListView只会显示一行内容:

public class WrapContentListView extends ListView {
    public WrapContentListView(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 让ListView自适应内容高度
        int expandSpec = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}

然后在布局里替换原来的ListView为这个自定义控件即可。

小提示

如果你的PDF支持缩放,同步滚动时可能需要根据缩放比例调整偏移量,你可以通过PDFView的getZoom()方法获取当前缩放值,然后对滚动偏移进行适配。

内容的提问来源于stack exchange,提问作者Josi Allen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:45:04