我需要在EditText
中引入数据,但我想使用虚拟键盘,而不是Android键盘。如果我使用setKeyListener(null)
,即使使用setCursorVisible(true)
后光标也不可见。
是否有可能使EditText
在哪里,即使它不可编辑,光标也可见?
编辑2: 我找到了一个部分方法来做到这一点,但是当我双击EditText时它不起作用。
我为setOnClickListner()
制作了setOnLongClickListner()
和EditText
方法。在这种方法中,我隐藏了窗口的软输入,我也使用setTextIsSelectable(false)
。我唯一的问题是当我双击EditText
软输入键盘显示而我不知道如何隐藏它时,我尝试在清单中使用android:windowSoftInputMode="stateAlwaysHidden"
,但它也不起作用。< / p>
编辑:
这是我目前用于基本转换器计算器的代码。
public class MainActivity extends AppCompatActivity {
EditText number;
EditText base;
boolean baseB = false;
String numberS = "0";
String baseS = "10";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_main);
//make the EditText for number and base not editable
number = (EditText) findViewById(R.id.number);
number.setKeyListener(null);
base = (EditText) findViewById(R.id.base);
base.setKeyListener(null);
//... more code here (changing fonts for each EditText and changing status bar color
}
// I have a function for each button all are the same
public void onClickBaseChange(View v) {
if (baseB) {
baseB = false;
// i use toasts at this moment to know when i'm on number or base field
Toast.makeText(this, "Number", Toast.LENGTH_SHORT).show();
} else {
baseB = true;
Toast.makeText(this, "Base", Toast.LENGTH_SHORT).show();
}
}
public void onClickB0(View v) {
if (numberS.length() > 0 && !numberS.equals("0") && !baseB) {
numberS += "0";
number = (EditText) findViewById(R.id.number);
number.setText(numberS, TextView.BufferType.EDITABLE);
number.setSelection(numberS.length());
} else {
if (Integer.valueOf(baseS) >= 1) {
baseS += "0";
base = (EditText) findViewById(R.id.base);
base.setText(baseS, TextView.BufferType.EDITABLE);
}
}
}
public void onClickB1(View v) {
if (numberS.equals("0")) {
numberS = "1";
} else {
numberS += "1";
}
number = (EditText) findViewById(R.id.number);
number.setText(numberS, TextView.BufferType.EDITABLE);
number.requestFocus();
number.setSelection(numberS.length());
}
xml看起来像这样:
<android.widget.RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/colorBackground"
tools:context="manastur.calculator.MainActivity">
<EditText
android:id="@+id/base"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:layout_marginTop="120dp"
android:background="@android:color/transparent"
android:cursorVisible="true"
android:text=""
android:textColor="@color/text"
android:textSize="30dp" />
<EditText
android:id="@+id/number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="30dp"
android:layout_marginTop="50dp"
android:background="@android:color/transparent"
android:cursorVisible="true"
android:text=""
android:textColor="@color/text"
android:textSize="50dp" />
<LinearLayout
android:id="@+id/secondRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/firstRow"
android:layout_centerHorizontal="true">
<Button
android:id="@+id/b1"
android:layout_width="85dp"
android:layout_height="85dp"
android:background="@drawable/b1"
android:onClick="onClickB1" />
<Button
android:id="@+id/b2"
android:layout_width="85dp"
android:layout_height="85dp"
android:background="@drawable/b2"
android:onClick="onClickB2" />
<!-- from this point on is the same, there are 5 LinearLayouts which
represents the 5 rows of button of the num pad -->
答案 0 :(得分:1)
使用此代码实现这一目标,
开发时我从原生Dialpad代码
中获取了参考资料KeypadlessKeypad.java
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.MotionEventCompat;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class KeypadlessKeypad extends EditText {
private static final Method mShowSoftInputOnFocus = getSetShowSoftInputOnFocusMethod(
EditText.class, "setShowSoftInputOnFocus", boolean.class);
public static Method getSetShowSoftInputOnFocusMethod(Class<?> cls, String methodName, Class<?>... parametersType) {
Class<?> sCls = cls.getSuperclass();
while (sCls != Object.class) {
try {
return sCls.getDeclaredMethod(methodName, parametersType);
} catch (NoSuchMethodException e) {
// Just super it again
}
sCls = sCls.getSuperclass();
}
return null;
}
private Context mContext;
/**
* Listener for Copy, Cut and Paste event
* Currently callback only for Paste event is implemented
*/
private OnEditTextActionListener mOnEditTextActionListener;
public KeypadlessKeypad(Context context) {
super(context);
mContext = context;
init();
}
public KeypadlessKeypad(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}
public KeypadlessKeypad(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
mContext = context;
init();
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
super.onSelectionChanged(selStart, selEnd);
}
public final void appendText(CharSequence text) {
append(text, 0, text.length());
}
/***
* Initialize all the necessary components of TextView.
*/
private void init() {
setSingleLine(true);
synchronized (this) {
setInputType(getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
setFocusableInTouchMode(true);
}
reflexSetShowSoftInputOnFocus(false); // Workaround.
// Ensure that cursor is at the end of the input box when initialized. Without this, the
// cursor may be at index 0 when there is text added via layout XML.
setSelection(getText().length());
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
hideKeyboard();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final boolean ret = super.onTouchEvent(event);
// Must be done after super.onTouchEvent()
hideKeyboard();
return ret;
}
private void hideKeyboard() {
final InputMethodManager imm = ((InputMethodManager) getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE));
if (imm != null && imm.isActive(this)) {
imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
}
}
private void reflexSetShowSoftInputOnFocus(boolean show) {
if (mShowSoftInputOnFocus != null) {
invokeMethod(mShowSoftInputOnFocus, this, show);
} else {
// Use fallback method. Not tested.
hideKeyboard();
}
}
public static Object invokeMethod(Method method, Object receiver, Object... args) {
try {
return method.invoke(receiver, args);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return null;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int textViewWidth = View.MeasureSpec.getSize(widthMeasureSpec);
int height = getMeasuredHeight();
this.setMeasuredDimension(textViewWidth, height);
}
@Override
protected void onTextChanged(CharSequence text, int start, int before,
int after) {
super.onTextChanged(text, start, before, after);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
}
@Override
public boolean onTextContextMenuItem(int id) {
boolean consumed = super.onTextContextMenuItem(id);
switch (id) {
case android.R.id.paste:
if (mOnEditTextActionListener != null) {
mOnEditTextActionListener.onPaste();
}
break;
}
return consumed;
}
/**
* Setter method for {@link #mOnEditTextActionListener}
*
* @param onEditTextActionListener
* Instance of the {@link OnEditTextActionListener}
*/
public void setOnEditTextActionListener(OnEditTextActionListener onEditTextActionListener) {
this.mOnEditTextActionListener = onEditTextActionListener;
}
private Rect mRect = new Rect();
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
final int action = MotionEventCompat.getActionMasked(event);
int[] location = new int[2];
getLocationOnScreen(location);
mRect.left = location[0];
mRect.top = location[1];
mRect.right = location[0] + getWidth();
mRect.bottom = location[1] + getHeight();
int x = (int) event.getX();
int y = (int) event.getY();
if (action == MotionEvent.ACTION_DOWN && !mRect.contains(x, y)) {
InputMethodManager input = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
input.hideSoftInputFromWindow(getWindowToken(), 0);
}
return super.dispatchTouchEvent(event);
}
@Override
public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
// Since we're replacing the text every time we add or remove a
// character, only read the difference. (issue 5337550)
final int added = event.getAddedCount();
final int removed = event.getRemovedCount();
final int length = event.getBeforeText().length();
if (added > removed) {
event.setRemovedCount(0);
event.setAddedCount(1);
event.setFromIndex(length);
} else if (removed > added) {
event.setRemovedCount(1);
event.setAddedCount(0);
event.setFromIndex(length - 1);
} else {
return;
}
} else if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
// The parent EditText class lets tts read "edit box" when this View has a focus, which
// confuses users on app launch (issue 5275935).
return;
}
super.sendAccessibilityEventUnchecked(event);
}
/**
* Interface to get callback from the Edittext copy, cut and paste event
* For time being only the Paste Event callback is generated
*/
public interface OnEditTextActionListener {
/**
* If Edittext get paste event then this method will be called
*/
void onPaste();
}
}
在你的xml中你可以这样给出,
<[package name].KeypadlessKeypad
android:id="@+id/dialnumbertv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000"
android:cursorVisible="false"
android:ellipsize="start"
android:gravity="center"
android:inputType="phone"
android:singleLine="true"
android:textIsSelectable="true"
android:textSize="30sp"
android:textStyle="italic"
android:visibility="visible"/>
在你的片段中你可以这样实现,
public void onViewCreated(final View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mDialNumbertv = view.findViewById(R.id.dialnumbertv);
mDialNumbertv.setCursorVisible(false);
mDialNumbertv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!isDigitsEmpty()) {
mDialNumbertv.setCursorVisible(true);
}
}
});
mDialNumbertv.addTextChangedListener(new TextWatcher() {
@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 void afterTextChanged(Editable s) {
if (isDigitsEmpty()) {
mDialNumbertv.setCursorVisible(false);
}
// updateDeleteButton();
}
});
mDialNumbertv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// Ref https://android.googlesource.com/platform/packages/apps/Contacts/+/39948dc7e34dc2041b801058dada28fedb80c388/src/com/android/contacts/dialpad/DialpadFragment.java
// Right now EditText does not show the "paste" option when cursor is not visible.
// To show that, make the cursor visible, and return false, letting the EditText
// show the option by itself.
mDialNumbertv.setCursorVisible(true);
return false;
}
});
mDialNumbertv.setOnEditTextActionListener(
new KeypadlessKeypad.OnEditTextActionListener() {
@Override
public void onPaste() {
// If some content pasted on mDialNumbertv
// we need to run some search on Contact and Price
String mobileNumber = mDialNumbertv.getText().toString();
if (TextUtils.isEmpty(mobileNumber)) {
return;
}
// updateContactName(mobileNumber);
}
});
}
private KeypadlessKeypad mDialNumbertv;
private boolean isDigitsEmpty() {
return mDialNumbertv.length() == 0;
}
private void setClickedDigit(final String digitToSet) {
if (!TextUtils.isEmpty(digitToSet)) {
char digit = digitToSet.charAt(0);
String mobileNumber = mDialNumbertv.getText() + digitToSet;
mDialNumbertv.getText().insert(mDialNumbertv.getSelectionStart(), digitToSet);
// If the cursor is at the end of the text we hide it.
final int length = mDialNumbertv.length();
if (length == mDialNumbertv.getSelectionStart() && length == mDialNumbertv.getSelectionEnd()) {
mDialNumbertv.setCursorVisible(false);
}
}
}
答案 1 :(得分:0)
您可以使用edittext.setselection(0)
或
也许您可以使用requestfocus()
请求焦点答案 2 :(得分:0)
我想要实现以下相同的行为-
创建一个自定义类,该类将覆盖AppCompatEditText的2个方法。
class CustomEditText(context: Context?, attrs: AttributeSet) : AppCompatEditText(context, attrs) {
override fun onCheckIsTextEditor(): Boolean {
return true
}
override fun isTextSelectable(): Boolean {
return true
}
}
在XML文件中,使用此自定义视图创建EditText。
<com.ui.custom.CustomEditText
android:id="@+id/et_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="none"
android:focusable="true"
android:gravity="center"
android:focusableInTouchMode="true"/>
现在,只需添加onFocusChangeListener并设置editText.setKeyListener = null。
binding.etEmail.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
binding.etEmail.keyListener = null
}
}
如果需要,您可以在onTouch上添加相同的内容。
这里的主要问题是View类的onCheckIsTextEditor()始终返回false,即使在代码中调用setCursorVisible(true)也会导致光标从不闪烁或不可见。
我希望这会有所帮助。