Событие щелчка по промежутку Android

Ok. Это мои проблемы.

  1. Мне нужно использовать регулярные выражения, чтобы вырезать все, кроме букв, а затем мне нужно заключить найденные слова в тег $word. При этом str = str.replaceAll(шаблон, "$0");. прямо сейчас я фильтрую все правильные элементы (пунктуацию, цифры и т. д.), но каждая буква в каждом слове заключена в тег a, а не в слово. Итак, как мне использовать регулярное выражение для группировки букв в слово?

from "(открыть тег)t(закрыть)(открыть тег)h(закрыть)(открыть тег)i(закрыть)(открыть тег)s(закрыть) (открыть тег)i(a закрыть)(тег открыт)s(закрыть) (открыть тег)w(закрыть)(открыть тег)r(закрыть)(открыть тег)o(закрыть)(открыть тег)n(a закрыть)(открыть тег)g(закрыть)";

to :

"(открытый тег)Это(закрытие) (открытый тег)это(закрытие) (открытый тег)правильно(закрытие)";

затем я делаю их интерактивными, и мне нужно поймать событие щелчка и получить позицию на экране в слове, по которому щелкнули, поскольку я хочу использовать событие щелчка, чтобы всплывающая подсказка отображалась чуть ниже слова, по которому щелкнули. Спасибо за помощь.

открытый класс MainActivity расширяет активность {

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

}


person TheMan68    schedule 29.03.2013    source источник
comment
я не могу четко понять вопрос. У вас есть строка, и вы намерены щелкнуть текст в текстовом представлении.   -  person Raghunandan    schedule 29.03.2013
comment
ну, во-первых, у меня есть строка Это с номерами 238 66 И ?? PUNC BL BLAi хочу преобразовать это в ‹span›This‹/span› ‹span›is‹/span› ‹span›a‹/span› ‹span›with‹/span› ‹span›numbers‹/span› 238 66 ‹span›И‹/span› ?? ‹span›PUNC‹/span› ‹span›BL‹/span› ‹span›BLA‹/span›   -  person TheMan68    schedule 29.03.2013
comment
но я получаю это ‹span›T‹/span›‹span›h‹/span›‹span›i‹/span›‹span›s ‹/span›‹span›i‹/span›‹span›s‹/ span›..... и т. д. Итак, как мне сгруппировать буквы в слово   -  person TheMan68    schedule 29.03.2013
comment
Вы хотите, чтобы отдельные работы в текстовом виде были интерактивными?   -  person Raghunandan    schedule 29.03.2013
comment
да, но я уже получил это с кодом выше. я могу регистрировать каждое отдельное слово и все детали, которые мне нужны для каждого нажатого элемента, но он преобразует все буквы, а не слова   -  person TheMan68    schedule 29.03.2013
comment
спасибо за ваш быстрый ответ   -  person TheMan68    schedule 29.03.2013
comment
Пожалуйста, отредактируйте свой вопрос. Вместо того, чтобы писать всю историю, вы можете просто указать на реальную проблему.   -  person Raghunandan    schedule 29.03.2013


Ответы (2)


Последний код, пожалуйста, см. форма ссылки github

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

Перед установкой нового диапазона необходимо удалить исходный диапазон. См. ниже
onClick() ClickableSpan не работает для 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"
Лучше добавить свойство Handler для класса LinkMovementMethodExt.
Вы можете захватить все Spanned, которые доставляются как объект Message.

Фрагмент кода в методе 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

Вы можете обработать ожидаемый охват в вашем классе обработчика. Может быть, это гибкий способ справиться с .
Надеюсь помочь вам.


введите здесь описание изображения


Над текстовым представлением текст <a href='/a'>aaaa</a>123456<a href='/b'>bbbb</b>7890
Я понимаю ваше требование:
Нажмите «aaaa», вы хотите получить егоs href value '/a', click 'bbbb',get its href '/b'; Не запускать действие по умолчанию, которое открыто в веб-браузере.
Если я правильно понимаю, вы можете сделать так:

  • Установите 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, которому вы можете назначить желаемое значение цвета.

Как сделать?

  • Шаг 1, получите текущий диапазон кликов.

  • Шаг 2, установите BackgroundColorSpan для текущего диапазона кликов.

