Android: Disable text selection in a webview
Asked Answered
O

7

66

I am using a webview to present some formatted stuff in my app. For some interaction (which are specific to certain dom elements) I use javascript and WebView.addJavascriptInterface(). Now, I want to recognize a long touch. Unfortunately, onLongTouch, in Android 2.3 the handles for text selection are displayed.

How can I turn off this text selection without setting the onTouchListener and return true? (Then, the interaction with the "website" doesn't work anymore.

Outofdoor answered 24/2, 2011 at 16:41 Comment(1)
For those curious to handle (e.g. disable) all touch events through a custom View.OnTouchListener, see this related question.Clumsy
O
9

I figured it out!! This is how you can implement your own longtouchlistener. In the function longTouch you can make a call to your javascript interface.

var touching = null;
$('selector').each(function() {
    this.addEventListener("touchstart", function(e) {
        e.preventDefault();
        touching = window.setTimeout(longTouch, 500, true);
    }, false);
    this.addEventListener("touchend", function(e) {
        e.preventDefault();
        window.clearTimeout(touching);
    }, false);
});

function longTouch(e) {
    // do something!
}

This works.

Outofdoor answered 24/2, 2011 at 18:21 Comment(6)
My problem remains: The event.preventDefault() call in the touchstart event also prevents the normal cursor mode input/selection (on html textinput elements).Engstrom
that is true... Maybe switching off all long touch events on the android layer and removing the preventDefaults works?Outofdoor
the behaviour is confusing me.. returning true for every onTouch event seems to work, but when I only select certain (long) move and down events to skip further propagation, I run into states, where I do not get any event until text selection is cancelled (e.g.) input element changed.. text selection seems also be triggered between the down and the (future) up event. maybe I am missing another event type where I can cancel it..Engstrom
I've found that this breaks any scrolling in the browser. For example, if you put your finger on the selector element and try to scroll up and down, nothing will happen.Sublease
@EMMERICH, I ran into same problem, it broke scrolling. Is there any solution to prevent text selection in native way?Mcdonough
Thanks for this info - I was having a different problem - trying to prevent android from popping up a selector box while the html selector was disabled by my code (using logic, not the disabled state), and your method of catching 'touchstart' did the trickMirianmirielle
A
146

This worked for me

mWebView.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        return true;
    }
});
mWebView.setLongClickable(false);

I have not tested, if you don't want the vibration caused by the long click, you can try this:

mWebView.setHapticFeedbackEnabled(false);
Ammonate answered 9/10, 2012 at 6:6 Comment(8)
That still produce a small vibration (but no contextual action bar).Ballerina
mWebView.setLongClickable(false); does not make any different, but setting long click listener and passing true from onLongClick() method worked for me.Salchunas
This worked for me, but I didn't need the last line "mWebView.setLongClickable(false);"Aguste
mWebView.setOnLongClickListener(v -> true); mWebView.setLongClickable(false);Borrero
This is working fine but if we double tap on the content in a text field ,selection& copy options are enabled. How to disable this?Running
Worked for me for a Crash Bug fix in Lollipop Android Versions. Thanks.Kraul
Not working for me, text keeps getting selected upon short click.Apophthegm
how to disable selectionAbnormity
D
44

Setting webkit css property -webkit-user-select to none would solve the problem.

Example CSS to disable selection:

* {
   -webkit-user-select: none;
}
Dealt answered 8/9, 2011 at 1:53 Comment(4)
This is actually the best solution to prevent selection because it is cross-platform.Garrido
Unfortunately this doesn't work in all versions of Android. It should be the best solution, but it isn't :/Illsorted
*:not(input):not(textarea) { webkit-user-select: none; }Argot
Thanks alot, in order to get it to work with android I changed it to '{ webkit-user-select: none; user-select: none; }'Ermines
O
9

I figured it out!! This is how you can implement your own longtouchlistener. In the function longTouch you can make a call to your javascript interface.

var touching = null;
$('selector').each(function() {
    this.addEventListener("touchstart", function(e) {
        e.preventDefault();
        touching = window.setTimeout(longTouch, 500, true);
    }, false);
    this.addEventListener("touchend", function(e) {
        e.preventDefault();
        window.clearTimeout(touching);
    }, false);
});

