Android截获我自己应用程序的软键击-退格问题
我有一个应用程序,它需要镜像我在某个Android截获我自己应用程序的软键击-退格问题,android,android-edittext,android-softkeyboard,android-input-method,Android,Android Edittext,Android Softkeyboard,Android Input Method,我有一个应用程序,它需要镜像我在某个片段中所做的每一次击键。到目前为止,我所做的是将TextWatcher附加到EditText并覆盖posterextchanged并提取最后一个字符(将隐藏EditText,因此一次只能输入一个字符) 为了处理退格,我在EditText中覆盖onKeyDown,并为Jellybean及以上设备使用一个涉及自定义BaseInputConnection的解决方案(将生成的KEYCODE\u DEL传递给onKeyDown——在某处找到了这个解决方案) 我遇到的问题
片段中所做的每一次击键。到目前为止,我所做的是将TextWatcher
附加到EditText
并覆盖posterextchanged
并提取最后一个字符(将隐藏EditText
,因此一次只能输入一个字符)
为了处理退格,我在EditText
中覆盖onKeyDown
,并为Jellybean及以上设备使用一个涉及自定义BaseInputConnection
的解决方案(将生成的KEYCODE\u DEL
传递给onKeyDown
——在某处找到了这个解决方案)
我遇到的问题是,当EditText
为空时,不会生成keycodel\u DEL
事件,因此我无法检测退格(即使它不会做任何事情)。我试图做的是在创建EditText
时向它添加一个字符,当我在extextchanged
中检测到EditText
为空时,如果我在输入另一个字符之前单击backspace,它将删除该填充字符,然后用另一个填充字符重新填充它
但是,“填充字符”永远不会被删除。例如,在实例化EditText
时,我用一个“a”填充它。如果我按backspace,什么也不会发生。“a”不会从编辑文本中删除
有人知道这是怎么回事吗
状态变量
private static volatile boolean backspacePressed = false;
private static volatile boolean ignoreTextChange = false;
TextWatcher
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if(backspacePressed) {
Logger.i("BKSPC");
backspacePressed = false;
if(et.length() <= 1) {
ignoreTextChange = true;
et.setText("b");
et.setSelection(1);
}
return;
}
if(ignoreTextChange) {
ignoreTextChange = false;
return;
}
else {
Logger.i("" + s.charAt(s.length() - 1));
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
};
我的Fragment
的onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
et = new InterceptTextView(getActivity());
et.addTextChangedListener(textWatcher);
ignoreTextChange = true;
et.setText("a");
et.setSelection(1);
return et;
}
我是这样做的。在我的InputConnection
中,我覆盖getTextBeforeCursor
以始终返回”
,这样IME总是认为至少有一个字符可以删除
我还将连接的输入类型设置为InputType.type_NULL
,以便传递关键事件(Google的官方解决方案)
我的自定义EditText
:
public class InterceptTextView extends EditText {
public interface OnBackspacePressListener {
public void onBackspacePressed();
}
private OnBackspacePressListener backspaceListener;
public InterceptTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setText(" ");
}
public void setOnBackspacePressListener(OnBackspacePressListener backspaceListener) {
this.backspaceListener = backspaceListener;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_DEL) {
if(backspaceListener != null) {
backspaceListener.onBackspacePressed();
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
outAttrs.actionLabel = null;
outAttrs.inputType = InputType.TYPE_NULL;
BaseInputConnection connection = new BaseInputConnection(this, false) {
@Override
public String getTextBeforeCursor(int ignore, int ignore2) {
return " ";
}
};
return connection;
}
}
我的片段
:
public class KeyFragment extends Fragment {
private static volatile boolean backspacePressed = false;
private InterceptTextView et;
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if(backspacePressed) {
backspacePressed = false;
return;
}
else {
Logger.i("" + s.charAt(s.length() - 1));
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.keyboard, null);
et = (InterceptTextView) v.findViewById(R.id.keyboard_input_sink);
et.setOnBackspacePressListener(new OnBackspacePressListener() {
@Override
public void onBackspacePressed() {
backspacePressed = true;
Logger.i("BCKSPC");
}
});
et.addTextChangedListener(textWatcher);
return v;
}
}
有没有办法将输入类型设置回原来的状态?我喜欢你的解决方法,但我需要一个caps键盘。据我所知,没有InputType.NULL它无法工作,但我可以再看一次。
public class KeyFragment extends Fragment {
private static volatile boolean backspacePressed = false;
private InterceptTextView et;
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if(backspacePressed) {
backspacePressed = false;
return;
}
else {
Logger.i("" + s.charAt(s.length() - 1));
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.keyboard, null);
et = (InterceptTextView) v.findViewById(R.id.keyboard_input_sink);
et.setOnBackspacePressListener(new OnBackspacePressListener() {
@Override
public void onBackspacePressed() {
backspacePressed = true;
Logger.i("BCKSPC");
}
});
et.addTextChangedListener(textWatcher);
return v;
}
}