person boiledwater    schedule 24.04.2013
comment
это действительно хорошее решение. Могу ли я выполнить индивидуальное действие при нажатии на ссылку, но при этом иметь тот же эффект нажатия на ссылку (вместо этого я использую ClickableSpan)? - person android developer; 03.09.2013
comment
я не понимаю. может быть, я объясню лучше: предположим, у меня есть textView, в котором я устанавливаю текст из strings.xml, внутри которого есть несколько ссылок. я хочу зафиксировать щелчок по каждому из них, чтобы я сам обрабатывал то, что происходит дальше, вместо того, чтобы открывать намерение для веб-браузера. как бы я это сделал? - person android developer; 04.09.2013
comment
где вы поместите обработчик и заставите его обогнать поведение по умолчанию? в настоящее время все, что я вижу, это подготовка обработчика, но нет связи с тем, где его разместить и заставить работать... - person android developer; 05.09.2013
comment
У меня есть метод редактирования MovementMethod getInstance(), который имеет параметр обработчика. - person boiledwater; 05.09.2013
comment
Разработчик @android, я пишу для этого демонстрационный проект. Как вас отправить? - person boiledwater; 05.09.2013
comment
Благодарю. вы можете использовать любой веб-сайт, который вы хотите. даже вставить бин. кстати, я думаю, что вы случайно установили неправильные переменные. обычно используется для полей, а не для параметров. - person android developer; 05.09.2013
comment
для скачивания с этого сайта требуется регистрация и знание китайского языка. :( - person android developer; 05.09.2013
comment
@androiddeveloper, я не нашел файловую систему интернет-магазина. Если вам нравится, пожалуйста, отправьте письмо по адресу [email protected]; Отправлю к вам завтра. - person boiledwater; 05.09.2013
comment
@androiddeveloper, я не нашел файловую систему интернет-магазина. Если вам нравится, пожалуйста, отправьте письмо по адресу [email protected]; Отправлю к вам завтра. - person boiledwater; 05.09.2013
comment
это так долго, что вам нужно опубликовать весь проект? просто опубликуйте образец. вы можете использовать pasteBin . просто вставьте соответствующий код: pastebin.com - person android developer; 05.09.2013
comment
я уже пробовал это, и это не работает, так как, когда вы нажимаете на ссылку, она остается помеченной, как будто вы все еще касаетесь ее. в поведении по умолчанию, как только вы нажмете на ссылку, она снова вернется в нормальное состояние. Кстати, вам не нужно использовать обработчик. вместо этого вы можете использовать прослушиватель. - person android developer; 06.09.2013
comment
давайте продолжим это обсуждение в чате - person boiledwater; 06.09.2013
comment
я не думаю, что вы понимаете. код нормально обрабатывает ссылку, но эффект прикосновения к ссылке работает не очень хорошо. он показывает что-то вроде этого, хотя я больше не касаюсь ссылки: imageshack.us/photo/my-images/89/13ms.png - person android developer; 06.09.2013
comment
@androiddeveloper, я не понял, что ты имеешь в виду раньше. Теперь я изменил код github, загрузите его снова. При нажатии на ссылку соответствующий цвет фона изменится на зеленый. img824.imageshack.us/img824/5177/kee9.png - person boiledwater; 09.09.2013
comment
у него все та же ошибка, только с другим цветом: когда я касаюсь его и убираю палец с устройства, ссылка остается с тем же эффектом, как если бы я все еще касался ее. - person android developer; 09.09.2013
comment
@androiddeveloper, Вы хотите: во время периода касания измените фон ссылки. Восстановите статус инициализации после завершения касания. Если это так, загрузите снова. - person boiledwater; 09.09.2013
comment
теперь работает нормально. может быть, я должен был разместить вопрос вместо того, чтобы писать все здесь. что вы сделали для того, чтобы заставить его работать? также, почему цвет теперь зеленый? - person android developer; 09.09.2013
comment
можно ли использовать цвет по умолчанию? также, что было не так до этого, теперь работает нормально? - person android developer; 09.09.2013
comment
Да, вы можете установить любой цвет. Перед значением href system.out.println, возможно, вы этого не заметили. Чтобы показать четкость, измените стиль Toast. - person boiledwater; 09.09.2013
comment
я не понимаю последнюю фразу. - person android developer; 09.09.2013
comment
меня не волнует тост. Я имел в виду цвет URL. я спросил, могу ли я использовать для этого цвет по умолчанию. Я думаю, что обычно это какой-то синий цвет, но на старых устройствах он может быть зеленым. - person android developer; 09.09.2013
comment
@androiddeveloper, вы можете установить любой цвет по своему усмотрению. Я изменил цвет на синий. - person boiledwater; 10.09.2013
comment
я знаю что могу. я спрашиваю, как использовать вариант по умолчанию, так как он может отличаться для каждого устройства/версии/ПЗУ... - person android developer; 10.09.2013
comment
@androiddeveloper, я загружаю последний код. изменить цвет фона ссылки на цвет по умолчанию (view.getLinkTextColors().getDefaultColor()) - person boiledwater; 10.09.2013
comment
кажется, что код, который вы написали для цвета ссылок при нажатии на них, неверен, так как он придает полностью непрозрачный синий цвет. - person android developer; 27.10.2013

Предполагая, что вы хотите щелкнуть отдельные слова в текстовом представлении?. Я не понимаю преобразования всех букв в слова в вашем комментарии.

Приведенное ниже можно использовать для нажатия на отдельные работы, и оно отображается в всплывающем меню.

    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
     }
    }
    }
person Raghunandan    schedule 29.03.2013
comment
@ TheMan68 это то, что ты искал? - person Raghunandan; 29.03.2013
comment
не совсем так, как это все еще делает все элементы, такие как число и другие элементы, кликабельными. мне нужны были только слова, поэтому я использовал регулярные выражения, чтобы вставить тег a вокруг слов. Спасибо за помощь - person TheMan68; 30.03.2013