我有几个输入字段的活动.当活动开始时,显示软键盘.当按下后退按钮软键盘关闭并关闭活动时,我需要再次按下后退按钮.
所以问题是:是否有可能拦截后退按钮关闭软键盘并在一次按下后退按钮完成活动而不创建自定义InputMethodService?
PS我知道如何在其他情况下拦截后退按钮:onKeyDown()或者onBackPressed()在这种情况下它不起作用:只有第二次按下后退按钮被拦截.
mhr*_*dek 76
是的,完全可以显示和隐藏键盘并拦截对后退按钮的调用.这是一个额外的努力,因为已经提到在API中没有直接的方法来做到这一点.关键是boolean dispatchKeyEventPreIme(KeyEvent)在布局中覆盖.我们做的是创建我们的布局.我选择了RelativeLayout,因为它是我的Activity的基础.
<?xml version="1.0" encoding="utf-8"?>
<com.michaelhradek.superapp.utilities.SearchLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.michaelhradek.superapp"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/white">
Run Code Online (Sandbox Code Playgroud)
在我们的Activity中,我们设置输入字段并调用该setActivity(...)函数.
private void initInputField() {
mInputField = (EditText) findViewById(R.id.searchInput);
InputMethodManager imm =
(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
InputMethodManager.HIDE_IMPLICIT_ONLY);
mInputField.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
performSearch();
return true;
}
return false;
}
});
// Let the layout know we are going to be overriding the back button
SearchLayout.setSearchActivity(this);
}
Run Code Online (Sandbox Code Playgroud)
显然,该initInputField()函数设置输入字段.它还使enter键能够执行功能(在我的例子中是搜索).
@Override
public void onBackPressed() {
// It's expensive, if running turn it off.
DataHelper.cancelSearch();
hideKeyboard();
super.onBackPressed();
}
Run Code Online (Sandbox Code Playgroud)
因此,当onBackPressed()在我们的布局中调用时,我们可以做任何我们想做的事情,比如隐藏键盘:
private void hideKeyboard() {
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mInputField.getWindowToken(), 0);
}
Run Code Online (Sandbox Code Playgroud)
无论如何,这是我对RelativeLayout的重写.
package com.michaelhradek.superapp.utilities;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.RelativeLayout;
/**
* The root element in the search bar layout. This is a custom view just to
* override the handling of the back button.
*
*/
public class SearchLayout extends RelativeLayout {
private static final String TAG = "SearchLayout";
private static Activity mSearchActivity;;
public SearchLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SearchLayout(Context context) {
super(context);
}
public static void setSearchActivity(Activity searchActivity) {
mSearchActivity = searchActivity;
}
/**
* Overrides the handling of the back key to move back to the
* previous sources or dismiss the search dialog, instead of
* dismissing the input method.
*/
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
Log.d(TAG, "dispatchKeyEventPreIme(" + event + ")");
if (mSearchActivity != null &&
event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
KeyEvent.DispatcherState state = getKeyDispatcherState();
if (state != null) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getRepeatCount() == 0) {
state.startTracking(event, this);
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP
&& !event.isCanceled() && state.isTracking(event)) {
mSearchActivity.onBackPressed();
return true;
}
}
}
return super.dispatchKeyEventPreIme(event);
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我无法承担所有的功劳.如果您在Android 源代码中查看快速SearchDialog框,您将看到该想法的来源.
Ali*_*mel 71
onKeyDown()和onBackPressed()不适用于这种情况.你必须使用onKeyPreIme.
最初,您必须创建扩展EditText的自定义编辑文本.然后你必须实现控制KeyEvent.KEYCODE_BACK的 onKeyPreIme方法.在此之后,一个足以解决您的问题.这个解决方案非常适合我.
CustomEditText.java
public class CustomEditText extends EditText {
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// User has pressed Back key. So hide the keyboard
InputMethodManager mgr = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(this.getWindowToken(), 0);
// TODO: Hide your view as you do it in your activity
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
在您的XML中
<com.YOURAPP.CustomEditText
android:id="@+id/CEditText"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
Run Code Online (Sandbox Code Playgroud)
在你的活动中
public class MainActivity extends Activity {
private CustomEditText editText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (CustomEditText) findViewById(R.id.CEditText);
}
}
Run Code Online (Sandbox Code Playgroud)
Kir*_*man 10
我发现,覆盖Layout类的dispatchKeyEventPreIme方法也很有效.只需将主Activity设置为属性并启动预定义方法即可.
public class LinearLayoutGradient extends LinearLayout {
MainActivity a;
public void setMainActivity(MainActivity a) {
this.a = a;
}
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
if (a != null) {
InputMethodManager imm = (InputMethodManager) a
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isActive() && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
a.launchMethod;
}
}
return super.dispatchKeyEventPreIme(event);
}
}
Run Code Online (Sandbox Code Playgroud)
我通过重写dispatchKeyEvent取得了成功:
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
finish();
return true;
}
return super.dispatchKeyEvent(event);
}
Run Code Online (Sandbox Code Playgroud)
它隐藏键盘并完成活动.
| 归档时间: |
|
| 查看次数: |
77540 次 |
| 最近记录: |