Skip to content

Instantly share code, notes, and snippets.

@adamsp
Last active December 26, 2015 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamsp/7189623 to your computer and use it in GitHub Desktop.
Save adamsp/7189623 to your computer and use it in GitHub Desktop.
How to create clickable links from TextViews within a DreamService.
/**
* Copyright 2013 Adam Speakman
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nz.net.speakman.android.example;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.Browser;
import android.service.dreams.DreamService;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
/**
* A LinkMovementMethod extension that handles clicking on links in a DreamService.
*/
public class DreamLinkMovementMethod extends LinkMovementMethod {
private DreamService mDream;
public DreamLinkMovementMethod(DreamService dream) {
mDream = dream;
}
// Sourced from https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/text/method/LinkMovementMethod.java
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
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);
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
onClick(link[0], 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);
}
// Behaviour sourced from: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/text/style/URLSpan.java
private void onClick(ClickableSpan link, View widget) {
if (link instanceof URLSpan) {
Uri uri = Uri.parse(((URLSpan) link).getURL());
Context context = widget.getContext();
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
String packageName = context.getPackageName();
intent.putExtra(Browser.EXTRA_APPLICATION_ID, packageName);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
mDream.finish();
} else {
link.onClick(widget);
}
}
}
LinkMovementMethod lmm = new DreamLinkMovementMethod(mDream);
TextView someTextView = (TextView)findViewById(R.id.tweet_author_image);
someTextView.setMovementMethod(lmm);
someTextView.setText(Html.fromHtml("This is a <a href=\"http://www.google.com\">Clickable Link</a>, "
+ " accessible from a <a href=\"http://developer.android.com/reference/android/service/dreams/DreamService.html\">Dream Service</a>."));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment