Nonaktifkan pengguliran di tampilan web?

86

Sampai sekarang saya hanya menjadi pengembang iPhone dan sekarang saya telah memutuskan untuk mencoba Android. Sesuatu yang belum dapat saya pahami di Android adalah cara mencegah pengguliran secara terprogram dalam WebView?

Sesuatu yang mirip dengan pencegahan iPhone dari onTouchMoveacara tersebut akan sangat bagus!

Jake Sankey
sumber

Jawaban:

179

Berikut kode saya untuk menonaktifkan semua pengguliran di tampilan web:

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

Untuk hanya menyembunyikan scrollbar, tetapi tidak menonaktifkan scrolling:

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

atau Anda dapat mencoba menggunakan tata letak kolom tunggal tetapi ini hanya berfungsi dengan halaman sederhana dan menonaktifkan pengguliran horizontal:

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

Anda juga dapat mencoba membungkus tampilan web Anda dengan tampilan gulir yang digulir secara vertikal dan menonaktifkan semua pengguliran di tampilan web:

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

Dan atur

webview.setScrollContainer(false);

Jangan lupa untuk menambahkan webview.setOnTouchListener(...)kode di atas untuk menonaktifkan semua pengguliran di tampilan web. ScrollView vertikal akan memungkinkan untuk menggulir konten WebView.

peceps
sumber
berfungsi dengan baik, tetapi setelah beberapa detik menyebabkan crash pada Samsung i5700 spica di /system/lib/libwebcore.so.
Lukas
LayoutAlgorithm.SINGLE_COLUMN atau webview.setOnTouchListener?
peceps
3
Jika Anda meletakkan WebView di ScrollView, setel atribut android: isScrollContainer dari WebView ke "false" daripada menyetel android: scrollbars ke "none". Ini memiliki efek menonaktifkan sepenuhnya penanganan gulir tampilan web dan memungkinkannya untuk meluas sesuai dengan kontennya. Scroll kemudian akan ditangani hanya oleh ScrollView induk.
BladeCoder
1
Jika Anda perlu menangani MotionEvent.ACTION_MOVEacara di Anda WebViewlihat jawaban saya di bawah.
GDanger
1
Mengabaikan ACTION_MOVEpada setOnTouchListeneracara tersebut memiliki beberapa efek samping jadi saya TIDAK akan merekomendasikan jawaban ini; 1. Gesek cepat dihitung sebagai onclickperistiwa di halaman. 2. Mencegah overflow scrolling elemen pada halaman, ini mungkin diperlukan untuk interaksi yang tepat tergantung pada situs. 3. Acara JS touchmove. @GDanger memiliki jawaban yang benar yang mengesampingkan overScrollBydengan memperluas WebViewkarena tidak memiliki efek samping, hanya mencegah pengguliran halaman. stackoverflow.com/a/26129301/1244574
jkasten
22

Saya tidak tahu apakah Anda masih membutuhkannya atau tidak, tetapi inilah solusinya:

appView = (WebView) findViewById(R.id.appView); 
appView.setVerticalScrollBarEnabled(false);
appView.setHorizontalScrollBarEnabled(false);
umar
sumber
18
baik. ini menonaktifkan scrollbar, tetapi tidak mencegah scrolling dengan menyeret. Tampaknya html juga harus pas ...
rdmueller
Jika Anda mendesain halaman web Anda hanya untuk tampilan web android maka saya sarankan membuat halaman web Anda dalam tabel. Lebar harus seperti width = "100%" dan sama untuk tingginya. jadi tidak akan ada lagi penyeretan.
umar
width = 100% tidak selalu berfungsi, misalnya: stackoverflow.com/questions/6460871/…
NoBugs
mengagumkan .. itu yang saya butuhkan. Terima kasih
Peter
21

Membuat WebViewperistiwa gerakan pengabaian adalah cara yang salah untuk melakukannya. Bagaimana jika WebViewperlu mendengar tentang acara tersebut?

Alih-alih membuat subkelas WebViewdan mengganti metode gulir non-pribadi.

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

Jika Anda melihat sumber untuk WebViewAnda dapat melihat bahwa onTouchEventpanggilan doDragyang menyerukan overScrollBy .

GDanger
sumber
1
Jika Anda perlu menonaktifkan programatis / mengaktifkan gulir, lihat inti yang saya buat ini.
GDanger
1
Metode Anda berhasil untuk saya. Dan saya sangat setuju dengan Anda. Dalam kasus saya, saya tidak dapat menyeret bilah kemajuan video & audio yang disematkan di WebView dengan menggunakan jawaban terima.
codezjx
Ini adalah jawaban yang benar. Meskipun perlu beberapa penyesuaian di konstruktor utama. Silakan lihat jawaban lengkap saya di bawah ini. stackoverflow.com/a/51936944/393502
Vansi
14

Menambahkan detail margin ke badan akan mencegah pengguliran jika konten Anda terbungkus dengan benar, seperti:

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

Cukup mudah, dan lebih sedikit kode + overhead bug :)