function longTouch(e) {
    // do something!
}

This works.

Outofdoor answered 24/2, 2011 at 18:21 Comment(6)
My problem remains: The event.preventDefault() call in the touchstart event also prevents the normal cursor mode input/selection (on html textinput elements).Engstrom
that is true... Maybe switching off all long touch events on the android layer and removing the preventDefaults works?Outofdoor
the behaviour is confusing me.. returning true for every onTouch event seems to work, but when I only select certain (long) move and down events to skip further propagation, I run into states, where I do not get any event until text selection is cancelled (e.g.) input element changed.. text selection seems also be triggered between the down and the (future) up event. maybe I am missing another event type where I can cancel it..Engstrom
I've found that this breaks any scrolling in the browser. For example, if you put your finger on the selector element and try to scroll up and down, nothing will happen.Sublease
@EMMERICH, I ran into same problem, it broke scrolling. Is there any solution to prevent text selection in native way?Mcdonough
Thanks for this info - I was having a different problem - trying to prevent android from popping up a selector box while the html selector was disabled by my code (using logic, not the disabled state), and your method of catching 'touchstart' did the trickMirianmirielle
V
6

It appears that cut/paste via long press is turned off if you used

    articleView.setWebChromeClient(new WebChromeClient(){...})

See https://bugzilla.wikimedia.org/show_bug.cgi?id=31484

So if you are using setChromeClient and you WANT to have long click to start copy/paste, the do the following:

    webView.setWebChromeClient(new WebChromeClient(){

        [.... other overrides....]

        // @Override
        // https://bugzilla.wikimedia.org/show_bug.cgi?id=31484
        // If you DO NOT want to start selection by long click,
        // the remove this function
        // (All this is undocumented stuff...)
        public void onSelectionStart(WebView view) {
            // By default we cancel the selection again, thus disabling
            // text selection unless the chrome client supports it.
            // view.notifySelectDialogDismissed();
        }

    });
Vestryman answered 19/4, 2012 at 17:4 Comment(6)
I need to have the copy/paste feature in my webview. I used setWebChromeClient to use onProgressChanged method for progress bar updates. This disabled the copy/paste feature. Adding the onSelectionStart method enabled copy/paste again. Thanks a lot for this hidden gem!Shoop
This method isn't in the API, what are you guys talking about? developer.android.com/reference/android/webkit/…Punishable
This also confuses me, what Android system are you talking about?Dias
They are referring to a "hidden" API method: bugzilla.wikimedia.org/show_bug.cgi?id=31484#c15 hence why it does not show up in the API docs for WebChromeClient class.Miller
This workaround only works until SDK 2.3.7 r1. For newer SDK you can't use WebChromeClient or don't use Copy/Paste on 2.3.x mobiles. See grepcode.com/file/repository.grepcode.com/java/ext/… and grepcode.com/file/repository.grepcode.com/java/ext/…Wateriness
Would this also help with long clicking on links in order to open them in the default web browser?Bournemouth
L
0

It seems that the only option is to set onTouchListener and write your own code to detect long-click. Then return true if it's a long-click and false otherwise.

Lewd answered 24/2, 2011 at 16:48 Comment(5)
But I want to implement a longclick listener in javascript as well. By overriding the onTouchListener I would turn off all long clicks on the view. How can it be, that one can not turn off text selection? I think this is a pretty basic thing to want to do.Outofdoor
Got it. Try this: #924282Lewd
does not seem to have any effect in android.Outofdoor
but with android 4.4 default selection also comingJaunitajaunt
this would disable scrolling.Funereal
D
0

An alternative solution is to subclass WebView and Override performLongClick as bellow:

public class AdvanceWebView extends WebView {
   //Add constructors...
   @Override
   public boolean performLongClick() {
   return true;
   }
}
Dogfish answered 6/10, 2019 at 23:6 Comment(0)
P
0

For kotlin i found the following to work:

webView.isLongClickable = false
Pyrotechnics answered 1/6, 2020 at 7:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.