EditText的进阶运用
EditText 是咱们常用的输入框控件,平常咱们只是运用它输入文本,这儿记录一些它不太常见的操作和一些解决方案。
一、焦点的主动获取
假如一个页面内界说了EditText,那么有或许咱们进入此页面的时分会主动弹起软键盘,(分机型,有的会弹,有的不弹)。假如咱们需求弹软键盘,咱们制定给 EditText 设置
android:focusable="true" android:focusableInTouchMode="true"
可是假如咱们不想这个页面进去就弹出软键盘,咱们能够给根布局或许 EditText缓存英文 的父布局设置 focusable 。
二、光标和背景的操控
默许的 EditText 是带下划线和粗光标的,咱们能够对它们进行简略的修改
android:background="@null" //去掉了下划线 android:textCursorDrawable="@null" //去掉光标的色彩
自界说光标的色彩和宽度:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="2dp" />
<solid android:color="#BDC7D8" />
</shape>
运用自界说光标
android:textCursorDrawable="@drawable/edittext_cursor"
三、约束小数点位数
咱们能够经过监听 EditText 的文本改动的办法来改动文本值,咱们还能经过产品策略 DigitsKeyList输入框变成黑色怎么办ener 的办法监听文本的改动。
3.1 TextWatcher的办法
咱们能够经过监听 EditText 的文本改动,比方咱们只想要小数点后边2位数,咱们就监听文本改动,点后边的2位数,假如多了就把他删去掉。
public class MoneyTextWatcher implements TextWatcher { private EditText editText; private int digits = 2; public MoneyTextWatcher(EditText et) { editText = et; } public MoneyTextWatcher setDigits(int d) { digits = d; return this; } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { //删去“.”后边超越2位后的数据 if (s.toString().contains(".")) { if (s.length() - 1 - s.toString().indexOf(".") > digits) { s = s.toString().subSequence(0, s.toString().indexOf(".") + digits+1); editText.setText(s); editText.setSelection(s.length()); //光标移到最后 } } //假如"."在开始方位,则开始方位主动补0 if (s.toString().trim().substring(0).equals(".")) { s = "0" + s; editText.setText(s); editText.setSelection(2); } //假如开始方位为0,且第二位跟的不是".",则无法后续输入 if (s.toString().startsWith("0") && s.toString().trim().length() > 1) { if (!s.toString().substring(1, 2).equals(".")) { editText.setText(s.subSequence(0, 1)); editText.setSelection(1); return; } } } @Override public void afterTextChanged(Editable s) { } }
运用:
//默许两位小数 mEditText.addTextChangedListener(new MoneyTextWatcher(mEditText1)); //手动设置其他位数,例如3 mEditText.addTextChangedListener(new MoneyTextWatcher(mEditText1).setDigits(3);
3.2 DigitsKeyListener的办法
public class ETMoneyValueFilter extends DigitsKeyListener { public ETMoneyValueFilter(int d) { super(false, true); digits = d; } private int digits = 2; //默许显现二位数的小数点 public ETMoneyValueFilter setDigits(int d) { digits = d; return this; } @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { CharSequence out = super.filter(source, start, end, dest, dstart, dend); if (out != null) { source = out; start = 0; end = out.length(); } int len = end - start; if (len == 0) { return source; } //以点开始的时分,主动在前面增加0 if (source.toString().equals(".") && dstart == 0) { return "0."; } //假如开始方位为0,且第二位跟的不是".",则无法后续输入 if (!source.toString().equals(".") && dest.toString().equals("0")) { return ""; } int dlen = dest.length(); for (int i = 0; i < dstart; i++) { if (dest.charAt(i) == '.') { return (dlen - (i + 1) + len > digits) ? "" : new SpannableStringBuilder(source, start, end); } } for (int i = start; i < end; ++i) { if (source.charAt(i) == '.') { if ((dlen - dend) + (end - (i + 1)) > digits) return ""; else break; } } return new SpannableStringBuilder(source, start, end); } }
其实是和 TextWatcher 相似的办法,那么运用的时分咱们这样运用:
//默许两位小数 mEditText.setFilters(new InputFilter[]{new MoneyValueFilter()}); //手动设置其他位数,例如3 mEditText.setFilters(new InputFilter[]{new MoneyValueFilter().setDigits(3)});
在Kotlin代码中是这样运用:
et_input.filters = arrayOf(ETMoneyValueFilter().setDigits(3))
这样就能够完结小数点后边二位数的操控,还google顺便加入了.的判别,主动加0的操作。
四、EditText的Search操作
当此 EditText 软键盘弹起的时分,右输入框样式下角的确认变为查找,咱们需求给 E工商银行电话人工客服ditText 设置一个特点:
android:imeOptions="actionSearch"
然后给软键盘设置一个监听
//点击软键盘查找按钮 etSearch.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_ENTER) { // 先躲藏键盘 ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)) .hideSoftInputFromWindow(TransactionHistorySearchActivity.this.getCurrentFocus() .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); if (isSearch){ isSearch = false; if (!TextUtils.isEmpty(etSearch.getText().toString())) searchHistory(etSearch.getText().toString()); } } return false; } });
这儿运用一个flag来判别,是因为部分机型会回调2次。所以为了一致作用,咱们运用github拦截判别只调用一次。
当然Search的逻辑假如你运用 Kotlin + DataBinding 来完结,那么就更简略了。
//执行查找 fun doSearch() { KeyboardUtils.hideSoftInput(mActivity) scrollTopRefresh() } //查找的删去 fun searchDel() { mViewModel.mKeywordLiveData.value = "" doSearch() }
<LinearLayout
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_marginLeft="@dimen/d_15dp"
android:background="@drawable/shape_search_gray_bg_corners20"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="@dimen/d_16dp"
android:layout_height="@dimen/d_16dp"
android:layout_marginLeft="@dimen/d_12dp"
android:src="@drawable/search_icon"
binding:clicks="@{click.doSearch}" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_12dp"
android:layout_weight="1"
android:background="@color/transparent"
android:hint="咱们都在搜"
android:imeOptions="actionSearch"
android:singleLine="true"
android:text="@={viewModel.mKeywordLiveData}"
android:textColor="@color/black"
android:textColorHint="@color/gray_99"
android:textSize="@dimen/d_14sp"
binding:onKeyEnter="@{click.doSearch}"
binding:typefaceMedium="@{true}" />
<ImageView
android:layout_width="@dimen/d_16dp"
android:layout_height="@dimen/d_16dp"
android:layout_marginRight="@dimen/d_10dp"
android:src="@drawable/search_delete"
android:visibility="gone"
binding:clicks="@{click.searchDel}"
binding:isVisibleGone="@{!TextUtils.isEmpty(viewModel.MKeywordLiveData)}" />
</LinearLayout>
首要的 Binding Adapter 办法为 onKeyEnter ,它Git完结了软键盘的查找。
下面giti是自界说BindingAdapter的办法:
var _viewClickFlag = false var _clickRunnable = Runnable { _viewClickFlag = false } /** * Edit的确认按键事情 */ @BindingAdapter("onKeyEnter") fun EditText.onKeyEnter(action: () -> Unit) { setOnKeyListener { _, keyCode, _ -> if (keyCode == KeyEvent.KEYCODE_ENTER) { KeyboardUtils.closeSoftKeyboard(this) if (!_viewClickFlag) { _viewClickFlag = true action() } removeCallbacks(_clickRunnable) postDelayed(_clickRunnable, 1000) } return@setOnKeyListener false } }
和上面Java的完结办法相似,相同的做了防抖的操缓存文件夹名称作。为了部分机型连续调用屡次的问题。
作用:

五、焦点与软键盘的自由操控
上面提到的焦点,不主动弹出软键盘,假如我想自由的操控焦点与软键盘怎么办?
一个例子输入框来说明,比方咱们的需求,点击 EditText 的时分弹出弹框提示用户注意事项,当点击确认或许取消之后再持续输入。分化过程如下:
- 咱们点击EditText不能弹出软键盘
- 监听焦点获取之后弹出弹框
- 弹框完结之后咱们需求手动的给EditTex缓存视频合并t焦点
- 获取焦点之后需求设置光标与软键盘
代码逻辑如下:
mBankAccountEt.setShowSoftInputOnFocus(false); mBankAccountEt.setOnFocusChangeListener((v, hasFocus) -> { if (hasFocus && !isShowedBankAccountNotice) { showBankAccountNoticePopup(); } }); private void showBankAccountNoticePopup() { BasePopupView mPopupView = new XPopup.Builder(mActivity) .moveUpToKeyboard(false) .hasShadowBg(true) .asCustom(new BankNameNoticePopup(mActivity, () -> { isShowedBankAccountNotice = true; mBankAccountEt.setShowSoftInputOnFocus(true); //需求把焦点设置回EditText mBankAccountEt.setFocusable(true); mBankAccountEt.setFocusableInTouchMode(true); mBankAccountEt.requestFocus(); mBankAccountEt.setSelection(mBankAccountEt.getText().toString().length()); KeyboardUtils.showKeyboard(mBankAccountEt); })); if (mPopupView != null && !mPopupView.isShow()) { mPopupView.show(); } }
弹框就不给咱们展现了,十分简略的弹窗,界说运用的弹窗库,逻辑都在完结的回调中。
KeyboardUtils东工资超过5000怎么扣税西类,操控EditText的软键盘展现与躲藏
/* * 显现键盘 * */ public static void showKeyboard(View view) { InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { view.requestFocus(); imm.showSoftInput(view, 0); } } /* * 躲藏键盘 * */ public static void hideKeyboard(View view){ InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (imm != null) { imm.hideSoftInputFromWindow(view.getWindowToken(),0); } }
作用:

六、RV + EditText复用的问题
不知道咱们有没有在RV中运用过 EditText ,Item中假如有 EditText 那么在滚出屏幕之后 再拉回来或许方才输入的文本就消失了,或许换成不是方才输入的文本了,是因为缓存复用,或许复用了其他Item上产品面的 EditText 控件。
有几种解决办法如下:
办法一: 强制的停用Recyclerview的复用
helper.setIsRecyclable(false);
可是RV就无法缓存与回收了,gitee假如你的Item数量就是固定的并且不多,那么运用产品经理这个办法是最好的。
办法二:缓存清理 经过监听焦点来增加或移除E微信输入框dittext的TextChangedListener
@Override protected void convert(BaseViewHolder helper, EdittextInRecyclerViewOfBean item) { EditText editText = helper.getView(R.id.et); editText.setText(item.getNum() + ""); TextWatcher textWatcher = 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 (TextUtils.isEmpty(s.toString())) { item.setNum(0); } else { item.setNum(Integer.parseInt(s.toString())); } } }; editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus){ editText.addTextChangedListener(textWatcher); }else { editText.removeTextChangedListener(textWatcher); } } }); }
办法三: 经过view的setTag()办法解决
@Override protected void convert(BaseViewHolder helper, EdittextInRecyclerViewOfBean item) { TextWatcher textWatcher = 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 (TextUtils.isEmpty(s.toString())) { item.setNum(0); } else { item.setNum(Integer.parseInt(s.toString())); } } }; EditText editText = helper.getView(R.id.et); //为了避免TextWatcher在调用settext()时被调用,提前将它移除 if (editText.getTag() instanceof TextWatcher) { editText.removeTextChangedListener((TextWatcher) editText.getTag()); } editText.setText(item.getNum() + ""); //从头增加上TextWatcher监听 editText.addTextChangedListener(textWatcher); //将TextWatcher绑定到EditText editText.setTag(textWatcher); }
办法四:工商银行 为每个Edi缓存视频怎样转入相册tText的绑定方位
public class EditTextInRecyclerViewAdapter extends RecyclerView.Adapter {
private List<EdittextInRecyclerViewOfBean> mList = new ArrayList<>();
public void setData(List<EdittextInRecyclerViewOfBean> list) {
this.mList = list;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_edittext, parent, false);
return new ViewHolder(v, new ITextWatcher());
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
ViewHolder viewHolder = (ViewHolder) holder;
viewHolder.mITextWatcher.bindPosition(position);
viewHolder.mEditText.setText(mList.get(position).getNum()+"");
}
@Override
public int getItemCount() {
return mList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
EditText mEditText;
ITextWatcher mITextWatcher;
private ViewHolder(View v, ITextWatcher watcher) {
super(v);
this.mEditText = v.findViewById(R.id.et);
this.mITextWatcher = watcher;
this.mEditText.addTextChangedListener(watcher);
}
}
class ITextWatcher implements TextWatcher {
private int position;
private void bindPosition(int position) {
this.position = position;
}
@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 (TextUtils.isEmpty(s.toString())) {
mList.get(position).setNum(0);
} else {
mList.get(position).setNum(Integer.parseInt(s.toString()));
}
}
}
}
办法五: 构造办法中增加TextChanged宫颈癌
class PicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { var ivPic: ImageView = itemView.findViewById(R.id.ivPic) var etScore: EditText = itemView.findViewById(R.id.etScore) var tvTitle: TextView = itemView.findViewById(R.id.tvTitle) var myTextWatcher: MyTextWatcher = MyTextWatcher() init { etScore.addTextChangedListener(myTextWatcher) } fun updateView(picItem: PicItem) { myTextWatcher.picItem = picItem ivPic.setImageResource(picItem.picResId) tvTitle.text = picItem.title if (picItem.score == null) { etScore.hint = "请输入分数" etScore.setText("") } else { etScore.setText(picItem.score) } } } class MyTextWatcher: TextWatcher { lateinit var picItem:PicItem override fun afterTextChanged(s: Editable?) { picItem?.apply { score=s?.toString() } } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { } }
办法六: 让产品改需求,不要运用EditText,或许咱们爽性运用T缓存视频怎样转入相册extView,然后点击Item弹出输入框的弹框办法来完结。
后记
总结缓存视频怎样转入相册了很多 EditText 不常见的一些问题与解决方案,不知道咱们有没有遇到其他问题,或许一些 Edi工商银行tText 的骚操作,都能够评论区留言弥补哦!
关于 EditText 的分享就到这儿了,后边假如有弥补我会持续更新!
完结.

我正在参加技能社区创作者签约计划招募活动,点击链接报名投稿。
评论(0)