Вопрос по android – Кликабельные ссылки и меню копирования / вставки в EditView в Android

5

у меня естьEditText посмотреть в моем приложении для Android. Мне нужны & quot; внутренние ссылки & quot; в нем это означает, что мне нужно несколько кнопок или пролета внутриEditText и сonClick с этой кнопкой я могу сделать некоторые действия (не перенаправить на веб-страницу). Я понял, что это кнопки сClickableSpan() как это

<code>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);
</code>

Для этого кликабельности я использовал

et.setMovementMethod(LinkMovementMethod.getInstance());

& quot; Внутренние ссылки & quot; работает нормально, но после использованияet.setMovementMethod() копирование и вставка элементов отключены наOnLongClick меню. И это проблема, потому что мне нужны & quot; ссылки & quot; вEditText и скопировать текст из этого представления в то же время.

У меня есть идея установить в слушателеOnLongClickListener что-то вродеremoveMovementMethod() для временного отключения & quot; ссылки & quot; используйте и используйте меню с копированием / вставкой и после копирования текста включитеsetMovementMethod() метод снова. Но я не знаю, как это реализовать.

Вы можете мне помочь? Вы можете быть, есть и другие способы ...

Спасибо!

Ваш Ответ

2   ответа
4

Для кликабельных ссылок внутри 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);

Есть надежда, что это кому-нибудь поможет!

15

что переключение пользователя с режима ссылки на режим копирования принесет вам приз за удобство использования. Мое решение позволяет выделять текст и открывать ссылки одновременно. Для этого я просто расширяю ArrowKeyMovementMethod, который позволяет выделять текст, и добавляю метод onTouchEvent () из LinkMovementMethod, который обрабатывает нажатие / касание ссылок. Есть только одна строка кода, которая должна быть изменена, это та, которая удаляет выделение из 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);
    }

}

Делать это довольно безопасно, даже если в документации указано:

This interface [MovementMethod] is intended for use by the framework; it should not be implemented directly by applications. http://developer.android.com/reference/android/text/method/MovementMethod.html

Приведенный выше код расширяет документированный класс, а не реализует интерфейс. Все, что он делает, это добавляет проверку, чтобы увидеть, была ли ссылка нажата, и иначе использует методы суперкласса.

Похожие вопросы