handle textview link click in my android app

前端 未结 12 904
迷失自我
迷失自我 2020-11-22 04:33

I\'m currently rendering HTML input in a TextView like so:

tv.setText(Html.fromHtml(\"test\"));

The HTML b

相关标签:
12条回答
  • 2020-11-22 04:50

    Coming at this almost a year later, there's a different manner in which I solved my particular problem. Since I wanted the link to be handled by my own app, there is a solution that is a bit simpler.

    Besides the default intent filter, I simply let my target activity listen to ACTION_VIEW intents, and specifically, those with the scheme com.package.name

    <intent-filter>
        <category android:name="android.intent.category.DEFAULT" />
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="com.package.name" />  
    </intent-filter>
    

    This means that links starting with com.package.name:// will be handled by my activity.

    So all I have to do is construct a URL that contains the information I want to convey:

    com.package.name://action-to-perform/id-that-might-be-needed/
    

    In my target activity, I can retrieve this address:

    Uri data = getIntent().getData();
    

    In my example, I could simply check data for null values, because when ever it isn't null, I'll know it was invoked by means of such a link. From there, I extract the instructions I need from the url to be able to display the appropriate data.

    0 讨论(0)
  • 2020-11-22 04:54

    its very simple add this line to your code:

    tv.setMovementMethod(LinkMovementMethod.getInstance());
    
    0 讨论(0)
  • 2020-11-22 04:56

    I changed the TextView's color to blue by using for example:

    android:textColor="#3399FF"
    

    in the xml file. How to make it underlined is explained here.

    Then use its onClick property to specify a method (I'm guessing you could call setOnClickListener(this) as another way), e.g.:

    myTextView.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        doSomething();
    }
    });
    

    In that method, I can do whatever I want as normal, such as launch an intent. Note that you still have to do the normal myTextView.setMovementMethod(LinkMovementMethod.getInstance()); thing, like in your acitivity's onCreate() method.

    0 讨论(0)
  • 2020-11-22 04:59

    Example: Suppose you have set some text in textview and you want to provide a link on a particular text expression: "Click on #facebook will take you to facebook.com"

    In layout xml:

    <TextView
                android:id="@+id/testtext"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
    

    In Activity:

    String text  =  "Click on #facebook will take you to facebook.com";
    tv.setText(text);
    Pattern tagMatcher = Pattern.compile("[#]+[A-Za-z0-9-_]+\\b");
    String newActivityURL = "content://ankit.testactivity/";
    Linkify.addLinks(tv, tagMatcher, newActivityURL);
    

    Also create one tag provider as:

    public class TagProvider extends ContentProvider {
    
        @Override
        public int delete(Uri arg0, String arg1, String[] arg2) {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public String getType(Uri arg0) {
            return "vnd.android.cursor.item/vnd.cc.tag";
        }
    
        @Override
        public Uri insert(Uri arg0, ContentValues arg1) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public boolean onCreate() {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
                            String arg4) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
            // TODO Auto-generated method stub
            return 0;
        }
    
    }
    

    In manifest file make as entry for provider and test activity as:

    <provider
        android:name="ankit.TagProvider"
        android:authorities="ankit.testactivity" />
    
    <activity android:name=".TestActivity"
        android:label = "@string/app_name">
        <intent-filter >
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="vnd.android.cursor.item/vnd.cc.tag" />
        </intent-filter>
    </activity>
    

    Now when you click on #facebook, it will invoke testactivtiy. And in test activity you can get the data as:

    Uri uri = getIntent().getData();
    
    0 讨论(0)
  • 2020-11-22 05:00

    if there are multiple links in the text view . For example textview has "https://" and "tel no" we can customise the LinkMovement method and handle clicks for words based on a pattern. Attached is the customised Link Movement Method.

    public class CustomLinkMovementMethod extends LinkMovementMethod
    {
    
    private static Context movementContext;
    
    private static CustomLinkMovementMethod linkMovementMethod = new CustomLinkMovementMethod();
    
    public boolean onTouchEvent(android.widget.TextView widget, android.text.Spannable buffer, android.view.MotionEvent event)
    {
        int action = event.getAction();
    
        if (action == MotionEvent.ACTION_UP)
        {
            int x = (int) event.getX();
            int y = (int) event.getY();
    
            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();
    
            x += widget.getScrollX();
            y += widget.getScrollY();
    
            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);
    
            URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
            if (link.length != 0)
            {
                String url = link[0].getURL();
                if (url.startsWith("https"))
                {
                    Log.d("Link", url);
                    Toast.makeText(movementContext, "Link was clicked", Toast.LENGTH_LONG).show();
                } else if (url.startsWith("tel"))
                {
                    Log.d("Link", url);
                    Toast.makeText(movementContext, "Tel was clicked", Toast.LENGTH_LONG).show();
                } else if (url.startsWith("mailto"))
                {
                    Log.d("Link", url);
                    Toast.makeText(movementContext, "Mail link was clicked", Toast.LENGTH_LONG).show();
                }
                return true;
            }
        }
    
        return super.onTouchEvent(widget, buffer, event);
    }
    
    public static android.text.method.MovementMethod getInstance(Context c)
    {
        movementContext = c;
        return linkMovementMethod;
    }
    

    This should be called from the textview in the following manner:

    textViewObject.setMovementMethod(CustomLinkMovementMethod.getInstance(context));
    
    0 讨论(0)
  • 2020-11-22 05:00
    public static void setTextViewFromHtmlWithLinkClickable(TextView textView, String text) {
        Spanned result;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            result = Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY);
        } else {
            result = Html.fromHtml(text);
        }
        textView.setText(result);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
    }
    
    0 讨论(0)
提交回复
热议问题