android – 在WebView中打开URL而不是默认浏览器

android – 在WebView中打开URL而不是默认浏览器,第1张

概述我正在创建简单的Webview应用程序与文本视图上的一些链接,并打开webview而不是默认浏览器中的链接.我的文字视图包含各种不同的URLS,我正在尝试打开我的应用程序的webview中的每个链接. 这里代码: tv.setText("www.google.com www.facebook.com www.yahoo.com");tv.setMovementMethod(LinkMovem 我正在创建简单的WebvIEw应用程序与文本视图上的一些链接,并打开webvIEw而不是默认浏览器中的链接.我的文字视图包含各种不同的URLS,我正在尝试打开我的应用程序的webvIEw中的每个链接.

这里代码:

tv.setText("www.Google.com  www.facebook.com  www.yahoo.com");tv.setMovementMethod(linkMovementMethod.getInstance());;tv.setText(HTML.fromHTML(tv.getText().toString()));linkify.addlinks(tv,linkify.WEB_URLS);WebVIEwClIEnt yourWebClIEnt = new WebVIEwClIEnt()       {           // OverrIDe page so it's load on my vIEw only           @OverrIDe           public boolean shouldOverrIDeUrlLoading(WebVIEw  vIEw,String  url)           {            // This line we let me load only pages insIDe FirstdroID Webpage            if ( url.contains("www") == true )               // Load new URL Don't overrIDe URL link               return false;            // Return true to overrIDe url loading (In this case do nothing).            return true;           }       };wv.getSettings().setJavaScriptEnabled(true);       wv.getSettings().setSupportZoom(true);          wv.getSettings().setBuiltInZoomControls(true);     wv.setWebVIEwClIEnt(yourWebClIEnt);    // Load URL    wv.loadUrl(url);

已经尝试了this,this和this的例子,但是无法解决我在textvIEw中的多个链接的问题.请帮我解决这个问题.谢谢你的帮助.

编辑
我的TextvIEw包含字符串:

hello xyz some more statements... xyz.com/abc/hello xyz some more statements... xyz.com/abc/hello xyz some more statements... xyz.com/abc/hello xyz some more statements... xyz.com/abc/

像这样它有很多字符串和多个URL

解决方法 以下问题需要解决:

>链接TextVIEw
>找到一种方式来收听TextVIEw中的链接
>获取点击的链接的URL,并将其加载到WebVIEw中
>可选:使TextVIEw可点击,而不会失去选择文本的能力
>可选:在TextVIEw中处理格式化的文本(不同的文字大小和样式)

#1链接TextVIEw

这是最简单的问题,你已经解决了这个问题.我建议这样做:

String text = "These are some sample links:\nwww.Google.com\nwww.facebook.com\nwww.yahoo.com";Spannable spannable = new SpannableString( HTML.fromHTML(text) );linkify.addlinks(spannable,linkify.WEB_URLS);

我在这里使用一个Spannable来解决问题#2.

#2#3收听链接的点击并在WebVIEw中打开它们

要查看链接何时被点击并检索我们必须打开的URL,我们用linkSpan替换TextVIEw中的所有URLSpans(这就是为什么我们需要一个Spannable):

URLSpan[] spans = spannable.getSpans(0,spannable.length(),URLSpan.class);for (URLSpan urlSpan : spans) {    linkSpan linkSpan = new linkSpan(urlSpan.getURL());    int spanStart = spannable.getSpanStart(urlSpan);    int spanEnd = spannable.getSpanEnd(urlSpan);    spannable.setSpan(linkSpan,spanStart,spanEnd,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);    spannable.removeSpan(urlSpan);}

我们的linkSpan只是抓住点击的网址,并在WebVIEw中打开它:

private class linkSpan extends URLSpan {    private linkSpan(String url) {        super(url);    }    @OverrIDe    public voID onClick(VIEw vIEw) {        String url = getURL();        if (mWebVIEw != null && url != null) {            mWebVIEw.loadUrl(url);        }    }}

现在显然,我们必须在实例变量中保留对WebVIEw的引用,以使其工作.为了使这个答案尽可能的短,我选择将linkSpan定义为内部类,但我建议将其定义为顶级.注册一个监听器,或者将WebVIEw作为参数传递给构造函数.

没有将MovementMethod设置为linkMovementMethod,TextVIEw将不会打开链接:

tv.setMovementMethod(linkMovementMethod.getInstance());tv.setText(spannable,BufferType.SPANNABLE);

最后但并非最不重要的是我们确保WebVIEw不启动浏览器,而是加载该应用程序中的页面:

mWebVIEw.setWebVIEwClIEnt(new WebVIEwClIEnt() {    @OverrIDe    public boolean shouldOverrIDeUrlLoading(WebVIEw vIEw,String url) {        // we handle the url ourselves if it's a network url (http / https)         return ! URLUtil.isNetworkUrl(url);    }});

#4可点击并选择TextVIEw#5格式的文本

如果MovementMethod设置为linkMovementMethod,您可以单击链接,但是您不能再选择文本(您需要使用ArrowKeyMovementMethod).为了解决这个问题,我创建了一个自定义的MoveMethod类,它继承自ArrowKeyMovementMethod,并添加了点击链接的功能.最重要的是可以处理格式化的文本.因此,如果您决定在TextVIEw中使用不同的字体大小和样式,则以下MovementMethod将被覆盖(与EditTexts一起使用):

/** * ArrowKeyMovementMethod does support selection of text but not the clicking of links. * linkMovementMethod does support clicking of links but not the selection of text. * This class adds the link clicking to the ArrowKeyMovementMethod. * We basically take the linkMovementMethod ontouchEvent code and remove the line *      Selection.removeSelection(buffer); * which deselects all text when no link was found. */public class EnhancedlinkMovementMethod extends ArrowKeyMovementMethod {    private static EnhancedlinkMovementMethod sInstance;    private static Rect slineBounds = new Rect();    public static MovementMethod getInstance() {        if (sInstance == null) {            sInstance = new EnhancedlinkMovementMethod();        }        return sInstance;    }    @OverrIDe    public boolean ontouchEvent(TextVIEw Widget,Spannable buffer,MotionEvent event) {        int action = event.getAction();        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {            int index = getCharIndexAt(Widget,event);            if (index != -1) {                ClickableSpan[] link = buffer.getSpans(index,index,ClickableSpan.class);                if (link.length != 0) {                    if (action == MotionEvent.ACTION_UP) {                        link[0].onClick(Widget);                    }                    else if (action == MotionEvent.ACTION_DOWN) {                        Selection.setSelection(buffer,buffer.getSpanStart(link[0]),buffer.getSpanEnd(link[0]));                    }                    return true;                }            }            /*else {                Selection.removeSelection(buffer);            }*/        }        return super.ontouchEvent(Widget,buffer,event);    }    private int getCharIndexAt(TextVIEw textVIEw,MotionEvent event) {        // get coordinates        int x = (int) event.getX();        int y = (int) event.getY();        x -= textVIEw.getTotalpaddingleft();        y -= textVIEw.getTotalpaddingtop();        x += textVIEw.getScrollX();        y += textVIEw.getScrollY();        /*         * fail-fast check of the line bound.         * If we're not within the line bound no character was touched         */        Layout layout = textVIEw.getLayout();        int line = layout.getlineForVertical(y);        synchronized (slineBounds) {            layout.getlineBounds(line,slineBounds);            if (! slineBounds.contains(x,y)) {                return -1;            }        }        // retrIEve line text        Spanned text = (Spanned) textVIEw.getText();        int linestart = layout.getlinestart(line);        int lineEnd = layout.getlineEnd(line);        int lineLength = lineEnd - linestart;        if (lineLength == 0) {            return -1;        }        Spanned lineText = (Spanned) text.subSequence(linestart,lineEnd);        // compute leading margin and subtract it from the x coordinate        int margin = 0;        LeadingmarginSpan[] marginSpans = lineText.getSpans(0,lineLength,LeadingmarginSpan.class);        if (marginSpans != null) {            for (LeadingmarginSpan span : marginSpans) {                margin += span.getLeadingmargin(true);            }        }        x -= margin;        // retrIEve text wIDths        float[] wIDths = new float[lineLength];        TextPaint paint = textVIEw.getPaint();        paint.getTextWIDths(lineText,wIDths);        // scale text wIDths by relative Font size (absolute size / default size)        final float defaultSize = textVIEw.getTextSize();        float scaleFactor = 1f;        absoluteSizeSpan[] absspans = lineText.getSpans(0,absoluteSizeSpan.class);        if (absspans != null) {            for (absoluteSizeSpan span : absspans) {                int spanStart = lineText.getSpanStart(span);                int spanEnd = lineText.getSpanEnd(span);                scaleFactor = span.getSize() / defaultSize;                int start = Math.max(linestart,spanStart);                int end = Math.min(lineEnd,spanEnd);                for (int i = start; i < end; i++) {                    wIDths[i] *= scaleFactor;                }            }        }        // find index of touched character        float startChar = 0;        float endChar = 0;        for (int i = 0; i < lineLength; i++) {            startChar = endChar;            endChar += wIDths[i];            if (endChar >= x) {                // which "end" is closer to x,the start or the end of the character?                int index = linestart + (x - startChar < endChar - x ? i : i + 1);                //Logger.e(Logger.LOG_TAG,"Found character: " + (text.length()>index ? text.charat(index) : ""));                return index;            }        }        return -1;    }}

完成活动代码

以下是我使用的完整示例活动代码.它应该完全符合你想要的它使用我的EnhandedMovementMethod,但您可以使用一个简单的linkMovementMethod(具有前面提到的缺点).

public class linkTestActivity extends Activity {    private WebVIEw mWebVIEw;    @Suppresslint("SetJavaScriptEnabled")    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.activity_main);        mWebVIEw = (WebVIEw) findVIEwByID(R.ID.webVIEw);        TextVIEw tv = (TextVIEw) findVIEwByID(R.ID.textVIEw);        String text = "These are some sample links:\nwww.Google.com\nwww.facebook.com\nwww.yahoo.com";        // linkify the TextVIEw        Spannable spannable = new SpannableString( HTML.fromHTML(text) );        linkify.addlinks(spannable,linkify.WEB_URLS);        // Replace each URLSpan by a linkSpan        URLSpan[] spans = spannable.getSpans(0,URLSpan.class);        for (URLSpan urlSpan : spans) {            linkSpan linkSpan = new linkSpan(urlSpan.getURL());            int spanStart = spannable.getSpanStart(urlSpan);            int spanEnd = spannable.getSpanEnd(urlSpan);            spannable.setSpan(linkSpan,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);            spannable.removeSpan(urlSpan);        }        // Make sure the TextVIEw supports clicking on links        tv.setMovementMethod(EnhancedlinkMovementMethod.getInstance());        tv.setText(spannable,BufferType.SPANNABLE);        // Make sure we handle clicked links ourselves        mWebVIEw.setWebVIEwClIEnt(new WebVIEwClIEnt() {            @OverrIDe            public boolean shouldOverrIDeUrlLoading(WebVIEw vIEw,String url) {                // we handle the url ourselves if it's a network url (http / https)                 return ! URLUtil.isNetworkUrl(url);            }        });        mWebVIEw.getSettings().setJavaScriptEnabled(true);           mWebVIEw.getSettings().setSupportZoom(true);              mWebVIEw.getSettings().setBuiltInZoomControls(true);    }    private class linkSpan extends URLSpan {        private linkSpan(String url) {            super(url);        }        @OverrIDe        public voID onClick(VIEw vIEw) {            String url = getURL();            if (mWebVIEw != null && url != null) {                mWebVIEw.loadUrl(url);            }        }    }}
总结

以上是内存溢出为你收集整理的android – 在WebView中打开URL而不是默认浏览器全部内容,希望文章能够帮你解决android – 在WebView中打开URL而不是默认浏览器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1130906.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存