6

EditTextAndroid アプリにビューがあります。その中に「内部リンク」が必要です。これは、内部にいくつかのボタンまたはスパンが必要であり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「リンク」が必要であり、同時にこのビューからテキストをコピーする必要があるため、これは問題です。

OnLongClickListener一時的に「リンク」機能を無効にするようなものをリスナーに設定しremoveMovementMethod()、コピー/貼り付けでメニューを使用し、テキストスイッチオンsetMovementMethod()メソッドを再度コピーした後に使用することを考えています。しかし、私はこれを実現する方法がわかりません。

手伝って頂けますか?他の方法があるかもしれません...

ありがとうございました!

4

2 に答える 2

17

ユーザーにリンク モードとコピー モードを切り替えてもらうことで、ユーザビリティの賞が得られるとは思いません。私のソリューションでは、テキストを選択して同時にリンクを開くことができます。これを実現するには、テキストを選択できるようにする ArrowKeyMovementMethod を拡張し、リンクのクリック/タッチを処理する LinkMovementMethod から onTouchEvent() メソッドを追加するだけです。変更が必要なコードは 1 行だけです。これは、画面がタッチされた座標にリンクが見つからない場合に 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

上記のコードは、インターフェースを実装するのではなく、文書化されたクラスを拡張します。リンクがタップされたかどうかを確認するチェックを追加し、それ以外の場合はスーパー クラス メソッドを使用するだけです。

于 2013-08-30T21:49:46.040 に答える
4

私はこの問題を解決しました。これは誰かにとって興味深いものになるかもしれません...

私が使用した EditText 内のクリック可能なリンクについて

et.setMovementMethod(LinkMovementMethod.getInstance());

この場合、longClick メニューにはコピー/貼り付け項目はありません。それらをアクティブにするには、通常の EditText 状態に戻す必要があります。次の方法で実行できます。

et.setMovementMethod(ArrowKeyMovementMethod.getInstance());

このメソッドの後、リンクは機能しませんが、通常の longClick メニューが表示されます。

したがって、コンテキスト メニューに新しい項目を追加し、次の 2 つのオプションを切り替えました。

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

これが誰かを助けることを願っています!

于 2012-05-14T14:34:01.333 に答える