【问题标题】:disable setMovementMethod(LinkMovementMethod.getInstance()) on android在 android 上禁用 setMovementMethod(LinkMovementMethod.getInstance())
【发布时间】:2020-01-09 06:51:26
【问题描述】:

我在我的 Android 应用程序中使用 setMovementMethod(LinkMovementMethod.getInstance()) 作为 EditText 视图。 EditText 中的链接工作正常,但在某些情况下,我需要通过程序禁用此方法(因为在 longClick 菜单中启用复制项)。怎么做?我需要类似“removeMovementMethod()”的东西。

你能帮帮我吗?

谢谢!

【问题讨论】:

    标签: android android-edittext hyperlink


    【解决方案1】:

    遇到同样的问题后,请考虑一下,设置方法似乎有一定的顺序。

    1. 获取“文本视图”
    final TextView tv = new TextView(getContext());
    
    1. 设置所有必要的布局参数
    tv.setLayoutParams(lp_tv);
    
    1. 设置Linkify将文本中的所有链接标记为Link
    tv.setAutoLinkMask(Linkify.ALL);
    
    1. 设置TextView的内容(setAutoLinkMask之后)
    tv.setText("MyText")
    tv.setText(Html.fromHtml("<big>MyText</big>");
    
    1. 现在您可以附加LinkMovementMethod。如果之前附加了该方法,它将调用默认行为并打开系统浏览器。我使用TextViewLinkHandler 类作为个人行为来完成这项工作。标准行为是:
    tv.setLinkMovementMethod(new LinkMovementMethod.getInstance());
    

    如果用户单击链接,我会使用TextViewLinkHandler 做一些其他事情(例如打开一个单独的 Intent 来处理 URL)

     tv.setMovementMethod(new TextViewLinkHandler() {
    // do my stuff ... 
    // if left blank, nothing will happen on click at the link, so leave it blank to do nothing
    });
    

    与提到的TextViewLinkHandler()

    public abstract class TextViewLinkHandler extends LinkMovementMethod {
    
            public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
                if (event.getAction() != MotionEvent.ACTION_UP)
                    return super.onTouchEvent(widget, buffer, event);
    
                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);
    
                URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
                if (link.length != 0) {
                    onLinkClick(link[0].getURL());
                }
                return true;
            }
    
            abstract public void onLinkClick(String url);
        }
    

    【讨论】:

      【解决方案2】:

      setMovementMethod(null) 之后长按菜单将被禁用。因此最好使用这种方法:

      setMovementMethod(ArrowKeyMovementMethod.getInstance())
      

      【讨论】:

      • 我没有找到这样的方法。 android中有没有
      • 谢谢我也明白了。但它对点击跨度没有帮助,尽管它可以很好地长时间点击。旁边有没有
      • 在setMovementMethod(LinkMovementMethod.getInstance()) 之前,您可以尝试Log.v("movement", et.getMovementMethod()) 检查该值并在某些命令中再次使用et.setMovementMethod(VALUE) 返回该值。
      • et.getMovementMethod() 给出资源类型值 android.text.Method.ArroKeyMovementMethod@40521f10。这是什么意思??如果设置了我无法在edittext中删除click.ontouch上的跨区文本。:(
      • aLSO IF IS SET LinkMovemetMethod 方法我无法将光标位置放置到 spanntext 的末尾。如果我没有在可点击跨度之前设置 LinkMovementMethod,我将无法在 onclick 上删除 spanntext。有什么建议吗??
      【解决方案3】:
      setMovementMethod(null)
      

      会将文本视图的移动方法设置为空。如果您的代码想要以某种方式处理 MovementMethod,这当然会导致 NullPointerException。

      【讨论】:

      • 感谢您的回复!一般来说,答案是正确的,在setMovementMethod(null) 链接不起作用但 longClick 事件也没有反应之后。我需要从 EditText 复制文本,但它在 setMovementMethod(LinkMovementMethod.getInstance()) 之后被禁用我正在寻找解决这个问题的方法。可能你有一些想法?谢谢!
      • 我尝试重新附加 LongClicklistener 但它没有效果 :( 是 setMovementMethod(null) 的一些默认值,它看起来像这个值!= null。
      • 对不起,又没有效果了。在setMovementMethod(null) 之后,即使在调用setOnLongClickListener() 之后,也无法调用 longClick 菜单 :(
      • 是的,我使用了edittext.setMovementMethod(LinkMovementMethod.getInstance()),之后我没有在 longClick 菜单上复制项目,但是在edittext.setMovementMethod(null) 之后我根本没有 longClick 菜单......并且 edittext.setFocusable(true) 做了没办法……
      • @lubart 试试this 和this
      【解决方案4】:

      就像@lubart 在其中一个答案中评论的那样,设置 setMovementMethod(null) 将不起作用。您需要在设置 LinkMovementMethod 之前保存之前的 MovementMethod,并在不想使用 LinkMovementMethod 时再次恢复。

      我要强调的一件重要的事情是,当恢复到以前的 MovementMethod 时,您必须设置 AutoLinkMask=0,否则链接不会消失,插入符号不会显示,复制/粘贴上下文菜单也不会出现。

      另外,使用 setMovementMethod 后,在 EditText/TextView 中再次设置文本,以便应用移动方法。

      算法(不是代码):

      设置链接移动方式 -

      previousMovementMethod = editText.MovementMethod;
      
      editText.autoLinkMask = All;
      editText.MovementMethod = LinkMovementMethod.GetInstance();
      editText.SetText(editText.GetText());
      

      删除链接移动方法 -

      editText.autoLinkMask = 0;
      editText.MovementMethod = previousMovementMethod;
      editText.SetText(editText.GetText());
      

      【讨论】:

        【解决方案5】:

        试试看:- 在你的项目中添加这个类

        import android.text.Layout;
        import android.text.Selection;
        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;
        
        /**
         * Created by Nishu on 20-08-2015.
         */
        public class MyMovementMethod extends ArrowKeyMovementMethod {
        
        private static MyMovementMethod sInstance;
        
        public static MovementMethod getInstance() {
        if (sInstance == null) {
            sInstance = new MyMovementMethod ();
            }
             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);
        
            ClickableSpan[] link = buffer.getSpans(off, off,  ClickableSpan.class);
        
            if (link.length != 0) {
                if (action == MotionEvent.ACTION_UP) {
                    link[0].onClick(widget);
                }
                else if (action == MotionEvent.ACTION_DOWN) {
                    Selection.setSelection(buffer, buffer.getSpanStart(link[0]),   buffer.getSpanEnd(link[0]));
                }
        
                return true;
            }
            /*else {
                that's the line we need to remove
                Selection.removeSelection(buffer);
            }*/
          }
        
          return super.onTouchEvent(widget, buffer, event);
         }
        
        }
        

        现在用你的 EditText 添加下面的代码行

        YourEditText.setMovementMethod(MyMovementMethod.getInstance());
        

        并从 editText 中删除所有类型的 setMovementMethods 就是这样:)

        【讨论】:

          【解决方案6】:

          正如 user5211136 所说,您可以使用自定义 ArrowKeyMovementMethod。然后文本将是可选的,超链接也将起作用。但是user5211136类的使用调用错误

          “未找到意图的活动,意图{ act=android.intent.action.VIEW dat= https://...(有附加功能)}"

          对我来说。

          这就是我使用这个类的原因:

          public class CustomArrowKeyMovementMethod extends ArrowKeyMovementMethod {
          
              public static MovementMethod getInstance(){
                  return new CustomArrowKeyMovementMethod();
              }
          
              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);
          
                      URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
          
                      if (link.length != 0) {
                          if (action == MotionEvent.ACTION_UP) {
                              String url = link[0].getURL().trim();
                              if(url.startsWith("www")) {
                                  url = "http://" + url;
                              }
                              if (url.startsWith("https://") || url.startsWith("http://") || url.startsWith("tel:") || url.startsWith("mailto:")) {
                                  try {
                                      Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                                      widget.getContext().startActivity(browserIntent);
                                  } catch (Exception e) {
                                      Toast.makeText(widget.getContext(), "Couldn't open url", Toast.LENGTH_LONG).show();
                                  }
                              }
                          } else {
                              Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
                          }
                          return true;
                      }
                  }
                  return super.onTouchEvent(widget, buffer, event);
              }
          }
          

          并将其称为:

          textView.setMovementMethod();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-22
            • 1970-01-01
            • 2021-08-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多