Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Webview, Setting Long Click enabled on links exclusively?

Similar to other browser like Chrome and Firefox, I need the user to long click a link then show a context menu but if they long click something and it is not a link then do nothing.

Using registerForContextMenu(myWebView); allows long clicking on any object which I do not want. Therefore, I think one needs to filter the objects from registerForContextMenu(myWebView); or parse the html for links which seems overkill. I have also tried overriding shouldOverrideUrlLoadingmethod:

private boolean isLongClicked = false;  

this.webView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
                  if(isLongCLicked){
                          //do something
                     }else
                view.loadUrl(url);

            return true;
        }

    });

    webView.setOnLongClickListener(new OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                        isLongClicked = true;
                    forumView.performClick();
                        isLongCLicked = false;
                    return false;
                }
            });

I have looked at this thread Enable longClick in WebView but it has not helped me. I tried implementing it but I get a force close.

import android.content.Context;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.webkit.WebView;

public class WebViewSub extends WebView {


    public WebViewSub(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onCreateContextMenu(ContextMenu menu) {
        super.onCreateContextMenu(menu);

        HitTestResult result = getHitTestResult();

        MenuItem.OnMenuItemClickListener handler = new MenuItem.OnMenuItemClickListener() {
            public boolean onMenuItemClick(MenuItem item) {
                // do the menu action
                return true;
            }
        };

        if (result.getType() == HitTestResult.IMAGE_TYPE
                || result.getType() == HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
            // Menu options for an image.
            // set the header title to the image url
            menu.setHeaderTitle(result.getExtra());
            menu.add("save image")
                    .setOnMenuItemClickListener(handler);
            menu.add("View Image")
                    .setOnMenuItemClickListener(handler);
        } else if (result.getType() == HitTestResult.ANCHOR_TYPE
                || result.getType() == HitTestResult.SRC_ANCHOR_TYPE) {
            // Menu options for a hyperlink.
            // set the header title to the link url
            menu.setHeaderTitle(result.getExtra());
            menu.add("Save Link")
                    .setOnMenuItemClickListener(handler);
            menu.add("Share Link")
                    .setOnMenuItemClickListener(handler);
        }
    }
}

Lastly I tried using a HitTestResult, This is probably the closest I have got to solving the problem.

myWebView.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                registerForContextMenu(myWebView);
                WebView.HitTestResult result = forumView.getHitTestResult();
                if(result.getType() == 7){


                    openContextMenu(myWebView);

                }
                unregisterForContextMenu(myWebView);
                return false;
            }
        });

This does work only on links, however my context menu displays as a blank rectangle. I have tried using the actual OnLongClick View but it doesn't seem to work either. I do not think that my Context Menu is wrong; it worked outside OnLongClick.

@Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        getMenuInflater().inflate(R.menu.click, menu);
    }

How do I get the menu to appear correctly? I think I am on the right track using the HitTestResult onLongClick.

Edit (ANSWER):

myWebView.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                unregisterForContextMenu(myWebView);
                WebView.HitTestResult result = forumView.getHitTestResult();
                if(result.getType() == 7){
                registerForContextMenu(myWebView);


                }

                return false;
            }
        });

Every time on Long Click this unregisters the context menu then registers it, popping up the menu. I believe this works because as soon as a link is clicked it unregisters the registered context menu and then decides if it's a link to pull up the context menu. Previously, it would not give the user time to choose a option and immediately after registering the context menu unregister it.

like image 896
horvste Avatar asked Jun 15 '13 17:06

horvste


People also ask

How can I make my WebView faster on Android?

I read about how to increase performance of WebView by implementing Caching web resources like JS, CSS and image files. You can also static resources in your native application, and by intercepting the Resource requests you can override the default behaviour of WebView.

How do I enable JavaScript on Android WebView?

Enable JavaScript JavaScript is disabled in a WebView by default. You can enable it through the WebSettings attached to your WebView . You can retrieve WebSettings with getSettings() , then enable JavaScript with setJavaScriptEnabled() . WebView myWebView = (WebView) findViewById(R.

What can I use instead of WebView?

Alternatives to WebView If you want to send users to a mobile site, build a progressive web app (PWA). If you want to display third-party web content, send an intent to installed web browsers. If you want to avoid leaving your app to open the browser, or if you want to customize the browser's UI, use Custom Tabs.


1 Answers

This is actually a situation I was coming across rather lately due to an app I have been working on -- the solution that you arrived to is essentially the same that I implemented, so here it is for completions sake:

    webView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            unregisterForContextMenu(webView);
            WebView.HitTestResult result = webView.getHitTestResult();
            if (result.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
                registerForContextMenu(webView);
            } else {
                return true;
            }

            return false;
        }

Note that by using result.getExtra() you will retrieve the filtered results from the WebView, in this case, a HTML::a tag with src=http. Note that I also ignore any other long clicks on the WebView by returning true (handled).

like image 130
avluis Avatar answered Oct 09 '22 23:10

avluis