2

行。这些是我的问题。

  1. 我需要使用正则表达式来归档除字母之外的所有内容,然后我需要将找到的单词包含在 $word 标记中。有了这个 str = str.replaceAll(pattern, "$0");。现在我正在过滤所有正确的元素(标点符号、数字等),但它将每个单词中的每个字母都包含在 a 标签中,而不是单词中。那么如何使用正则表达式将字母组合成一个单词呢?

from "(a tag open)t(a close)(a tag open)h(a close)(a tag open)i(a close)(a tag open)s(a close) (a tag open)i(a close)(a tag open)s(a close) (a tag open)w(a close)(a tag open)r(a close)(a tag open)o(a close)(a tag open)n(a关闭)(标签打开)g(关闭)“;

到 :

"(a tag open)this(a close) (a tag open) is(a close) (a tag open)right(a close)";

然后我让它们可点击,我需要捕捉点击事件并在点击的单词上获取屏幕上的位置,因为我想使用点击的事件使工具提示显示在点击的单词下方。感谢您的帮助。

公共类 MainActivity 扩展 Activity {

public String text = "This is just a sentence to test you. 23 this is another number23!g?";
public TextView tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    text = explode(text);

    tv = (TextView) findViewById(R.id.tv1);

    tv.setLinksClickable(true);
    tv.setMovementMethod(LinkMovementMethod.getInstance());

    Spanned article = Html.fromHtml(text, null, null);
    setHTML(article);
}


public void setHTML(Spanned html) {
      SpannableString message = new SpannableString(html.toString());
      Object[] spans = html.getSpans(0, html.length(), Object.class);
      for (Object span : spans) {
         int start = html.getSpanStart(span);
         int end = html.getSpanEnd(span);
         int flags = html.getSpanFlags(span);
         if (span instanceof URLSpan) {
            URLSpan urlSpan = (URLSpan) span;
            span = new CallbackSpan(urlSpan.getURL());
         }
         message.setSpan(span, start, end, flags);
      }
      tv.setText(message);
   }
    public String explode(String str){  
      String pattern = "([a-zA-Z])";
      str = str.replaceAll(pattern, "<a href=\"$0\">$0</a>");
      return str;
    }

   private final class CallbackSpan extends ClickableSpan {

      private String m_data;
      private String url_main;

      public CallbackSpan(String url) {
         m_data = url.substring(0);
         url_main = url;

      }

      public void onClick(View view) {

          TextView item = (TextView)findViewById(R.id.tv2);
          item.setText(url_main + " was clicked.");
          Log.d("item", url_main);
      }
   }

}

4

2 回答 2

8

最新代码,请参阅链接形式github

message.setSpan(span, start, end, flags);

您需要在设置新跨度之前删除原始跨度。请看下面
ClickableSpan 的 onClick() 不适用于 URLSpan?

编辑您可以通过以下
方式捕获任何跨度点击事件extends LinkMovementMethod

    import android.os.Handler;
import android.os.Message;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.TextView;

import java.lang.ref.WeakReference;

public class LinkMovementMethodExt extends LinkMovementMethod {
    public static final int LinkMovementMethod_Down = 1001;
    public static final int LinkMovementMethod_Up = 2002;
    private static LinkMovementMethod sInstance;
    private Class mSpanClass = null;
    private WeakReference<Handler> mWeakReference = null;

    public static MovementMethod getInstance(Handler handler, Class spanClass) {
        if (sInstance == null) {
            sInstance = new LinkMovementMethodExt();
            ((LinkMovementMethodExt) sInstance).mWeakReference = new WeakReference<>(handler);
            ((LinkMovementMethodExt) sInstance).mSpanClass = spanClass;
        }
        return sInstance;
    }

    @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);
            /**
             * get you interest span
             */
            Object[] spans = buffer.getSpans(off, off, mSpanClass);
            if (spans.length != 0) {
                if (action == MotionEvent.ACTION_DOWN) {
                    Selection.setSelection(buffer, buffer.getSpanStart(spans[0]), buffer.getSpanEnd(spans[0]));
                    MessageSpan obj = new MessageSpan();
                    obj.setObj(spans);
                    obj.setView(widget);
                    Handler handler = mWeakReference.get();
                    if (handler != null) {
                        Message message = handler.obtainMessage();
                        message.obj = obj;
                        message.what = LinkMovementMethod_Down;
                        message.sendToTarget();
                        return true;
                    }
                    return false;
                } else if (action == MotionEvent.ACTION_UP) {
                    Handler handler = mWeakReference.get();
                    if (handler != null) {
                        MessageSpan obj = new MessageSpan();
                        obj.setView(widget);
                        Message message = handler.obtainMessage();
                        message.obj = obj;
                        message.what = LinkMovementMethod_Up;
                        message.sendToTarget();
                        return true;
                    }
                    return false;
                }
            }
        }

        return super.onTouchEvent(widget, buffer, event);
    }

    public boolean canSelectArbitrarily() {
        return true;
    }

    public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode,
                           KeyEvent event) {
        return false;
    }

