Introduce new MovementMethod for text selection and link clicks

This commit is contained in:
Torsten Grote
2016-09-08 13:15:46 -03:00
parent cab667ef6a
commit 7a1003178d
5 changed files with 84 additions and 13 deletions

View File

@@ -10,7 +10,7 @@
android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true">
<!-- Above Focusability attributes prevent automatic scroll-down,
<!-- Above focusability attributes prevent automatic scroll-down,
because body text is selectable -->
<include

View File

@@ -8,6 +8,7 @@ import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -110,16 +111,16 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
}
// post body
Spanned bodyText = getSpanned(item.getBody());
if (listener == null) {
body.setText(getSpanned(item.getBody()));
makeLinksClickable(body);
body.setText(bodyText);
body.setTextIsSelectable(true);
makeLinksClickable(body);
} else {
body.setTextIsSelectable(false);
if (item.getBody().length() > TEASER_LENGTH)
body.setText(getTeaser(ctx, item.getBody()));
else
body.setText(item.getBody());
bodyText = getTeaser(ctx, bodyText);
body.setText(bodyText);
}
// reblog button

View File

@@ -46,7 +46,7 @@ import static android.text.format.DateUtils.WEEK_IN_MILLIS;
public class AndroidUtils {
public static final long MIN_RESOLUTION = MINUTE_IN_MILLIS;
public static final int TEASER_LENGTH = 240;
public static final int TEASER_LENGTH = 320;
// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";
@@ -131,13 +131,13 @@ public class AndroidUtils {
MIN_RESOLUTION, flags).toString();
}
public static SpannableStringBuilder getTeaser(Context ctx, String body) {
public static SpannableStringBuilder getTeaser(Context ctx, Spanned body) {
if (body.length() < TEASER_LENGTH)
throw new IllegalArgumentException(
"String is shorter than TEASER_LENGTH");
SpannableStringBuilder builder =
new SpannableStringBuilder(body.substring(0, TEASER_LENGTH));
new SpannableStringBuilder(body.subSequence(0, TEASER_LENGTH));
String ellipsis = ctx.getString(R.string.ellipsis);
builder.append(ellipsis).append(" ");
@@ -176,7 +176,7 @@ public class AndroidUtils {
ssb.setSpan(cSpan, start, end, 0);
}
v.setText(ssb);
v.setMovementMethod(LinkMovementMethod.getInstance());
v.setMovementMethod(ArticleMovementMethod.getInstance());
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* 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 org.briarproject.android.util;
import android.text.Layout;
import android.text.Spannable;
import android.text.method.ArrowKeyMovementMethod;
import android.text.method.MovementMethod;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.widget.TextView;
public class ArticleMovementMethod extends ArrowKeyMovementMethod {
private static ArticleMovementMethod sInstance;
public static MovementMethod getInstance() {
if (sInstance == null) {
sInstance = new ArticleMovementMethod();
}
return sInstance;
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
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);
ClickableSpan[] link =
buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
link[0].onClick(widget);
}
}
return super.onTouchEvent(widget, buffer, event);
}
}

View File

@@ -42,6 +42,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
@@ -437,7 +438,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
}
b.append("<p>");
if (!StringUtils.isNullOrEmpty(entry.getAuthor())) {
b.append("\n\n-- ").append(clean(entry.getAuthor(), stripAll));
b.append("-- ").append(entry.getAuthor());
}
if (entry.getPublishedDate() != null) {
b.append(" (").append(entry.getPublishedDate().toString())
@@ -484,8 +485,10 @@ class FeedManagerImpl implements FeedManager, Client, EventListener {
private String getPostBody(String text) {
text = clean(text, article);
if (text.length() <= MAX_BLOG_POST_BODY_LENGTH) return text;
else return text.substring(0, MAX_BLOG_POST_BODY_LENGTH);
byte[] textBytes = StringUtils.toUtf8(text);
if (textBytes.length <= MAX_BLOG_POST_BODY_LENGTH)
return text;
return StringUtils.fromUtf8(textBytes, 0, MAX_BLOG_POST_BODY_LENGTH);
}
/**