Auri Rahimzadeh
sumber
1
Cemerlang! 1 untuk solusi HTML sederhana saja. Terkadang saya berharap, tata letak di android semudah css ...
Pritesh Desai
Terlihat bagus di browser Android stok, tetapi tampaknya tidak berfungsi di Firefox (Fennec) ... meskipun tidak ada yang bisa digulir secara horizontal, Firefox masih memungkinkan saya menggulir ke kanan ke titik di mana semua konten telah bergulir dari layar.
Michael
1
Tidak berfungsi pada WebView modern (Android 5 dan lebih tinggi)
Roel
8

Setel pendengar di WebView Anda:

webView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                return(event.getAction() == MotionEvent.ACTION_MOVE));
            }
        });
pengguna322987
sumber
3
Ada tanda kurung tambahan di akhir returnbaris di sana. Juga ini merusak kanvas HTML5 dan acara sentuh JavaScript.
Rohan Singh
Ini tentu saja menonaktifkannya, tetapi bagaimana cara mematikan pendengar nanti untuk masukan yang dapat diubah? Saya mencoba event.getAction() != MotionEvent.ACTION_MOVEjugareturn true
CQM
Kasus standar "tidak melakukan apa-apa" adalah return false, bukan return true.
Matius Baca
6

Saya belum mencoba ini karena saya belum mengalami masalah ini, tetapi mungkin Anda dapat mengatasi fungsi onScroll?

@Override
public void scrollTo(int x, int y){
super.scrollTo(0,y);
}
ZeroTruths
sumber
Inilah yang kami sebut di India sebagai Jugaad ... meskipun bekerja dengan baik
R4chi7
4

Solusi kotor saya, tetapi mudah diterapkan dan berfungsi dengan baik:

Cukup letakkan tampilan web di dalam tampilan gulir. Buat tampilan web menjadi terlalu besar dari kemungkinan konten (dalam satu atau kedua dimensi, tergantung pada persyaratan). ..dan atur scrollbar tampilan gulir sesuai keinginan Anda.

Contoh untuk menonaktifkan scrollbar horizontal pada tampilan web:

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

Saya harap ini membantu ;)

pengguna289463
sumber
ya, tapi ukuran gulirnya tidak akan terlalu besar dengan banyak ruang putih di bagian bawah?
Rafael Sanches
1
Bagaimana jika lebar konten akan menjadi 1001dp?
Waltsu
3

Saya menyelesaikan flicker dan auto-scroll dengan:

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

Namun jika masih tidak berfungsi karena beberapa alasan, cukup buat kelas yang memperluas WebView, dan letakkan metode ini di atasnya:

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

Saya menyarankan untuk memperluas WebView, untuk memberikan kontrol yang lebih efektif, seperti menonaktifkan / mengaktifkan gesekan, mengaktifkan / menonaktifkan sentuhan, pendengar, mengontrol transisi, animasi, menetapkan pengaturan secara internal, dan sebagainya ..

Abhinav Saxena
sumber
3

Untuk Menonaktifkan gulir gunakan ini

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

Ini mungkin bukan sumber masalah Anda tetapi saya telah menghabiskan berjam-jam mencoba melacak mengapa aplikasi saya yang berfungsi dengan baik di iphone menyebabkan browser android terus-menerus memunculkan scrollbar vertikal / horizontal dan benar-benar memindahkan halaman. Saya memiliki tag tubuh html dengan tinggi dan lebar disetel ke 100%, dan badan penuh dengan berbagai tag di lokasi berbeda. Tidak peduli apa yang saya coba, browser android akan menampilkan scroll bar dan memindahkan halaman sedikit, terutama saat melakukan swipe cepat. Solusi yang berhasil untuk saya tanpa harus melakukan apa pun di APK adalah menambahkan yang berikut ini ke tag body:

leftmargin="0" topmargin="0"

Tampaknya margin default untuk tag badan diterapkan di droid tetapi diabaikan di iPhone

Robert Etheredge
sumber
1

Jika Anda membuat subkelas Webview, Anda cukup mengganti onTouchEvent untuk memfilter peristiwa pemindahan yang memicu pengguliran.

public class SubWebView extends WebView {

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

mempelajari jawaban di atas hampir berhasil untuk saya ... tetapi saya masih memiliki masalah sehingga saya dapat 'melemparkan' pandangan di 2.1 (sepertinya diperbaiki dengan 2.2 & 2.3).

inilah solusi terakhir saya

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);
}
}
SteelBytes
sumber
Untuk menimpa metode onScrollChanged () bekerja untuk saya. Dalam kasus saya, saya tidak dapat menyeret bilah kemajuan video & audio yang disematkan di WebView dengan menggunakan jawaban terima. Terima kasih banyak!
codezjx
-1

Ini harus menjadi jawaban yang lengkap. Seperti yang disarankan oleh @GDanger. Perluas WebView untuk mengganti metode gulir dan menyematkan tampilan web khusus dalam layout 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();
        }
    }
}

Dan kemudian sematkan dalam file tata letak sebagai berikut

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

Kemudian di Aktivitas, gunakan beberapa metode tambahan untuk menonaktifkan scrollbar juga.

ScrollDisabledWebView webView = (ScrollDisabledWebView) findViewById(R.id.webView);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
Vansi
sumber
-3

Cukup gunakan android:focusableInTouchMode="false"di webView Anda .

Socratex
sumber