aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2016-09-17 11:25:39 +0200
committerChristian Schneppe <christian@pix-art.de>2016-09-17 11:25:39 +0200
commit0aea51fc3da3b534b520511b437a7c435cab530b (patch)
treeeb20e0d5ca3817d46231f82ebd84e083bd3de54e /src/main
parent93552c34f80607b70bed64d5d626575c007823fd (diff)
Allow text selection with multiple links in message
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java53
-rw-r--r--src/main/java/de/pixart/messenger/ui/widget/ClickableMovementMethod.java42
2 files changed, 57 insertions, 38 deletions
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
index 0ce332887..5e14db91e 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
@@ -16,6 +16,7 @@ import android.os.Build;
import android.support.v4.content.FileProvider;
import android.text.Spannable;
import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
@@ -56,6 +57,7 @@ import de.pixart.messenger.entities.Message.FileParams;
import de.pixart.messenger.entities.Transferable;
import de.pixart.messenger.ui.ConversationActivity;
import de.pixart.messenger.ui.ShowFullscreenMessageActivity;
+import de.pixart.messenger.ui.widget.ClickableMovementMethod;
import de.pixart.messenger.utils.CryptoHelper;
import de.pixart.messenger.utils.GeoHelper;
import de.pixart.messenger.utils.UIHelper;
@@ -323,7 +325,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
if (body.length() > Config.MAX_DISPLAY_MESSAGE_CHARS) {
body = body.substring(0, Config.MAX_DISPLAY_MESSAGE_CHARS)+"\u2026";
}
- final SpannableString formattedBody = new SpannableString(body);
+ Spannable formattedBody = new SpannableString(body);
int i = body.indexOf(Message.MERGE_SEPARATOR);
while(i >= 0) {
final int end = i + Message.MERGE_SEPARATOR.length();
@@ -332,12 +334,8 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
if (message.getType() != Message.TYPE_PRIVATE) {
if (message.hasMeCommand()) {
- final Spannable span = new SpannableString(formattedBody);
- span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- viewHolder.messageBody.setText(span);
- } else {
- viewHolder.messageBody.setText(formattedBody);
+ formattedBody.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else {
String privateMarker;
@@ -353,46 +351,25 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
privateMarker = activity.getString(R.string.private_message_to, to);
}
- final Spannable span = new SpannableString(privateMarker + " "
- + formattedBody);
- span.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground,false)), 0, privateMarker
+ formattedBody = new SpannableStringBuilder().append(privateMarker).append(' ').append(formattedBody);
+ formattedBody.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground,false)), 0, privateMarker
.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- span.setSpan(new StyleSpan(Typeface.BOLD), 0,
+ formattedBody.setSpan(new StyleSpan(Typeface.BOLD), 0,
privateMarker.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (message.hasMeCommand()) {
- span.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarker.length() + 1,
+ formattedBody.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarker.length() + 1,
privateMarker.length() + 1 + nick.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
- viewHolder.messageBody.setText(span);
- }
- int urlCount = 0;
- final Matcher matcher = Patterns.WEB_URL.matcher(body);
- int beginWebURL = Integer.MAX_VALUE;
- int endWebURL = 0;
- while (matcher.find()) {
- MatchResult result = matcher.toMatchResult();
- beginWebURL = result.start();
- endWebURL = result.end();
- urlCount++;
- }
- final Matcher geoMatcher = GeoHelper.GEO_URI.matcher(body);
- while (geoMatcher.find()) {
- urlCount++;
- }
- final Matcher xmppMatcher = XMPP_PATTERN.matcher(body);
- while (xmppMatcher.find()) {
- MatchResult result = xmppMatcher.toMatchResult();
- if (beginWebURL < result.start() || endWebURL > result.end()) {
- urlCount++;
- }
}
- viewHolder.messageBody.setTextIsSelectable(urlCount <= 1);
+ Linkify.addLinks(formattedBody, Linkify.WEB_URLS);
+ Linkify.addLinks(formattedBody, XMPP_PATTERN, "xmpp");
+ Linkify.addLinks(formattedBody, GeoHelper.GEO_URI, "geo");
viewHolder.messageBody.setAutoLinkMask(0);
- Linkify.addLinks(viewHolder.messageBody, Linkify.WEB_URLS);
- Linkify.addLinks(viewHolder.messageBody, XMPP_PATTERN, "xmpp");
- Linkify.addLinks(viewHolder.messageBody, GeoHelper.GEO_URI, "geo");
+ viewHolder.messageBody.setText(formattedBody);
+ viewHolder.messageBody.setTextIsSelectable(true);
+ viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance());
} else {
viewHolder.messageBody.setText("");
viewHolder.messageBody.setTextIsSelectable(false);
diff --git a/src/main/java/de/pixart/messenger/ui/widget/ClickableMovementMethod.java b/src/main/java/de/pixart/messenger/ui/widget/ClickableMovementMethod.java
new file mode 100644
index 000000000..dbf88f1d7
--- /dev/null
+++ b/src/main/java/de/pixart/messenger/ui/widget/ClickableMovementMethod.java
@@ -0,0 +1,42 @@
+package de.pixart.messenger.ui.widget;
+
+import android.text.Layout;
+import android.text.Spannable;
+import android.text.method.ArrowKeyMovementMethod;
+import android.text.style.ClickableSpan;
+import android.view.MotionEvent;
+import android.widget.TextView;
+
+public class ClickableMovementMethod extends ArrowKeyMovementMethod {
+
+ @Override
+ public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
+ // Just copied from android.text.method.LinkMovementMethod
+ if (event.getAction() == 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);
+ ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
+ if (link.length != 0) {
+ link[0].onClick(widget);
+ return true;
+ }
+ }
+ return super.onTouchEvent(widget, buffer, event);
+ }
+
+ public static ClickableMovementMethod getInstance() {
+ if (sInstance == null) {
+ sInstance = new ClickableMovementMethod();
+ }
+ return sInstance;
+ }
+
+ private static ClickableMovementMethod sInstance;
+} \ No newline at end of file