Доступные ссылки и меню копирования / вставки в EditView в Android

У меня есть вид EditText в приложении для Android. Мне нужно «внутренние ссылки» в нем, это означает, что мне нужно несколько кнопок или пробелов внутри EditText а с помощью onClick на этой кнопке я могу сделать некоторые действия (не перенаправлять на веб-страницу). Я понял эти кнопки с помощью 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 и скопировать текст из этого представления в одно и то же время.

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

Вы можете мне помочь? Возможно, у вас есть еще несколько способов …

Спасибо!

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

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

    Этот интерфейс [MovementMethod] предназначен для использования фреймворком; Он не должен реализовываться непосредственно приложениями. http://developer.android.com/reference/android/text/method/MovementMethod.html

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

    Я решил эту проблему, и может быть, это будет интересно кому-то …

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

    Имейте надежду, что это поможет кому-то!