Development Tip

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

yourdevel 2020. 9. 25. 23:42
반응형

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


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

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


다음은 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의 콘텐츠 스크롤을 허용합니다.


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

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

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하는 호출을 볼 수 있습니다 .


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

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

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


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

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

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

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

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

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

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

<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>

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


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

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

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

leftmargin="0" topmargin="0"

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


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

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를 확장 할 것을 제안합니다.


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);
    }
    ...

위의 답변을 공부하면 거의 효과가 있었지만 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);
}
}

이것은 완전한 대답이어야합니다. @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"/>

Then in the Activity, use some additional methods for disabling scrollbars too.

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

Just use android:focusableInTouchMode="false" on your webView.

참고URL : https://stackoverflow.com/questions/2527899/disable-scrolling-in-webview

반응형