6

找到两个解决方案 - 请参阅选定的答案

当用户单击 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 行为。我希望用户能够进行区域选择(用于复制和粘贴)。我可能仍然希望它获得焦点(所以当使用物理键盘的人使用该应用程序时,我不会破坏模型)。并且点击设置光标位置就可以了。因此,覆盖 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

试试这个,如果它可以帮助你。第一次edittext将表现为正常的editttext,并且你可以根据需要显示对话框

 EditText editText;
mTim_edittext.setOnFocusChangeListener(new OnFocusChangeListener() {

      public void onFocusChange(View v, boolean hasFocus) {

     if(!hasFocus){

    //statement


 if(condition){

AlertDialog diaBox = Utils.showErrorDialogBox(  "Term in Months Cannot be 0", context);                             
diaBox.show();
              }


            }
        }
    });
于 2013-02-12T09:21:30.047 回答
1

经过大量实验,这里有两个可行的解决方案!我在我的两台设备上对它们进行了测试——Nexus 7 运行 4.2.1,Kyocera C5170 运行 4.0.4。我的首选是解决方案 2。

解决方案 1

首先,诀窍是在 EditText 有机会完成它的工作之前确定 onTouch 而不是 onClick 中的光标位置 - 特别是在它弹出键盘之前。

一个额外的评论:一定要在你的清单中为弹出窗口设置 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 回答