2

To give context to my problem, think Twitter: There is a list of tweets. You can click any part of the Tweet to view the Tweet singularly. If an account is tagged in the Tweet with an @ then if you click on the account name, you are directed to the account's profile.

This is almost exactly what I'm trying to do in my app. I have a ListView of custom layouts I'll call wall posts. My wall posts include a TextView, and if a user is tagged in this text view with an @, e.g. @username, then I make @username spannable and set an onClickListener for that text. In my implementation I know that the spannable string was successfully set because the text is correctly underlined and blue by default. The problem is that when I click on the text, my click is treated like I clicked on the wall post, and the user who posted the wall post's account is opened for viewing, not the tagged user.

So in conclusion, with that context given, my question is: how can I make spannable string clicks override the clicks of the ListView items that the spannable strings are contained in? I still need the ListView OnItemClickListener to handle clicks on ListView items when not clicking on the spannable string. Thanks for any help, I really appreciate it!


P.S. I have looked at similar questions such as this one, which has no answer, and this one, whose suggestion to add this line here:

txtViewTwo.setMovementMethod(LinkMovementMethod.getInstance());

makes my spannable string clickable, but nullifies clicks on ListView items.

Community
  • 1
  • 1
ThePartyTurtle
  • 2,276
  • 2
  • 18
  • 32
  • I'm unable to try and confirm this right now but I believe if you implement the `OnItemClickListener` on a `ListView` that consumes the touch event then and there. You could confirm this by commenting `setOnItemClickListener` and clicking on a spannable string. It should work if your coding is right. Then in that case you should move your code to detect "clicked on wallpost" inside the adapter. Similar to how you assign an `OnClickListener` to the spannable string. – JanithaR Aug 19 '15 at 03:36

2 Answers2

1

the following works for me

textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setFocusable(false);
textview.setFocusableInTouchMode(false);

EDIT:

also should read ListView: TextView with LinkMovementMethod makes list item unclickable? for a workaround to make clicks on parts of the TextView that are non spans go through to the parent View

Community
  • 1
  • 1
SteelBytes
  • 6,905
  • 1
  • 26
  • 28
  • Although I've since changed the implementation, I've disabled list item clicks and decided to assign individual click listeners to each view I want to have a clickable function, I'll check this out and check back in! This could still save some folks a huge headache. – ThePartyTurtle Aug 19 '15 at 17:12
0

Try This it's working for me

 class MyClickableSpan extends ClickableSpan {// extend ClickableSpan

         Object object;
         String title;
         private boolean mIsPressed;
         private int mPressedBackgroundColor = 0xffeeeeee;
         private int mNormalTextColor;
         private int mPressedTextColor;

     public MyClickableSpan(Object o) {
         super();
         object = o;
     }

     public MyClickableSpan(Object o, String title) {
         super();
         object = o;
         this.title = title;
     }

         @Override
         public void onClick(View widget) {


         }

         @Override
         public void updateDrawState(TextPaint ds) { // In here Customise your state colors
             super.updateDrawState(ds);
             ds.setUnderlineText(false); // set to false to remove underline
             ds.setColor(Color.parseColor("#363636")); //            ds.setColor(mIsPressed ? mPressedTextColor : mNormalTextColor);
             ds.bgColor = mIsPressed ? mPressedBackgroundColor : 0xffffffff;
         }

         public void setPressed(boolean isSelected) {
             mIsPressed = isSelected;
         }


    }

public class MovementMethod extends LinkMovementMethod {
        private MyClickableSpan mPressedSpan;

        @Override
        public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                mPressedSpan = getPressedSpan(textView, spannable, event);
                if (mPressedSpan != null) {
                    mPressedSpan.setPressed(true);
                    Selection.setSelection(spannable, spannable.getSpanStart(mPressedSpan),
                            spannable.getSpanEnd(mPressedSpan));

                }
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                MyClickableSpan touchedSpan = getPressedSpan(textView, spannable, event);
                if (mPressedSpan != null && touchedSpan != mPressedSpan) {
                    mPressedSpan.setPressed(false);
                    mPressedSpan = null;
                    Selection.removeSelection(spannable);
                }
            } else {
                if (mPressedSpan != null) {
                    mPressedSpan.setPressed(false);
                    super.onTouchEvent(textView, spannable, event);
                }
                mPressedSpan = null;
                Selection.removeSelection(spannable);
            }
            return true;
}

    public SpannableStringBuilder appendClickableText(Object o, SpannableStringBuilder sb, String text) {
    //        SpannableStringBuilder sb = new SpannableStringBuilder();
            StyleSpan b = new StyleSpan(android.graphics.Typeface.BOLD);
            sb.append(text);
            MyClickableSpan clickableSpan = new MyClickableSpan(o);

            sb.setSpan(clickableSpan, sb.length() - text.length(), sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            sb.setSpan(b, sb.length() - text.length(), sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            try {
                if (o instanceof User) {
                    if (((User) o).isPure()) {
                        final ForegroundColorSpan fcs = new ForegroundColorSpan(Color.parseColor(context.getString(R.color.pure_gold)));
                        sb.setSpan(fcs, 0, user.getName().length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                }
            } catch (Exception ignored) {

            }
}
Master Fathi
  • 349
  • 1
  • 9
  • 19