Android RecyclerView 中多Item的EditText监听 和 EditText焦点混乱的解决方法
来源:互联网 发布:mac 网络游戏 编辑:程序博客网 时间:2024/06/04 07:48
最近在做毕业设计,使用了RecyclerView来做了以下个人资料的编辑界面。RecyclerView中包含了多种不同的Item,例如图片里面的 姓名,公司,部门,职位,邮箱的Item 里面都包含一个EditText。
RecyclerView中EditText的监听处理
这个界面的主要逻辑是监听每个EditText的输入,然后保存到个人对象里,最后保存到服务器上。RecyclerView中Item里EditText的监听可以按如下代码实现:
首先定义个回调接口:
public interface onTextChangeListener { void onTextChanged(int pos,String str);}
在RecyclerView的自定义Adapter中添加一个如上自定义的接口成员变量mTextListener,然后在onBindViewHolder里面来添加Item中EditText的输入监听,即EditText.addTextChangedListener(),然后在监听事件回调里的afterTextChanged 方法中 调用 mTextListener.onTextChanged 来达到接口回调的目的。
public class EditListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ private Context mContext; private LayoutInflater mInflater; private ArrayList<EditListBean> mList; private onTextChangeListener mTextListener; public EditListAdapter(Context context, ArrayList<EditListBean> list){ this.mContext=context; mInflater=LayoutInflater.from(mContext); this.mList=list; } //设置自定义接口成员变量 public void setOnTextChangeListener(onTextChangeListener onTextChangeListener){ this.mTextListener=onTextChangeListener; } //创建ViewHolder @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { RecyclerView.ViewHolder holder=new itemHolder2(mInflater.inflate(R.layout.edit_recyclerview_item2,parent,false)); return holder; } //绑定ViewHolder @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { final itemHolder2 holder2= (itemHolder2) holder; holder2.title.setText(mList.get(position).getKey()); holder2.input.setText((String) mList.get(position).getValue()); holder2.input.setHint(mList.get(position).getHint()); //添加EditText的监听事件 holder2.input.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) { //通过接口回调将数据传递到Activity中 mTextListener.onTextChanged(position,holder2.input.getText().toString()); } }); //内部类 ViewHolder class itemHolder2 extends RecyclerView.ViewHolder{ TextView title; EditText input; public itemHolder2(View itemView) { super(itemView); title= (TextView) itemView.findViewById(R.id.EditActivity_item2_title); input= (EditText) itemView.findViewById(R.id.EditActivity_item2_text); } } @Override public int getItemCount() { return mList.size(); } @Override public int getItemViewType(int position){ return mList.get(position).getType(); } }
Activity中的代码实现,在mAdapter中添加匿名内部类来监听EditText中的接口回调数据:
mAdapter.setOnTextChangeListener(new onTextChangeListener() { @Override public void onTextChanged(int pos, String str) { //在这里拿到RecyclerView中Item的position和EditText中的变化 mPedit.setList(pos,str); Log.e(String.format("%d is ---->",pos),str); } });
OK 上面的监听事件处理完了 我们来试试效果怎么样。首先点击姓名里面的EditText,在马化腾后面输入哈哈哈哈 然后收起键盘, 可以发现竟然下面几个Item的EditText也触发了回调事件了,也就是我编辑了Item2的EditText,然后Item7 , 9 , 11的EditText也触发了onTextChanged的监听事件了。如图,出现了监听事件错乱的重大的Bug。
Recycler中 多Item中EditText焦点混乱的解决
1 在Adapter的onBindViewHolder为每个holder.EditText设置一个Tag(可以是当前holder的positon),然后在afterTextChanged中判断holder.EditText的Tag 是否与当前holder的position是否一致来调用自定义接口,也就是使用Tag来解决视图复用带来的错乱问题,这在ListView上一般的处理方法。
在RecyclerView上效果怎么样呢? 答案是无效的,依然EditText监听错乱。这个方案PASS,不能解决。
2 正确的处理方法
在AndroidManifast.xml中设置当前Activity的标签:
添加android:windowSoftInputMode=”stateHidden|adjustPan” 属性配置
<activity android:name="view.EditActivity" android:windowSoftInputMode="stateHidden|adjustPan"> //重点 <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="view.MyActivity"/>
来看看效果怎么样呢? 恩,很完美,现在编辑完Item2的EditText后,其他Item的EditText也不会触发监听了,那这属性配置(windowSoftInputMode)有什么作用呢??
windowSoftInputMode属性解析
android:windowSoftInputMode
Activity 的主窗口与包含屏幕软键盘的窗口的交互方式。 该属性的设置影响两个方面:
当 Activity 成为用户注意的焦点时软键盘的状态 — 隐藏还是可见。
对 Activity 主窗口所做的调整 — 是否将其尺寸调小以为软键盘腾出空间,或者当窗口部分被软键盘遮挡时是否平移其内容以使当前焦点可见“stateHidden” 当用户选择 Activity 时 — 也就是说,当用户确实是向前导航到 Activity,而不是因离开另一 Activity 而返回时 — 隐藏软键盘。
“adjustPan” 不调整 Activity 主窗口的尺寸来为软键盘腾出空间, 而是自动平移窗口的内容,使当前焦点永远不被键盘遮盖,让用户始终都能看到其输入的内容。 这通常不如尺寸调正可取,因为用户可能需要关闭软键盘以到达被遮盖的窗口部分或与这些部分进行交互。
没有设置了adjustPan属性的效果,Activity窗口位置不变,但是尺寸变小了,也就是键盘占了Activity的下半部分,导致RecyclerView的height变小了:
设置adjustPan属性的效果,Activity窗口尺寸不变,但是位置变了,平移到上面了:
了解了这个属性后就可以对 问题的来源和解决方法 得到一个很充分的认识了,最主要还是adjustPan 这个属性。当编辑完Item2后 收起键盘后,被键盘遮挡的item会重新调用onBindViewHolder 视图复用,导致其他Item中的EditText触发监听事件。设置了android:windowSoftInputMode= adjustPan 后 会使整个Activity窗口平移,不会导致Item 被刷新,自然也不会触发监听了。
- Android RecyclerView 中多Item的EditText监听 和 EditText焦点混乱的解决方法
- RecyclerView中item的EditText的监听
- Android ListView中嵌套EditText,随着软件盘的出现和消失,EditText焦点和内容混乱的问题
- Android EditText得到和失去焦点、内容变化的监听
- EditText失去焦点的监听
- ListView中item点击事件和item中radiobutton的点击editText输入焦点问题
- Android 中获取EditText控件的焦点以及监听他的内容让焦点自动跳转到下一个EditText控件
- Android EditText不获取焦点和监听
- Android ListView/recyclerView条目中EditText容易失去焦点的问题和取出横向时上下滚动有阴影
- Recyclerview item中有EditText使用刷新遇到的坑!!!!!
- Android开发中动态获取RecyclerView的Item中EditText的内容
- RecyclerView中item内有EditText监听addTextChangedListener出错
- Android listView中 editText 的 addTextChangedListener 和 OnItemClickListener 监听
- Android中ListView中item的EditText控件监听剩余字数
- android EditText 监听焦点变化
- Android EditText监听焦点事件
- android取消EditText的焦点
- Android 隐藏EditText的焦点
- HDU 5968
- 写给大数据开发初学者的话
- Vue.js要点记录(二)
- 多采样率信号处理 ——信号的抽取与插值
- DWR框架-----搭建
- Android RecyclerView 中多Item的EditText监听 和 EditText焦点混乱的解决方法
- Beautiful Year
- POJ 2785
- struts----------action之间的跳转(带参数)
- Office word 2013中直接调用MathType的方法
- GPIO模拟i2c时序
- 内联函数
- 泛函与变分
- 接口和抽象类的作用和区别