Web görünümünde kaydırma devre dışı bırakılsın mı?


86

Şimdiye kadar sadece bir iPhone geliştiricisiydim ve şimdi Android'e bir koşuşturma vermeye karar verdim. Android'de çözemediğim bir şey, bir WebView? 'De kaydırmayı programlı olarak nasıl engelleyeceğim ?

İPhone'ların onTouchMoveolayı önlemesine benzer bir şey harika olurdu!

Yanıtlar:


179

İşte web görünümünde tüm kaydırmayı devre dışı bırakmak için kodum :

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

Yalnızca kaydırma çubuklarını gizlemek, ancak kaydırmayı devre dışı bırakmamak için:

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

veya tek sütun düzeni kullanmayı deneyebilirsiniz, ancak bu yalnızca basit sayfalarda çalışır ve yatay kaydırmayı devre dışı bırakır:

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

Ayrıca , web görünümünüzü dikey kaydırmalı kaydırma görünümüyle kaydırmayı deneyebilir ve web görünümündeki tüm kaydırmayı devre dışı bırakabilirsiniz:

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

Ve ayarla

webview.setScrollContainer(false);

webview.setOnTouchListener(...)Web görünümünde tüm kaydırmayı devre dışı bırakmak için yukarıdaki kodu eklemeyi unutmayın . Dikey ScrollView, WebView içeriğinin kaydırılmasına izin verir.


iyi çalışıyor, ancak birkaç saniye sonra /system/lib/libwebcore.so içinde Samsung i5700 spica'da çökmeye neden oluyor.
Lukas,

LayoutAlgorithm.SINGLE_COLUMN veya webview.setOnTouchListener?
48'de peceps

3
ScrollView'a bir Web Görünümü koyarsanız, android: kaydırma çubuklarını "yok" olarak ayarlamak yerine, Web Görünümü'nün android: isScrollContainer özniteliğini "yanlış" olarak ayarlayın. Bu, web görünümünün kaydırma işlemini tamamen devre dışı bırakma etkisine sahiptir ve içeriğine göre genişlemesine izin verir. Scroll daha sonra yalnızca ana ScrollView tarafından işlenecektir.
BladeCoder

1
MotionEvent.ACTION_MOVEOlayları halletmeniz gerekiyorsa WebViewaşağıdaki cevabıma bakın.
GDanger

1
Yok sayılması ACTION_MOVEüzerine setOnTouchListenerbu cevabı tavsiye ETMEM böylece olay bazı yan etkileri vardır; 1. Hızlı kaydırmalar onclick, sayfadaki etkinlikler olarak sayılır . 2. Sayfadaki öğelerin taşmasını önler, bu, siteye bağlı olarak uygun etkileşim için gerekli olabilir. 3. JS touchmoveolayı. @GDanger, başka bir etkisi olmadığı için overScrollBygenişleterek geçersiz kılan doğru cevaba sahip WebView, sadece sayfanın kaydırılmasını engelliyor. stackoverflow.com/a/26129301/1244574
jkasten

22

Hala ihtiyacınız olup olmadığını bilmiyorum, ama işte çözüm:

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

18
tamam. bu kaydırma çubuklarını devre dışı bırakır, ancak sürükleyerek kaydırmayı engellemez. Görünüşe göre html de
sığmalı

Web sayfalarınızı yalnızca android web görünümü için tasarlıyorsanız, web sayfalarınızı tablo halinde yapmanızı öneririm. Genişlik, genişlik = "% 100" gibi ve yükseklik için aynı olmalıdır. böylece artık sürükleme olmayacak.
umar

genişlik =% 100 her zaman çalışmaz, örneğin: stackoverflow.com/questions/6460871/…
NoBugs

harika .. ihtiyacım olan şey bu. Teşekkürler
Peter

21

Yapımı WebViewhareket olayları görmezden bu konuda gitmek için yanlış bir yoldur. Ya WebViewbu olayları duymak gerekirse ?

Bunun yerine WebView, özel olmayan kaydırma yöntemlerini alt sınıflara ayırın ve geçersiz kılın.

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

Eğer bakarsanız kaynağı için WebViewbunu görebilirsiniz onTouchEventçağrıları doDragçağırır overScrollBy .


1
Kaydırmayı programlı olarak devre dışı bırakmanız / etkinleştirmeniz gerekirse, oluşturduğum bu özete bakın .
GDanger

1
Metodun benim için çalışıyor. Ve sana oldukça katılıyorum. Benim durumumda, kabul cevabını kullanarak Web Görünümü'ne yerleştirilmiş video ve ses ilerleme çubuğunu sürükleyemiyorum.
codezjx

Bu doğru cevap. Her ne kadar geçersiz kılan kurucular arasında bazı ince ayarlara ihtiyaç duysa da. Lütfen aşağıdaki tam cevabıma bakın. stackoverflow.com/a/51936944/393502
Vansi

14

Kenar boşluğu ayrıntılarını gövdeye eklemek, içeriğiniz düzgün bir şekilde sarılırsa kaydırmayı engeller:

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

Yeterince kolay ve çok daha az kod + hata yükü :)


