Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle HTML text links in current activity

In my UI I have a list of names which I have displayed using Html.fromHtml() due to the way the names should be highlighted (see pic, the red names).

Under the names I have a ScrollView (see pic, the grey bit). I would like to be able to scroll to a certain part of the scrollview when a name is pressed.

enter image description here

So I sort of have several pieces to solve here:

  1. Make each name clickable individually
  2. Let my current activity handle the click
  3. Not underline the name

OR 4. Solve the text wrapping layout using individual textviews

I know the best thing to do would be to create individual textviews for each name BUT if I do that I lose the text wrapping as seen in the picture.

Thanks for your time.

Edit: I found this Link but it uses an intent so it's not quite the same, I don't want another activity to handle the click, just the current one.

like image 335
C0deAttack Avatar asked Sep 13 '11 22:09

C0deAttack


1 Answers

This is how I've added onClick actions to particular words in a string of text.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff">

    <TextView 
        android:id="@+id/mytextview1"
        android:textColor="#000000"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp" />

</LinearLayout>

Main activity:

public class HtmlTextLinkTestActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        TextView tv = (TextView) findViewById(R.id.mytextview1);
        tv.setText("Whale and Lion");

        clickify(tv, "Whale", new ClickSpan.OnClickListener() {
            @Override
            public void onClick() {
                Toast.makeText(HtmlTextLinkTestActivity.this, "Whale was clicked!", Toast.LENGTH_SHORT).show();
            }
        });

        clickify(tv, "Lion", new ClickSpan.OnClickListener() {
            @Override
            public void onClick() {
                Toast.makeText(HtmlTextLinkTestActivity.this, "Lion was clicked!", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public static void clickify(TextView view, final String clickableText,  final ClickSpan.OnClickListener listener) {
        CharSequence text = view.getText();
        String string = text.toString();
        ClickSpan span = new ClickSpan(listener);

        int start = string.indexOf(clickableText);
        int end = start + clickableText.length();
        if (start == -1) return;

        if (text instanceof Spannable) {
            ((Spannable)text).setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            SpannableString s = SpannableString.valueOf(text);
            s.setSpan(span, start, end, Spanned.SPAN_MARK_MARK);
            view.setText(s);
        }

        MovementMethod m = view.getMovementMethod();
        if ((m == null) || !(m instanceof LinkMovementMethod)) {
            view.setMovementMethod(LinkMovementMethod.getInstance());
        }
    }
}

class ClickSpan extends ClickableSpan {

    private OnClickListener mListener;

    public ClickSpan(OnClickListener listener) {
        mListener = listener;
    }

    @Override
    public void onClick(View widget) {
       if (mListener != null) mListener.onClick();
    }

    public interface OnClickListener {
        void onClick();
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        ds.setColor(0xff0000ff); // remove this if you don't want to want to override the textView's color if you specified it in main.xml
    }
}
like image 195
C0deAttack Avatar answered Oct 18 '22 22:10

C0deAttack