From 1a1930341895368ae7deed81801edd58a7dd265a Mon Sep 17 00:00:00 2001 From: Floens Date: Tue, 17 Nov 2015 19:14:30 +0100 Subject: [PATCH] Use a TextView for the PostCell comment again Maintaining FastTextView because too much of a mess to maintain because the post comment uses spannables extensively and the caching became too difficult. It is still used for the "n replies" and the date, these have simple requirements. --- .../floens/chan/controller/Controller.java | 4 +- .../NavigationControllerContainerLayout.java | 5 +- .../org/floens/chan/ui/cell/PostCell.java | 94 +++++++++++-------- .../org/floens/chan/ui/text/FastTextView.java | 5 +- .../ui/text/FastTextViewMovementMethod.java | 2 +- Clover/app/src/main/res/layout/cell_post.xml | 4 +- 6 files changed, 68 insertions(+), 46 deletions(-) diff --git a/Clover/app/src/main/java/org/floens/chan/controller/Controller.java b/Clover/app/src/main/java/org/floens/chan/controller/Controller.java index e29e4c26..8a6f9e03 100644 --- a/Clover/app/src/main/java/org/floens/chan/controller/Controller.java +++ b/Clover/app/src/main/java/org/floens/chan/controller/Controller.java @@ -118,7 +118,9 @@ public abstract class Controller { } if (AndroidUtils.removeFromParentView(view)) { - Logger.test(getClass().getSimpleName() + " view removed onDestroy"); + if (LOG_STATES) { + Logger.test(getClass().getSimpleName() + " view removed onDestroy"); + } } } diff --git a/Clover/app/src/main/java/org/floens/chan/controller/ui/NavigationControllerContainerLayout.java b/Clover/app/src/main/java/org/floens/chan/controller/ui/NavigationControllerContainerLayout.java index d8899237..2825fbcf 100644 --- a/Clover/app/src/main/java/org/floens/chan/controller/ui/NavigationControllerContainerLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/controller/ui/NavigationControllerContainerLayout.java @@ -32,6 +32,7 @@ import android.widget.Scroller; import org.floens.chan.controller.Controller; import org.floens.chan.controller.NavigationController; +import org.floens.chan.utils.Time; public class NavigationControllerContainerLayout extends FrameLayout { private NavigationController navigationController; @@ -183,12 +184,12 @@ public class NavigationControllerContainerLayout extends FrameLayout { swipingController = navigationController.getTop(); drawShadow = true; -// long start = Time.startTiming(); + long start = Time.startTiming(); Controller below = getBelowTop(); navigationController.beginSwipeTransition(swipingController, below); -// Time.endTiming("attach", start); + Time.endTiming("attach", start); } float translationX = Math.max(0, event.getX() - swipeStartEvent.getX()); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java index 5c9b5354..8ed47940 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/cell/PostCell.java @@ -36,18 +36,19 @@ import android.text.Spanned; import android.text.TextPaint; import android.text.TextUtils; import android.text.format.DateUtils; +import android.text.method.LinkMovementMethod; import android.text.style.AbsoluteSizeSpan; import android.text.style.BackgroundColorSpan; import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.UnderlineSpan; import android.util.AttributeSet; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; +import android.widget.TextView; import com.android.volley.VolleyError; import com.android.volley.toolbox.ImageLoader; @@ -83,7 +84,7 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin private ThumbnailView thumbnailView; private FastTextView title; private PostIcons icons; - private FastTextView comment; + private TextView comment; private FastTextView replies; private ImageView options; private View divider; @@ -94,6 +95,7 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin private int countrySizePx; private int paddingPx; private boolean threadMode; + private boolean ignoreNextOnClick; private boolean bound = false; private Theme theme; @@ -107,9 +109,15 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin private OnClickListener selfClicked = new OnClickListener() { @Override public void onClick(View v) { - callback.onPostClicked(post); + if (ignoreNextOnClick) { + ignoreNextOnClick = false; + } else { + callback.onPostClicked(post); + } } }; + private PostViewMovementMethod commentMovementMethod = new PostViewMovementMethod(); + private PostViewFastMovementMethod titleMovementMethod = new PostViewFastMovementMethod(); public PostCell(Context context) { super(context); @@ -130,7 +138,7 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin thumbnailView = (ThumbnailView) findViewById(R.id.thumbnail_view); title = (FastTextView) findViewById(R.id.title); icons = (PostIcons) findViewById(R.id.icons); - comment = (FastTextView) findViewById(R.id.comment); + comment = (TextView) findViewById(R.id.comment); replies = (FastTextView) findViewById(R.id.replies); options = (ImageView) findViewById(R.id.options); divider = findViewById(R.id.divider); @@ -397,18 +405,17 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin commentText = post.comment; } - comment.setText(new SpannableString(commentText)); + comment.setText(commentText); comment.setVisibility(isEmpty(commentText) && !post.hasImage ? GONE : VISIBLE); if (commentClickable != threadMode) { commentClickable = threadMode; if (commentClickable) { - PostViewMovementMethod movementMethod = new PostViewMovementMethod(); - comment.setMovementMethod(movementMethod); + comment.setMovementMethod(commentMovementMethod); comment.setOnClickListener(selfClicked); if (noClickable) { - title.setMovementMethod(movementMethod); + title.setMovementMethod(titleMovementMethod); } } else { comment.setOnClickListener(null); @@ -494,17 +501,17 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin * A MovementMethod that searches for PostLinkables.
* See {@link PostLinkable} for more information. */ - private class PostViewMovementMethod implements FastTextViewMovementMethod { + private class PostViewMovementMethod extends LinkMovementMethod { @Override - public boolean onTouchEvent(@NonNull FastTextView widget, @NonNull Spanned buffer, @NonNull Spanned cachedBuffer, @NonNull MotionEvent event) { + public boolean onTouchEvent(@NonNull TextView widget, @NonNull Spannable buffer, @NonNull MotionEvent event) { int action = event.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_DOWN) { int x = (int) event.getX(); int y = (int) event.getY(); - x -= widget.getPaddingLeft(); - y -= widget.getPaddingTop(); + x -= widget.getTotalPaddingLeft(); + y -= widget.getTotalPaddingTop(); x += widget.getScrollX(); y += widget.getScrollY(); @@ -517,45 +524,58 @@ public class PostCell extends LinearLayout implements PostCellInterface, PostLin if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { + ignoreNextOnClick = true; link[0].onClick(widget); - removeBackgroundSpan(widget, cachedBuffer); + buffer.removeSpan(BACKGROUND_SPAN); } else if (action == MotionEvent.ACTION_DOWN && link[0] instanceof PostLinkable) { - int spanStart = buffer.getSpanStart(link[0]); - int spanEnd = buffer.getSpanEnd(link[0]); - - // Set the buffer on the visible buffer, not on the functional buffer - // This is because the visible buffer may be a cached one or may be in use multiple times - if (spanStart <= spanEnd && spanStart >= 0 && spanEnd >= 0 && spanStart <= cachedBuffer.length() && spanEnd <= cachedBuffer.length()) { - showBackgroundSpan(widget, cachedBuffer, spanStart, spanEnd); - } else { - Log.e(TAG, "Could not add the background span because it was out of range!"); - } + buffer.setSpan(BACKGROUND_SPAN, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]), 0); } else if (action == MotionEvent.ACTION_CANCEL) { - removeBackgroundSpan(widget, cachedBuffer); + buffer.removeSpan(BACKGROUND_SPAN); } return true; } else { - removeBackgroundSpan(widget, cachedBuffer); - return false; + buffer.removeSpan(BACKGROUND_SPAN); } } - return false; + return true; } + } - private void showBackgroundSpan(FastTextView widget, Spanned buffer, int start, int end) { - if (buffer instanceof Spannable) { - ((Spannable) buffer).setSpan(BACKGROUND_SPAN, start, end, 0); - widget.invalidate(); - } - } + /** + * A MovementMethod that searches for PostLinkables.
+ * This version is for the {@link FastTextView}.
+ * See {@link PostLinkable} for more information. + */ + private class PostViewFastMovementMethod implements FastTextViewMovementMethod { + @Override + public boolean onTouchEvent(@NonNull FastTextView widget, @NonNull Spanned buffer, @NonNull MotionEvent event) { + int action = event.getActionMasked(); + + if (action == MotionEvent.ACTION_UP) { + int x = (int) event.getX(); + int y = (int) event.getY(); - private void removeBackgroundSpan(FastTextView widget, Spanned buffer) { - if (buffer instanceof Spannable) { - ((Spannable) buffer).removeSpan(BACKGROUND_SPAN); - widget.invalidate(); + x -= widget.getPaddingLeft(); + y -= widget.getPaddingTop(); + + 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 false; } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/text/FastTextView.java b/Clover/app/src/main/java/org/floens/chan/ui/text/FastTextView.java index 7296563d..c2690df6 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/text/FastTextView.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/text/FastTextView.java @@ -32,14 +32,13 @@ import android.view.MotionEvent; import android.view.View; import org.floens.chan.R; -import org.floens.chan.ui.cell.PostCell; import org.floens.chan.utils.Logger; import static org.floens.chan.utils.AndroidUtils.sp; /** * A simple implementation of a TextView that caches the used StaticLayouts for performance.
- * This view was made for {@link PostCell} and may have untested behaviour with other layouts. + * This view was made for {@link org.floens.chan.ui.cell.PostCell} and {@link org.floens.chan.ui.cell.CardPostCell }and may have untested behaviour with other layouts. */ public class FastTextView extends View { private static final String TAG = "FastTextView"; @@ -130,7 +129,7 @@ public class FastTextView extends View { boolean handled = false; if (movementMethod != null && text instanceof Spanned && layout != null && isEnabled()) { - handled |= movementMethod.onTouchEvent(this, (Spanned) text, (Spanned) layout.getText(), event); + handled |= movementMethod.onTouchEvent(this, (Spanned) text, event); } return handled || super.onTouchEvent(event); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/text/FastTextViewMovementMethod.java b/Clover/app/src/main/java/org/floens/chan/ui/text/FastTextViewMovementMethod.java index 705df8f8..80196129 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/text/FastTextViewMovementMethod.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/text/FastTextViewMovementMethod.java @@ -21,5 +21,5 @@ import android.text.Spanned; import android.view.MotionEvent; public interface FastTextViewMovementMethod { - boolean onTouchEvent(FastTextView widget, Spanned buffer, Spanned cachedBuffer, MotionEvent event); + boolean onTouchEvent(FastTextView widget, Spanned buffer, MotionEvent event); } diff --git a/Clover/app/src/main/res/layout/cell_post.xml b/Clover/app/src/main/res/layout/cell_post.xml index 6df46358..0f608785 100644 --- a/Clover/app/src/main/res/layout/cell_post.xml +++ b/Clover/app/src/main/res/layout/cell_post.xml @@ -61,7 +61,7 @@ along with this program. If not, see . android:layout_below="@id/title" android:layout_toRightOf="@id/thumbnail_view" /> - . android:layout_alignWithParentIfMissing="true" android:layout_below="@id/icons" android:layout_toRightOf="@id/thumbnail_view" - app:textColor="?attr/text_color_primary" /> + android:textColor="?attr/text_color_primary" />