1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Xamarin.AndroidでTextViewに埋め込んだUrlリンクをタップした時の動作を置き換える

Last updated at Posted at 2018-12-08

#背景と目的

  • Xamarin.Androidで開発しているときに,Html#fromHtmlを使ってURLリンクを埋め込んだときに,Chromeとかではなく,Webviewとかを使って開きたかった.
  • Javaの実装記事は@le_skambaさんの記事 が参考になります.
  • Xamarin.Androidはなかったので備忘録として.

#実装

実装の手順はJavaでの実装とほぼ同じです.

  1. LinkMovementMethodを拡張する
  2. TextViewに拡張したLinkMovementMethodを指定してやる
    手順はこれだけです.

実際のコードは次の通りです

LinkMovementMethodを拡張する

CustomLinkMovementMethod .cs

public class CustomLinkMovementMethod : Android.Text.Method.LinkMovementMethod
{
    public override bool OnTouchEvent(TextView widget, ISpannable buffer, MotionEvent e)
    {
        var action = e.Action;
        if(action == MotionEventActions.Down || action == MotionEventActions.Up)
        {
            int x = (int)e.GetX();
            int y = (int)e.GetY();

            x -= widget.TotalPaddingLeft;
            y -= widget.TotalPaddingTop;

            x += widget.ScrollX;
            y += widget.ScrollX;

            var layout = widget.Layout;
            int line = layout.GetLineForVertical(y);
            int off = layout.GetOffsetForHorizontal(line, x);

            Type type = typeof(ClickableSpan);
            var link = buffer.GetSpans(off, off,  Java.Lang.Class.FromType(type) );

            if(link.Length != 0)
            {
                if(action == MotionEventActions.Up)
                {
                    if(link[0] is URLSpan)
                    {
                        string url = ((URLSpan)link[0]).URL;
                        YourBrowser_Open();//ここで自由に調理してください
                    }
                }
                else  if(action == MotionEventActions.Down)
                {
                    Selection.SetSelection(buffer, buffer.GetSpanStart(link[0]), buffer.GetSpanEnd(link[0]));
                }
                return true;
            }
            else
            {
                Selection.RemoveSelection(buffer);
            }
            
        }
        return base.OnTouchEvent(widget, buffer, e);


    }
}

TextViewのModementMethodに拡張したLinkMovementMethodを指定

text.MovementMethod = new CustomLinkMovementMethod();

ほとんどJavaと同じですが,Java.Lang.Class.FromType(type) あたりは,Xamarin独特な無理矢理さを感じますね....
is で型判定できるのはC#らしく,便利ですね.

あとがき

技術ブログ自体初の投稿となりますので,これでいいのかドキドキしてます.
仕事では,もっぱらJava/Androidの開発がメインです.
趣味ではXamarin.Android,Xamarin.Formsで書くことが多く,まだまだ記事が少ないのが現状かなと感じています.
普及のためにも,足りないと感じる情報があれば投稿していこうと思います.

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?