WebView에서 스크롤을 비활성화 하시겠습니까?


86

지금까지 저는 iPhone 개발자 일 뿐이었고 지금은 Android에 소용돌이를 주기로 결정했습니다. 내가 안드로이드에서 알아낼 수 없었던 것은 프로그래밍 방식으로 스크롤을 방지하는 방법입니다 WebView.

iPhones와 유사한 onTouchMove이벤트 예방이 좋을 것입니다!

답변:


179

다음은 webview에서 모든 스크롤 을 비활성화하는 코드입니다 .

  // disable scroll on touch
  webview.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
  });

스크롤바를 숨기고 스크롤을 비활성화하지 않으려면 :

WebView.setVerticalScrollBarEnabled(false);
WebView.setHorizontalScrollBarEnabled(false);

또는 단일 열 레이아웃을 사용해 볼 수 있지만 이것은 단순한 페이지에서만 작동하며 가로 스크롤을 비활성화합니다.

   //Only disabled the horizontal scrolling:
   webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

수직 스크롤 스크롤 뷰로 웹뷰 를 래핑 하고 웹뷰에서 모든 스크롤링을 비활성화 할 수도 있습니다 .

<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical"    >
  <WebView
    android:id="@+id/mywebview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scrollbars="none" />
</ScrollView>

그리고 설정

webview.setScrollContainer(false);

webview.setOnTouchListener(...)webview에서 모든 스크롤을 비활성화 하려면 위 의 코드 를 추가하는 것을 잊지 마십시오 . 수직 ScrollView는 WebView의 콘텐츠 스크롤을 허용합니다.


잘 작동하지만 몇 초 후에 /system/lib/libwebcore.so의 Samsung i5700 spica에서 충돌이 발생합니다.
— Lukas

LayoutAlgorithm.SINGLE_COLUMN 또는 webview.setOnTouchListener?
— peceps

3
WebView를 ScrollView에 넣는 경우, android : scrollbars를 "none"으로 설정하는 대신 WebView의 android : isScrollContainer 속성을 "false"로 설정하십시오. 이는 웹뷰의 스크롤 처리를 완전히 비활성화하는 효과가 있으며 콘텐츠에 따라 확장 할 수 있습니다. 그러면 Scroll은 부모 ScrollView에 의해서만 처리됩니다.
— BladeCoder 2014-08-14

1
MotionEvent.ACTION_MOVE이벤트 를 처리해야하는 경우 WebView아래 내 대답을 참조하십시오.
— GDanger 2014 년

1
무시 ACTION_MOVE온 setOnTouchListener나는이 대답을 권하고 싶지 않다 있도록 이벤트가 부작용이있다; 1. 빠른 스 와이프는 onclick페이지에 대한 이벤트로 계산됩니다 . 2. 페이지 요소의 오버 플로우 스크롤을 방지합니다. 이는 사이트에 따라 적절한 상호 작용을 위해 필요할 수 있습니다. 3. JS touchmove이벤트. @GDanger에는 다른 부작용이 없기 때문에 overScrollBy확장하여 재정의하는 정답이 있으며 WebView페이지 스크롤을 방지합니다. stackoverflow.com/a/26129301/1244574
— jkasten

22

여전히 필요한지 여부는 모르겠지만 해결책은 다음과 같습니다.

appView = (WebView) findViewById(R.id.appView); 
appView.setVerticalScrollBarEnabled(false);
appView.setHorizontalScrollBarEnabled(false);

18
확인. 이것은 스크롤바를 비활성화하지만 드래그에 의한 스크롤을 막지는 않습니다. HTML도 꼭 맞아야하는 것 같습니다 ...
— rdmueller

웹 페이지를 Android 웹보기 전용으로 디자인하는 경우 웹 페이지를 테이블로 만드는 것이 좋습니다. 너비는 width = "100 %"와 같고 높이도 같아야합니다. 더 이상 끌기가 없습니다.
— umar

width = 100 %가 항상 작동하는 것은 아닙니다. 예 : stackoverflow.com/questions/6460871/…
— NoBugs 2011 년

굉장한 .. 내가 필요한 것입니다. 감사합니다
— Peter

21

WebView무시 모션 이벤트를 만드는 것은 잘못된 방법입니다. WebView이러한 이벤트에 대해들을 필요가 있다면 어떨까요?

대신 WebView비공개 스크롤 메서드를 하위 클래스로 만들고 재정의하십시오.

public class NoScrollWebView extends WebView {
    ...
    @Override
    public boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, 
                                int scrollRangeX, int scrollRangeY, int maxOverScrollX, 
                                int maxOverScrollY, boolean isTouchEvent) {
        return false;
    }

    @Override
    public void scrollTo(int x, int y) {
        // Do nothing
    }

    @Override
    public void computeScroll() {
        // Do nothing
    }
}

소스 를 보면 overScrollByWebView 를 onTouchEvent호출 doDrag하는 호출을 볼 수 있습니다 .


