RecycleView使用EditText的数据和焦点错乱问题解决方案
程序员文章站
2022-06-21 19:18:29
RecycleView是常用的列表控件,在日常的开发中使用频率很高,使用起来很方便,只要设置好条目布局和数据就可以完美的展示数据。EditText是常用的输入控件,用于用户的数据输入。二者本来各自使用都很容易,但是如果放到一起就出现问题,条目的复用导致EditText输入的内容出现错乱,焦点的获取也混乱了,令很多新手大为头疼。基本的思路是要在条目的可见和隐藏时处理好焦点的问题,要将操作的EditText的位置坐标记录下来,进行有效管理,还有将输入框的显示和隐藏也管理起来。解决的代码本身并不复杂,注释也标...
RecycleView是常用的列表控件,在日常的开发中使用频率很高,使用起来很方便,只要设置好条目布局和数据就可以完美的展示数据。EditText是常用的输入控件,用于用户的数据输入。二者本来各自使用都很容易,但是如果放到一起就出现问题,条目的复用导致EditText输入的内容出现错乱,焦点的获取也混乱了,令很多新手大为头疼。
基本的思路是要在条目的可见和隐藏时处理好焦点的问题,要将操作的EditText的位置坐标记录下来,进行有效管理,还有将输入框的显示和隐藏也管理起来。解决的代码本身并不复杂,注释也标识出来了。之前写过一个List View和EditText搭配使用的文章,这里算是更新吧,并且输入框也增加了多个输入框的处理逻辑。
核心的Adapter代码如下:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String TAG="MyAdapter";
private List<ItemDataEntity> list;
private Context mContext;
private final InputMethodManager inputMethodManager;
//edittext的焦点position位置
int etFocusPos = -1;
private int idSelectView=-1;
public MyAdapter(List<ItemDataEntity> list, Context mContext) {
this.list = list;
this.mContext = mContext;
inputMethodManager = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, null);
ViewHolder viewHolder = new ViewHolder(inflate);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
holder.tvNum.setText("序号:"+list.get(position).getNum());
holder.tvName.setText("姓名:"+list.get(position).getName());
holder.etAge.setText(list.get(position).getAge());
holder.etaddress.setText(list.get(position).getAddress());
holder.etaddress.addTextChangedListener(textWatcher);
holder.etAge.addTextChangedListener(textWatcher);
//当焦点获取或取消时
holder.etaddress.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if (b){
idSelectView = view.getId();
etFocusPos = position;
Log.i(TAG,"etFocusPos焦点选中-"+etFocusPos);
}
}
});
//当焦点获取或取消时
holder.etAge.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if (b){
idSelectView = view.getId();
etFocusPos = position;
Log.i(TAG,"etFocusPos焦点选中-"+etFocusPos);
}
}
});
}
/**
* 当适配器创建的view(即列表项view)划出屏幕,不可见时调用
* @param holder
*/
@Override
public void onViewDetachedFromWindow(ViewHolder holder) {
super.onViewDetachedFromWindow(holder);
Log.i(TAG,"隐藏item="+holder.getAdapterPosition());
//根据点击的不同editextview 处理焦点和监听
if (idSelectView==R.id.et_address){
holder.etaddress.removeTextChangedListener(textWatcher);
holder.etaddress.clearFocus();
}else if (idSelectView==R.id.et_age){
holder.etAge.removeTextChangedListener(textWatcher);
holder.etAge.clearFocus();
}
//当条目不可见时,重置焦点position,隐藏键盘
if (etFocusPos == holder.getAdapterPosition()) {
inputMethodManager.hideSoftInputFromWindow(((ViewHolder) holder).etaddress.getWindowToken(), 0);
etFocusPos=-1;
}
}
/**
* edittextview的文本监听
*/
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) {
//每次修改文字后,保存在数据集合中
Log.i(TAG,"index="+etFocusPos+",save="+s.toString());
if (!TextUtils.isEmpty(s.toString())&&etFocusPos!=-1){
if (idSelectView==R.id.et_address){
list.get(etFocusPos).setAddress(s.toString());
}else if (idSelectView==R.id.et_age){
list.get(etFocusPos).setAge(s.toString());
}
}
}
};
/**
* 当列表项出现到可视界面的时候调用
* @param holder
*/
@Override
public void onViewAttachedToWindow(ViewHolder holder) {
super.onViewAttachedToWindow(holder);
Log.i(TAG,"显示item="+holder.getAdapterPosition());
if (idSelectView==R.id.et_age){
holder.etAge.addTextChangedListener(textWatcher);
}else if (idSelectView==R.id.et_address){
holder.etaddress.addTextChangedListener(textWatcher);
}
//根据点击的位置,处理焦点和光标位置
if (etFocusPos == holder.getAdapterPosition()) {
if (idSelectView==R.id.et_age){
holder.etAge.requestFocus();
holder.etAge.setSelection(holder.etAge.getText().length());
}else if (idSelectView==R.id.et_address){
holder.etaddress.requestFocus();
holder.etaddress.setSelection(holder.etaddress.getText().length());
}
}
}
@Override
public int getItemCount() {
return list == null ? 0 : list.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView tvNum;
private TextView tvName;
private EditText etAge;
private EditText etaddress;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tvNum = itemView.findViewById(R.id.tv_num);
tvName = itemView.findViewById(R.id.tv_name);
etAge = itemView.findViewById(R.id.et_age);
etaddress = itemView.findViewById(R.id.et_address);
}
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
xmlns:tool="http://schemas.android.com/tools"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_num"
tool:text="001"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_name"
android:layout_marginLeft="10dp"
tool:text="tom"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/et_age"
android:layout_marginLeft="10dp"
android:layout_width="80dp"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/et_address"
android:layout_marginLeft="10dp"
android:layout_width="80dp"
android:layout_height="wrap_content" />
</LinearLayout>
展示的逻辑:
ArrayList<ItemDataEntity> itemDataEntities = new ArrayList<>();
for (int i=0;i<50;i++){
ItemDataEntity itemDataEntity = new ItemDataEntity();
itemDataEntity.setName("T"+i);
itemDataEntity.setNum(""+i);
itemDataEntities.add(itemDataEntity);
}
RecyclerView recyclerView=findViewById(R.id.recycleview);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplication());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
MyAdapter myAdapter = new MyAdapter(itemDataEntities, getApplication());
recyclerView.setAdapter(myAdapter);
本文地址:https://blog.csdn.net/qiantanlong/article/details/108709516