textView.setMovementMethod(LinkMovementMethodExt.getInstance());


为“android developer”编辑
最好为LinkMovementMethodExt类添加Handler属性。 您可以捕获作为 Message 对象传递的所有 Spanned。 在 onTouchEvent 方法中截取代码:



Message message = Handler.obtainMessage();
message.obj = buffer.getSpans(off, off, Spanned.class);//get all spanned
message.what = 111;//which value ,it is up to you
message.sendToTarget(); //send message to you target handler

您可以在处理程序类中处理预期的处理程序。可能是灵活的处理方式。
希望能帮到你。


在此处输入图像描述


上面的textview文本是<a href='/a'>aaaa</a>123456<a href='/b'>bbbb</b>7890
我理解你的要求:
点击'aaaa',你想得到它s href value '/a', click 'bbbb',get it的href'/b';不要触发在 Web 浏览器中打开的默认操作。
如果我的理解是正确的,你可以这样做:

  • 为 textview 等设置 LinkMovementMethod:textview.setMovementMethod(LinkMovementMethodExt.getInstance(handler, URLSpan.class));
  • 获取兴趣跨度,这里是 URLSpan。
    在您的处理程序handleMessage方法中,您可以这样做:
private Handler handler = new Handler() {
      public void handleMessage(Message msg) {
          int what = msg.what;
          if (what == 100) {
              Object[] spans = (Object[])msg.obj;
              for (Object span : spans) {
                  if (span instanceof URLSpan) {
                      System.out.println(((URLSpan) span).getURL());
                  }
              }
          }
      };
  };

下载演示代码

  • MainActivity具有color属性,您可以根据需要分配哪个颜色值。

怎么做?

  • Step1,获取当前点击跨度。

  • Step2,为当前点击范围设置BackgroundColorSpan

于 2013-04-24T02:42:57.147 回答
0

假设您要单击文本视图上的单个单词?我不明白在您的评论中将所有字母转换为单词。

下面可以用来点击个别作品,并以吐司的形式显示。

    public class MainActivity extends Activity {

    TextView _tv;
    String[] each;
    SpannableString ss1;
    Button b;
    EditText et;
    String s;
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    b= (Button) findViewById(R.id.button1);
    et = (EditText) findViewById(R.id.ed);
    _tv = (TextView) findViewById( R.id.tv );
    b.setOnClickListener(new OnClickListener()
    {

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        s=et.getText().toString();
        _tv.setText("");
        for(int i=0;i<s.length();i++)
        {
            each = s.split("\\s+");
        }
        for(int i=0;i<each.length;i++)
        {
            System.out.println("................"+each[i]);
            ss1=  new SpannableString(each[i]);
            //StyleSpan boldSpan = new StyleSpan( Typeface.BOLD );
            //spannable.setSpan( boldSpan, 41, 52, Spannable.SPAN_INCLUSIVE_INCLUSIVE );
            ss1.setSpan(new MyClickableSpan(each[i]), 0, ss1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            _tv.append(ss1); 
            _tv.append(" "); 

        }
        _tv.setMovementMethod(LinkMovementMethod.getInstance());
    }
       });
      }
      class MyClickableSpan extends ClickableSpan{ 
      String clicked;
          public MyClickableSpan(String string) {
    // TODO Auto-generated constructor stub
       clicked =string;
      }
      //clickable span
      public void onClick(View textView) {
      //do something


      Toast.makeText(MainActivity.this,clicked ,
        Toast.LENGTH_SHORT).show();
     }
     @Override
     public void updateDrawState(TextPaint ds) {
     ds.setColor(Color.BLACK);//set text color 
     ds.setUnderlineText(false); // set to false to remove underline
     }
    }
    }
于 2013-03-29T08:36:50.097 回答