6

2 つの解決策が見つかりました - 選択した回答を参照してください

ユーザーが EditText の特定の領域をクリックすると、ダイアログが表示されます。クリックをキャプチャするために onClick を使用しました。これは部分的に機能します。ユーザーが EditText を初めてタップすると、ソフト キーボードがポップアップしますが、ダイアログはポップアップしません。続けてタップすると、キーボードが表示され、次にダイアログが表示されます (キーボードは消えます)。

これは、EditText がフォーカスを得ることと関係があると思われます。

コードスニップは次のとおりです。

public class PrefixEditText extends EditText implements TextWatcher, OnClickListener
{
  public PrefixEditText (Context context)
  {
    super (context);
    setOnClickListener (this);
  }

  @Override
  public void onClick(View v)
  {
    int selStart = getSelectionStart();
    if (selStart < some_particular_pos)
      bring_up_dialog();
  }
}

重要: 通常の EditText の動作を完全に無効にしたくありません。ユーザーが地域を選択できるようにしたい (コピー & ペースト用)。おそらく、まだフォーカスを当てたいと思っています(物理キーボードを使用しているユーザーがアプリを使用するときにモデルを壊さないようにします)。クリックでカーソル位置を設定してもOKです。したがって、onTouch をオーバーライドして EditText からのすべての onTouch アクションをブロックするソリューションは、私にとってはうまくいきません。

更新 私はもう少し発見しました。EditText がフォーカスを取得している場合、onFocusChange が呼び出されますが、onClick は呼び出されません。既にフォーカスがある場合、onClick が呼び出されますが、onFocusChange は呼び出されません。

次に、呼び出してキーボードを非表示にすることができます

setInputType (InputType.TYPE_NULL);

onFocusChange でこれを行うと、キーボードが表示されなくなります。onClick でこれを行うのは (クリックする前にキーボードが非表示になっていると仮定して) 明らかに遅すぎます - キーボードが表示されてから消えます。

次に試すアイデアは、onTouch 中にキーボードを非表示にすることです。しかし、私はそのコードを台無しにすることを恐れています - 私が理解したことは、EditTextの将来のバージョンに関して非常に壊れやすいようです.

これについて何か考えはありますか?

4

5 に答える 5

3

これはうまくいくかもしれません

 EditText e = new EditText(context);
    e.setOnFocusChangeListener(new OnFocusChangeListener() {

        public void onFocusChange(View v, boolean hasFocus) {
            // TODO Auto-generated method stub
        if(hasFocus)
        {
            //dialogue popup
        }
        }
    });

または、使用してからe.hasFocus();使用e.setFocusable(false);して、フォーカスを外すことができます

/////////////// 私のコード

e.setInputType(InputType.TYPE_NULL);

e.setOnClickListener(new OnClickListener() {

    public void onClick(View v) {
        // TODO Auto-generated method stub
        AlertDialog.Builder sa = new Builder(ctx);
        sa.create().setOnDismissListener(new OnDismissListener() {

            public void onDismiss(DialogInterface dialog) {
                // TODO Auto-generated method stub
                e.setInputType(InputType.TYPE_CLASS_TEXT);
            }
        });
        sa.show();
    }
});
于 2013-02-12T05:45:48.367 に答える
2

キャプチャクリックをonClickからonTouchに変更してみてください

    this.editText.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                                //dialogue popup
            }
            return false;
        }
    });
于 2013-02-12T05:49:11.057 に答える
1

多くの実験の後、ここに2つの実用的な解決策があります! 4.2.1 を実行する Nexus 7、4.0.4 を実行する Kyocera C5170 の 2 つのデバイスでテストしました。私の好みはソリューション 2 です。

解決策 1

最初のトリックは、EditText が機能する前に、特にキーボードがポップアップする前に、onClick ではなく onTouch でカーソル位置を決定することでした。

追加のコメント: ポップアップのマニフェストで必ず android:windowSoftInputMode="stateHidden" を設定してください。そうしないと、ポップアップとともにキーボードが表示されます。

コード全体は次のとおりです。

public class ClickText extends EditText implements OnTouchListener
{
  public ClickText (Context context, AttributeSet attrs)
  {
    super (context, attrs);
    setOnTouchListener (this);
  }

  @Override
  public boolean onTouch (View v, MotionEvent event)
  {
    if (event.getActionMasked() == MotionEvent.ACTION_DOWN)
    {
      int line = getLayout().getLineForVertical ((int)event.getY());
      int onTouchCursorPos = getLayout().getOffsetForHorizontal (line, event.getX());
      if (onTouchCursorPos < 10) // or whatever condition
        showPopup (this); // or whatever you want to do
    }
    return false;
  }

  private void showPopup (final EditText text)
  {
    Intent intent = new Intent (getContext(), Popup.class);
    ((Activity)getContext()).startActivity (intent);
  }
}

解決策 2

これは実際にはよりシンプルで、副作用が少なく、より優れていると思います。

ここでの秘訣は、EditText にすべてのクリック処理を行わせてから、非同期でオーバーライドすることです。要点は次のとおりです。タッチが「離される」まで待ちます - MotionEvent.ACTION_UP - そして、すぐにアクションを実行する代わりに、Runnable をイベント キューに投稿し、そこでアクションを実行します。

コード全体:

public class ClickText extends EditText implements OnTouchListener
{
  public ClickText (Context context, AttributeSet attrs)
  {
    super (context, attrs);
    setOnTouchListener (this);
  }

  @Override
  public boolean onTouch (View v, MotionEvent event)
  {
    switch (event.getActionMasked())
    {
      case MotionEvent.ACTION_UP:
      {
        post (new Runnable ()
        {
          // Do this asynch so that EditText can finish setting the selectino.
          @Override
          public void run()
          {
            int selStart = getSelectionStart();
            int selEnd = getSelectionEnd();

            // If selStart is different than selEnd, user has highlighed an area of
            // text; I chose to ignore the click when this happens.
            if (selStart == selEnd)
              if (selStart >= 0 && selStart < 10) // or whatever range you want
                showPopup (this);
          }            
        });

        break;
      }
    }

    return false;
  }

  private void showPopup (final EditText text)
  {
    Intent intent = new Intent (getContext(), Popup.class);
    ((Activity)getContext()).startActivity (intent);
  }
}
于 2013-02-13T16:40:05.387 に答える
0

以下のコードスニペットを使用してください

this.editText.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                                //dialogue popup
            }
            return false;
        }
    });
于 2017-12-17T12:59:01.677 に答える