在Android的可点击的链接和复制/粘贴菜单EditView中(Clickable links a

2019-06-24 09:45发布

我有一个EditText在我的Android应用程序视图。 我需要它“内在联系”,这意味着我需要里面的一些按钮或跨度EditTextonClick这个按钮,我可以做一些动作(不重定向到Web页面)。 我意识到这个按钮ClickableSpan()这样的

linkWord = "my link";
link = new SpannableString(linkWord);
cs = new ClickableSpan(){
private String w = linkWord;
    @Override
    public void onClick(View widget) {
    wrd.setText(w);
    }
};
link.setSpan(cs, 0, linkWord.length(), 0);
et.append(link);

为了使这个跨度可点击我用

et.setMovementMethod(LinkMovementMethod.getInstance());

“内在联系”工作正常,但使用后et.setMovementMethod()复制和粘贴物品是禁止在OnLongClick菜单。 这是一个问题,因为我需要在“链接” EditText从这个画面中,同时复制文本。

我有想法听者设置OnLongClickListenerremoveMovementMethod()临时禁用“链接”功能,并复制/粘贴使用的菜单和文本应对开关之后setMovementMethod()再次方法。 但我不知道如何实现这一点。

你能帮助我吗? 您可能也有一些其他的方式?

谢谢!

Answer 1:

我不认为有链接,复制模式之间进行切换会为你赢得一个可用性奖。 我的解决方案,您可以选择文本并打开在同一时间的链接。 要做到这一点,我只是延长ArrowKeyMovementMethod,这使得选择文本,并从其中处理链接的点击/感人的LinkMovementMethod添加的onTouchEvent()方法。 有,但一行代码需要改变,这是一个去除TextView的选择时,没有链接可以在屏幕被触摸的坐标上找到。

下面是完整的类:

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);
    }

}

这样做是即使文档指出很安全:

此接口[MovementMethod]旨在用于由框架使用; 它不应该被应用程序直接执行。 http://developer.android.com/reference/android/text/method/MovementMethod.html

上面的代码延伸的记录类,而不是实现的接口。 它所做的是增加一个检查,看是否有联系被窃听和以其他方式使用超类的方法。



Answer 2:

我解决了这个问题,可这会有人很有趣...

对于里面的EditText可点击的链接我用

et.setMovementMethod(LinkMovementMethod.getInstance());

在这种情况下longClick菜单中有没有复制/粘贴物品。 对于激活他们,我需要回到正常的EditText状态,我可以做到这一点:

et.setMovementMethod(ArrowKeyMovementMethod.getInstance());

这种方法后链接将无法工作,但显示正常longClick菜单。

因此,我增加了新的项目上下文菜单,这两个选项之间切换:

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    if(et.getSelectionStart() == -1){ // in case of setMovementMethod(LinkMovementMethod.getInstance())
        menu.add(0, 1, 0, "Enable copy");
    }
    else{
        menu.add(0, 2, 0, "Enable links");
    }
}
@Override
public boolean onContextItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case 1:
          et.setMovementMethod(ArrowKeyMovementMethod.getInstance());
          et.setSelection(0, 0);
              //re-register EditText for context menu:
          unregisterForContextMenu(et);
          registerForContextMenu(et);
          break;
      case 2:
          et.setMovementMethod(LinkMovementMethod.getInstance());
          break;
      }
      return true;
  }

此外,我注册的EditText上下文菜单:

registerForContextMenu(et);

有一个希望,这将帮助别人!



文章来源: Clickable links and copy/paste menu in EditView in android