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_MOVEsetOnTouchListener나는이 대답을 권하고 싶지 않다 있도록 이벤트가 부작용이있다; 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
    }
}

소스 를 보면 overScrollByWebViewonTouchEvent호출 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.