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

交互SignatureView时禁用ScrollView滚动的实现方案求助

解决SignatureView在ScrollView中绘制时滚动的问题

这个问题我之前也碰到过,核心就是要让ScrollView在用户操作SignatureView的时候暂时放弃滚动拦截权,下面给你两种可行的方案,第一种最直接好实现:

方案一:通过OnTouchListener控制ScrollView滚动(推荐,无需修改库代码)

步骤1:给ScrollView添加ID

先修改你的布局XML,给ScrollView加上唯一ID,方便后续在代码中获取实例:

<ScrollView 
    android:id="@+id/main_scroll_view" <!-- 新增这个ID -->
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:fitsSystemWindows="true" 
    xmlns:tools="http://schemas.android.com/tools" 
    tools:context="com.example.jordan.promise.fragments.EnterSignature" 
    android:configChanges="orientation|screenSize" 
    android:name=".MainActivity" 
    android:label="@string/app_name">
    <!-- 原有LinearLayout和SignatureView内容保持不变 -->
</ScrollView>

步骤2:在代码中设置触摸监听

在你的onCreateView方法里,获取ScrollView和SignatureView的实例,然后给SignatureView添加触摸监听,控制ScrollView的滚动拦截状态:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_enter_signature, container, false);
    
    // ... 你原有代码(获取控件、设置欢迎文本等)
    
    // 获取ScrollView实例
    ScrollView scrollView = view.findViewById(R.id.main_scroll_view);
    // 获取SignatureView实例
    signatureView = view.findViewById(R.id.signature_view);
    
    // 设置触摸监听,控制ScrollView滚动
    signatureView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // 用户按下SignatureView时,禁止ScrollView拦截触摸事件
                    scrollView.requestDisallowInterceptTouchEvent(true);
                    return false; // 让SignatureView继续处理触摸事件
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    // 用户松开或触摸被取消时,恢复ScrollView的滚动能力
                    scrollView.requestDisallowInterceptTouchEvent(false);
                    return false;
                default:
                    return false;
            }
        }
    });
    
    // ... 你原有其他代码(线程、按钮监听等)
    
    return view;
}

原理说明

requestDisallowInterceptTouchEvent(true)会通知父布局(这里是ScrollView):“这个触摸事件我自己处理,你别插手”,这样ScrollView就不会触发滚动逻辑了。当用户结束触摸后,再调用false恢复父布局的拦截权,ScrollView就能正常滚动了。

方案二:自定义SignatureView(适合深度定制场景)

如果你想让SignatureView本身具备“阻止父布局滚动”的能力,可以自定义一个继承自SignatureView的类,重写onTouchEvent方法:

public class CustomSignatureView extends SignatureView {
    public CustomSignatureView(Context context) {
        super(context);
    }

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

    public CustomSignatureView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 通知父布局不要拦截触摸
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // 恢复父布局的拦截权
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
        }
        // 调用父类的触摸事件处理逻辑
        return super.onTouchEvent(event);
    }
}

然后在XML布局中替换原来的com.kyanogen.signatureview.SignatureView为你的自定义类即可。

两种方案都能解决你的问题,方案一更简单,不需要修改第三方库的代码,推荐优先尝试。

内容的提问来源于stack exchange,提问作者Jordan Edmondson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:09:19