1
Parlak! Basit bir yalnızca HTML çözümü için +1. Bazen keşke, android'deki düzen css kadar kolay olsaydı ...
Pritesh Desai

Hisse senedi android tarayıcısında iyi görünüyor, ancak Firefox'ta (Fennec) çalışmıyor gibi görünüyor ... yatay olarak kaydırılacak hiçbir şey olmamasına rağmen, Firefox yine de tüm içeriğin kaydırıldığı noktaya sağa kaydırmama izin veriyor ekranın dışında.
Michael

1
Modern WebView (Android 5 ve üstü) üzerinde çalışmıyor
Roel

8

Web Görünümünüzde bir dinleyici ayarlayın:

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

3
Burada returnsatırın sonunda fazladan bir parantez var. Ayrıca bu, HTML5 canvas ve JavaScript dokunma olaylarını bozar.
Rohan Singh

Bu kesinlikle onu devre dışı bırakır, ancak dinleyiciyi daha sonra girişi yeniden yapılabilir hale getirmek için nasıl öldürebilirim? Denedim event.getAction() != MotionEvent.ACTION_MOVEyanı sırareturn true
CQM

Standart "hiçbir şey yapma" durumu return false, değil return true.
Matthew

6

Henüz bu sorunla karşılaşmadığım için bunu denemedim, ancak belki onScroll işlevini aşabilirsiniz?

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

Buna Hindistan'da Jugaad diyoruz ... gayet iyi çalışmasına rağmen
R4chi7

4

Kirli ama uygulaması kolay ve iyi çalışan çözümüm:

Web görünümünü bir kaydırma görünümünün içine yerleştirmeniz yeterlidir. Web görünümünün olası içerikten çok daha büyük olmasını sağlayın (gereksinimlere bağlı olarak bir veya iki boyutta). ..ve kaydırma görünümünün kaydırma çubuklarını istediğiniz gibi ayarlayın.

Bir web görünümünde yatay kaydırma çubuğunu devre dışı bırakma örneği:

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

Umarım bu yardımcı olur ;)


evet, ama bu durumda kaydırma boyutu altta çok fazla beyaz alan olması çok büyük olmaz?
Rafael Sanches

1
Ya içerik genişliği 1001dp olacaksa?
Waltsu

3

Titreme ve otomatik kaydırmayı şu şekilde çözdüm:

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

Bununla birlikte, herhangi bir nedenle hala çalışmıyorsa, Web Görünümü'nü genişleten bir sınıf oluşturun ve bu yöntemi üzerine koyun:

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

Kaydırmayı devre dışı bırakmak / etkinleştirmek, dokunmaları etkinleştirmek / devre dışı bırakmak, dinleyiciler, kontrol geçişleri, animasyonlar, ayarları dahili olarak tanımlama gibi daha etkili bir kontrol sağlamak için Web Görünümü'nü genişletmeyi öneriyorum.


3

Kaydırmayı devre dışı bırakmak için bunu kullanın

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

2

Sorununuzun kaynağı bu olmayabilir, ancak iphone'da iyi çalışan uygulamamın neden android tarayıcısının sürekli olarak dikey / yatay kaydırma çubuklarını atmasına ve gerçekte sayfayı hareket ettirmesine neden olduğunu bulmaya çalışırken saatler harcadım. Yüksekliği ve genişliği% 100 olarak ayarlanmış bir html gövde etiketim vardı ve gövde farklı yerlerde çeşitli etiketlerle doluydu. Ne denersem deneyeyim, android tarayıcılar kaydırma çubuklarını gösterir ve sayfayı biraz hareket ettirir, özellikle hızlı bir kaydırma yaparken. Bir APK'de hiçbir şey yapmak zorunda kalmadan benim için çalışan çözüm, aşağıdakileri gövde etiketine eklemekti:

leftmargin="0" topmargin="0"

Gövde etiketi için varsayılan kenar boşlukları droid üzerinde uygulanıyor ancak iphone'da yok sayılıyor


1

Size ise alt sınıf Web görünümü, sadece tetik kaydırma bu hareketin-olayları filtrelemek için onTouchEvent geçersiz kılabilir.

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

Yukarıdaki cevapları incelemek benim için neredeyse işe yaradı ... ama yine de 2.1'deki görüşten 'kaçabileceğim' bir problemim vardı (2.2 ve 2.3 ile düzeltilmiş görünüyordu).

işte benim son çözümüm

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 () yöntemini geçersiz kılmak benim için çalışıyor. Benim durumumda, kabul cevabını kullanarak Web Görünümü'ne yerleştirilmiş video ve ses ilerleme çubuğunu sürükleyemiyorum. Çok teşekkürler!
codezjx

-1

Bu tam cevap olmalı. @GDanger tarafından önerildiği gibi. Kaydırma yöntemlerini geçersiz kılmak ve özel web görünümünü düzen xml içine yerleştirmek için Web Görünümü'nü genişletin.

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

Ve sonra aşağıdaki gibi düzen dosyasına katıştırın

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

Ardından, Aktivitede, kaydırma çubuklarını devre dışı bırakmak için bazı ek yöntemler kullanın.

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

-3

Sadece kullanmak android:focusableInTouchMode="false"için üzerinde Web görünümü .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.