将焦点设置在EditText上

224

我有一个EditText字段,并为其设置了OnFocusChangeListener。当它失去焦点时,会调用一个方法,检查EditText的值与数据库中的值是否相同。如果该方法的返回值为true,则会显示一条消息并将焦点再次放回到EditText上。直到该方法的返回值为false时,焦点应始终保持在EditText上,键盘也应该显示。

编辑:我认为我尚未完全清楚我的真正问题:在EditText的值被编辑为使方法“checkLiganame(liganame)”返回false的值之前,屏幕上的其他项目都不应该能够进行编辑。只有EditText字段可以编辑。

这是我的代码(对我无效):

final EditText Liganame = (EditText) findViewById(R.id.liganame);

    Liganame.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {

                String liganame = Liganame.getText().toString();


                if (checkLiganame(liganame)) {
                    Toast toast = Toast.makeText(CreateTableActivity.this,
                            "Dieser Liganame ist bereits vergeben",
                            Toast.LENGTH_SHORT);
                    toast.show();
                    Liganame.requestFocus();
                }
            }

还有方法:

public boolean checkLiganame(String liganame) {
    boolean found = false;

    DatabaseHelper databaseHelper = new DatabaseHelper(this);
    SQLiteDatabase db = databaseHelper.getReadableDatabase();

    Cursor cursor = db.query("liga", new String[] { "liganame" },
            "liganame = '" + liganame + "'", null, null, null, null);
    Log.i("Liganame: ", String.valueOf(cursor));

    db.close();
    if (cursor != null) {
        found = true;
    }

    return found;
}
这段代码会产生以下结果:在EditText失去焦点后,焦点会跳回到EditText,但我无法再编辑文本了。
EDIT2:更改了我的代码。情境如下:
我点击第一个EditText并输入一个已经存在于数据库中的字符串。弹出toast提示。现在我不能再编辑我的字符串了。我点击键盘上的“下一步”按钮,焦点仍停留在第一个EditText上。我尝试编辑我的字符串,但没有任何反应。相反,我的新字符串显示在第二个EditText中。我点击设备的返回箭头,然后重新点击第一个和第二个EditText-->键盘不再显示。
这是我的新代码:
public class CreateTableActivity extends Activity implements
    OnFocusChangeListener {

private EditText Liganame, Mannschaftsanzahl;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.create_league);

    Liganame = (EditText) findViewById(R.id.liganame);
    Liganame.setOnFocusChangeListener(this);
    Mannschaftsanzahl = (EditText) findViewById(R.id.mannschaftsanzahl);
    Mannschaftsanzahl.setOnFocusChangeListener(this);

    final Button save_button = (Button) findViewById(R.id.create_tabelle_speichern_button);

    OnClickListener mCorkyListener = new OnClickListener() {
        public void onClick(View v) {
            ButtonClick();
        }
    };
    save_button.setOnClickListener(mCorkyListener);



}