1
프로그래밍 방식으로 스크롤을 비활성화 / 활성화해야하는 경우 내가 만든 이 요점을 살펴보십시오 .
— GDanger 2014 년

1
당신의 방법이 저에게 효과적입니다. 그리고 나는 당신에게 매우 동의합니다. 제 경우에는 수락 답변을 사용하여 WebView에 포함 된 비디오 및 오디오 진행률 표시 줄을 드래그 할 수 없습니다.
— codezjx

이것이 정답입니다. 재정의 생성자에 걸쳐 약간의 조정이 필요하지만. 아래의 전체 답변을 참조하십시오. stackoverflow.com/a/51936944/393502
— Vansi

14

본문에 여백 세부 정보를 추가하면 콘텐츠가 올바르게 래핑 된 경우 스크롤되지 않습니다.

<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">

충분히 쉽고 코드 + 버그 오버 헤드가 훨씬 적습니다. :)


1
훌륭한! 간단한 HTML 전용 솔루션의 경우 +1. 가끔 ... 안드로이드의 레이아웃은 CSS로 쉽게했다 소원
— Pritesh 데 사이

기본 안드로이드 브라우저에서는 잘 보이지만 Firefox (Fennec)에서는 작동하지 않는 것 같습니다. 가로로 스크롤 할 항목이 없지만 Firefox에서는 여전히 모든 콘텐츠가 스크롤 된 지점까지 오른쪽으로 스크롤 할 수 있습니다. 화면에서.
— Michael

1
최신 WebView (Android 5 이상)에서 작동하지 않음
— Roel

8

WebView에 리스너를 설정하십시오.

webView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                return(event.getAction() == MotionEvent.ACTION_MOVE));
            }
        });

3
return줄 끝에 추가 괄호 가 있습니다. 또한 이것은 HTML5 캔버스 및 JavaScript 터치 이벤트를 중단합니다.
— Rohan Singh

이것은 확실히 그것을 비활성화하지만 나중에 어떻게 리스너를 종료하여 입력을 렌탈합니까? 나는 event.getAction() != MotionEvent.ACTION_MOVE뿐만 아니라 시도return true
— CQM

표준 "아무것도하지 않음"사례는가 return false아니라 return true입니다.
— 마태 복음 읽기

6

아직이 문제가 발생하지 않았기 때문에 시도하지 않았지만 onScroll 함수를 무시할 수 있습니까?

@Override
public void scrollTo(int x, int y){
super.scrollTo(0,y);
}

이것은 단지 잘 작동하지만, 우리가 ... 인도 Jugaad에 부르는
— R4chi7

4

더럽지 만 구현하기 쉽고 잘 작동하는 솔루션 :

단순히 스크롤 뷰 안에 웹뷰를 넣으십시오. 웹뷰를 가능한 콘텐츠보다 너무 크게 만듭니다 (요구 사항에 따라 하나 또는 두 차원 모두에서). .. 그리고 원하는대로 스크롤 뷰의 스크롤바를 설정합니다.

웹뷰에서 수평 스크롤바를 비활성화하는 예 :

<ScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:scrollbars="vertical"
>
    <WebView
        android:id="@+id/mywebview"
        android:layout_width="1000dip"
        android:layout_height="fill_parent"
    />
</ScrollView>

이게 도움이 되길 바란다 ;)


네,하지만 스크롤 크기가 너무 크지 않고 하단에 공백이 많지 않습니까?
— Rafael Sanches 2011 년

1
콘텐츠 너비가 1001dp이면 어떻게 되나요?
— Waltsu 2014-08-22

3

깜박임 및 자동 스크롤을 다음과 같이 해결했습니다.

webView.setFocusable(false);
webView.setFocusableInTouchMode(false);

그러나 어떤 이유로 여전히 작동하지 않으면 WebView를 확장하는 클래스를 만들고이 메서드를 그 위에 넣으십시오.

// disable scroll on touch
  setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
  });

스 와이프 비활성화 / 활성화, 터치 활성화 / 비활성화, 리스너, 제어 전환, 애니메이션, 내부적으로 설정 정의 등과 같은보다 효과적인 제어를 제공하기 위해 WebView를 확장 할 것을 제안합니다.


3

스크롤을 비활성화하려면 다음을 사용하십시오.

webView.setOnTouchListener(new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) 
    {
        return (event.getAction() == MotionEvent.ACTION_MOVE);
    }
});

2

이것이 문제의 원인은 아니지만 iPhone에서 잘 작동하는 내 응용 프로그램으로 인해 Android 브라우저가 지속적으로 수직 / 수평 스크롤 막대를 표시하고 실제로 페이지를 이동시키는 이유를 추적하는 데 몇 시간을 보냈습니다. 높이와 너비가 100 %로 설정된 html body 태그가 있었고 본문에는 여러 위치에있는 다양한 태그가 가득했습니다. 내가 무엇을 시도하든 안드로이드 브라우저는 스크롤 막대를 표시하고 페이지를 조금만 움직일 것입니다. 특히 빠른 스 와이프를 할 때 그렇습니다. APK에서 아무것도 할 필요없이 나를 위해 일한 솔루션은 body 태그에 다음을 추가하는 것이 었습니다.