@Override
public void onFocusChange(View v, boolean hasFocus) {
    String liganame = Liganame.getText().toString();

    if (checkLiganame(liganame)) {
        if (Liganame.requestFocus()) {
            getWindow()
                    .setSoftInputMode(
                            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
            Mannschaftsanzahl.clearFocus();
            Toast.makeText(CreateTableActivity.this,
                    "Dieser Liganame ist bereits vergeben",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

如果以下答案对您有所帮助,请接受其中一个答案。 - Akshatha S R
18个回答

370

只需将这一行放在您的onCreate()中即可。

editText.requestFocus();

它还会自动激活虚拟键盘的打开。因此,您无需在代码中执行此操作。 - user2342558
15
我的情况下无法打开键盘。 - Raman Joshi
只需在上面的代码下面添加以下行=> InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(_searchText, InputMethodManager.SHOW_IMPLICIT); - HandyPawan

181

仅请求聚焦并不能显示键盘。

要获取焦点并显示键盘,您需要编写类似以下内容的代码:

if(myEditText.requestFocus()) {
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}

编辑:在添加checkLiganame方法后,对答案进行了额外的信息补充。

在checkLiganame方法中,您检查游标是否为null。 游标将始终返回一个对象,因此对null的检查没有任何作用。 但是问题在于db.close();这一行。

当您关闭数据库连接时,Cursor变得无效,很可能被置空。

因此,获取值后关闭数据库。

不要检查游标是否为空,而应检查返回的行数是否大于0:if(cursor.getCount()> 0),然后如果是,则将布尔值设置为true。

编辑2:下面是一些代码,说明如何使其工作。 编辑3:抱歉我添加了错误的代码... ;S

首先,如果另一个EditText获得焦点,则需要清除焦点。 这可以使用myEditText.clearFocus()完成。 然后,在您的onFocusChangeListener中,您实际上不应该关心第一个EditText是否具有焦点,因此onFocusChangeListener可能看起来像这样:

public class MainActivity extends Activity implements OnFocusChangeListener {
    private EditText editText1, editText2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText1 = (EditText) findViewById(R.id.editText1);
        editText1.setOnFocusChangeListener(this);
        editText2 = (EditText) findViewById(R.id.editText2);
        editText2.setOnFocusChangeListener(this);
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        String liganame = editText1.getText().toString();

        if(liganame.length() == 0) {
            if(editText1.requestFocus()) {
                getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
                editText2.clearFocus();
                Toast.makeText(MainActivity.this, "Dieser Liganame ist bereits vergeben", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

将第一个检查 if(liganame.length() == 0) 替换为您自己的检查,然后它应该正常工作。 请注意,所有的EditText视图都应该像我在示例中所做的那样将它们的 onFocusChangeListener 设置为相同的监听器。


到目前为止,谢谢你的帮助。但这并没有完全解决我的问题。我已经编辑了我的问题描述。 - Andreas Schneider
那么checkLiganame到底在做什么?为什么不能只检查liganame是否为空,如果是真的,再次请求焦点呢? - Darwind
1
谢谢 :-) 现在我的方法已经正确运行了 :-) 但我在EditText字段方面的主要问题还没有解决。在方法找到一行后,我仍然无法编辑它... - Andreas Schneider
你最终解决了这个问题吗?因为我在我的项目中遇到了完全相同的问题,并在这里发布了我的问题:https://dev59.com/Dm7Xa4cB1Zd3GeqPn0XC - TimCS
感谢您的努力。这就是使SO变得令人惊叹的原因 :) - Dheeraj Bhaskar
显示剩余4条评论

70

Darwind的代码没有显示键盘。

这对我有用:

        _searchText.requestFocus();
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(_searchText, InputMethodManager.SHOW_IMPLICIT);

如果键盘没有显示,请尝试强制显示:

        imm.showSoftInput(_searchText, InputMethodManager.SHOW_FORCED);

24
这对我有用:
public void showKeyboard(final EditText ettext){
    ettext.requestFocus();
    ettext.postDelayed(new Runnable(){
            @Override public void run(){
                InputMethodManager keyboard=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                keyboard.showSoftInput(ettext,0);
            }
        }
        ,200);
}
隐藏:

要隐藏:

private void hideSoftKeyboard(EditText ettext){
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(ettext.getWindowToken(), 0);
}

2
你为什么需要等待 200 毫秒?这是必要的还是我可以直接显示它? - Coder123

19

当按钮被点击时,这会改变EditText的焦点:

public class MainActivity extends Activity {
    private EditText e1,e2;
    private Button b1,b2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        e1=(EditText) findViewById(R.id.editText1);
        e2=(EditText) findViewById(R.id.editText2);
        e1.requestFocus();
        b1=(Button) findViewById(R.id.one);
        b2=(Button) findViewById(R.id.two);
        b1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                e1.requestFocus();

            }
        });
        b2.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                e2.requestFocus();
            }
        });
    }
}

16

这是对我有用的方法,设置焦点并显示键盘

EditText userNameText = (EditText) findViewById(R.id.textViewUserNameText);
userNameText.setFocusable(true);
userNameText.setFocusableInTouchMode(true);
userNameText.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(userNameText, InputMethodManager.SHOW_IMPLICIT);

1
谢谢。setFocusable需要API 26。在我的情况下,也不需要setFocusableInTouchMode - CoolMind

8
如果我们动态创建一个 EditText,则必须按照以下所示设置 requestFocus()。
    EditText editText = new EditText(this);
    editText.setWidth(600);
    editText.requestFocus();

如果我们已经在xml视图中声明了组件,那么我们需要找到它并按照以下方式设置焦点。
EditText e1=(EditText) findViewById(R.id.editText1);
e1.requestFocus();

它只将焦点设置到相应的EditText组件。


6
    mEditText.setFocusableInTouchMode(true);
    mEditText.requestFocus();

    if(mEditText.requestFocus()) {
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    }

5
如果在布局膨胀之前尝试调用requestFocus(),它将返回false。此代码在布局膨胀后运行。您不需要像上面提到的那样延迟200毫秒。
editText.post(Runnable {
   if(editText.requestFocus()) {
       val imm = editText.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
       imm?.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0)
   }
})

4

我在这里回答过相关问题。

根据官方文档所述,我认为最佳解决方案是将View参数传递到像EditText这样的组件中,但showSoftKeyboard函数似乎不能在横屏模式下正常工作。

private fun showSoftKeyboard(view: View) {
    if (view.requestFocus()) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
    }
}

private fun closeSoftKeyboard(view: View) {
    if (view.requestFocus()) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接