leftmargin="0" topmargin="0"

바디 태그의 기본 여백이 드로이드에 적용되었지만 아이폰에서는 무시 된 것 같습니다


1

Webview 를 하위 클래스로 만드는 경우 단순히 onTouchEvent를 재정 의하여 스크롤을 트리거하는 이동 이벤트를 필터링 할 수 있습니다.

public class SubWebView extends WebView {

    @Override
    public boolean onTouchEvent (MotionEvent ev)    {
        if(ev.getAction() == MotionEvent.ACTION_MOVE) {
            postInvalidate();
            return true;
        }
        return super.onTouchEvent(ev);
    }
    ...

0

위의 답변을 공부하면 거의 효과가 있었지만 2.1에서 뷰를 '플링'할 수 있다는 문제가 여전히있었습니다 (2.2 및 2.3으로 수정 된 것으로 보임).

여기 내 최종 해결책이 있습니다.

public class MyWebView extends WebView
{
private boolean bAllowScroll = true;
@SuppressWarnings("unused") // it is used, just java is dumb
private long downtime;

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

public void setAllowScroll(int allowScroll)
{
    bAllowScroll = allowScroll!=0;
    if (!bAllowScroll)
        super.scrollTo(0,0);
    setHorizontalScrollBarEnabled(bAllowScroll);
    setVerticalScrollBarEnabled(bAllowScroll);
}

@Override
public boolean onTouchEvent(MotionEvent ev) 
{
    switch (ev.getAction())
    {
    case MotionEvent.ACTION_DOWN:
        if (!bAllowScroll)
            downtime = ev.getEventTime();
        break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
        if (!bAllowScroll)
        {
            try {
                Field fmNumSamples = ev.getClass().getDeclaredField("mNumSamples");
                fmNumSamples.setAccessible(true);
                Field fmTimeSamples = ev.getClass().getDeclaredField("mTimeSamples");
                fmTimeSamples.setAccessible(true);
                long newTimeSamples[] = new long[fmNumSamples.getInt(ev)];
                newTimeSamples[0] = ev.getEventTime()+250;
                fmTimeSamples.set(ev,newTimeSamples);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        break;
    }
    return super.onTouchEvent(ev);
}

@Override
public void flingScroll(int vx, int vy)
{
    if (bAllowScroll)
        super.flingScroll(vx,vy);
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt)
{
    if (bAllowScroll)
        super.onScrollChanged(l, t, oldl, oldt);
    else if (l!=0 || t!=0)
        super.scrollTo(0,0);
}

@Override
public void scrollTo(int x, int y)
{
    if (bAllowScroll)
        super.scrollTo(x,y);
}

@Override
public void scrollBy(int x, int y)
{
    if (bAllowScroll)
        super.scrollBy(x,y);
}
}

onScrollChanged () 메서드를 재정의하는 것이 저에게 효과적입니다. 제 경우에는 수락 답변을 사용하여 WebView에 포함 된 비디오 및 오디오 진행률 표시 줄을 드래그 할 수 없습니다. 감사합니다!
— codezjx

-1

이것은 완전한 대답이어야합니다. @GDanger가 제안한대로. WebView를 확장하여 스크롤 메서드를 재정의하고 레이아웃 xml 내에 사용자 지정 웹보기를 포함합니다.

public class ScrollDisabledWebView extends WebView {

    private boolean scrollEnabled = false;

    public ScrollDisabledWebView(Context context) {
        super(context);
        initView(context);
    }

    public ScrollDisabledWebView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        initView(context);
    }
    // this is important. Otherwise it throws Binary Inflate Exception.
    private void initView(Context context) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    }

    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,
                                   int scrollRangeX, int scrollRangeY, int maxOverScrollX,
                                   int maxOverScrollY, boolean isTouchEvent) {
        if (scrollEnabled) {
            return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,
                    scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
        }
        return false;
    }

    @Override
    public void scrollTo(int x, int y) {
        if (scrollEnabled) {
            super.scrollTo(x, y);
        }
    }

    @Override
    public void computeScroll() {
        if (scrollEnabled) {
            super.computeScroll();
        }
    }
}

그리고 다음과 같이 레이아웃 파일에 임베드하십시오.

<com.sample.apps.ScrollDisabledWebView
    android:id="@+id/webView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    tools:context="com.sample.apps.HomeActivity"/>

그런 다음 활동에서 스크롤 막대를 비활성화하는 몇 가지 추가 방법을 사용하십시오.

ScrollDisabledWebView webView = (ScrollDisabledWebView) findViewById(R.id.webView);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);

-3

webView에서 사용 android:focusableInTouchMode="false"하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.