ListView修改item中EditText

    xiaoxiao2021-03-25  45

    今天朋友去面试,有一道机试题,让处理ListView中EditText输入混乱的问题,乘着闲时间写了个demo,下面说说原理 - 说明: ListView伴随的UI的改变,基本上getView方法一直处于动态刷新状态,item一直呈现出复用,对于一般数据的展示没问题,因为涉及不到动态改变数据,但是对于需要动态改变的EditText,如果不动态清空或动态获取EditText中的值,就会出现数据紊乱,所以我们必须时刻监听EditText值的变化

    创建对象,给两个数据name和age,等会我们让age放在输入框上 */ public class DemoBean implements Serializable { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } } Activity中,随意放,主要做一个假数据 private void initView() { lv_list = $(R.id.lv_list); ListEditAdapter adapter = new ListEditAdapter(getList(), this); lv_list.setAdapter(adapter); } ...... private List<DemoBean> getList() { List<DemoBean> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { DemoBean bean = new DemoBean(); bean.setName("小明" + (i + 1)); bean.setAge("年龄" + (i + 10)); list.add(bean); } return list; } 布局文件不多说,一个TextView,一个EditText,主要看下面的适配器 public class ListEditAdapter extends BaseAdapter { private LayoutInflater inflater; private Context mContext; private List<DemoBean> mList; public ListEditAdapter(List<DemoBean> list, Context mContext) { this.mContext = mContext; this.mList = list; inflater = LayoutInflater.from(mContext); } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } private Integer index = -1; @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = inflater.inflate(R.layout.item_test, null); holder = new ViewHolder(); holder.et_age = (EditText) convertView.findViewById(R.id.et_age); holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name); holder.et_age.setTag(position); holder.et_age.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { index = (Integer) v.getTag(); } return false; } }); final ViewHolder finalHolder = holder; holder.et_age.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 (!TextUtils.isEmpty(s.toString())){ //得到当前的Tag int pos = (int) finalHolder.et_age.getTag(); DemoBean bean = mList.get(pos); bean.setAge(s.toString()); } } }); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); holder.et_age.setTag(position); } DemoBean bean=mList.get(position); holder.tv_name.setText(bean.getName()); holder.et_age.setText(bean.getAge()); if (index != -1 && index == position) { holder.et_age.setFocusableInTouchMode(true); holder.et_age.requestFocus(); holder.et_age.setSelection(bean.getAge().length()); } return convertView; } class ViewHolder { TextView tv_name; EditText et_age; } } 我们将核心代码摘出来详细看一下,通过对et_age设置Tag标识【通过不重复的position】,这样复用item的时候保证et_age的唯一性通过EditText的==addTextChangedListener== 记录文本的改变,通过标识拿到具体改变的EditText对象,进而赋值给对应对象 private Integer index = -1; @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder.et_age.setTag(position); final ViewHolder finalHolder = holder; holder.et_age.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 (!TextUtils.isEmpty(s.toString())){ //得到当前的Tag int pos = (int) finalHolder.et_age.getTag(); DemoBean bean = mList.get(pos); bean.setAge(s.toString()); } } }); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); holder.et_age.setTag(position); } 当这样写完之后发现一个问题,EditText每次弹出软键盘的时候EditText都会失去焦点,这点也好理解,因为点击弹出键盘的时候ListView会发生重绘,导致焦点丢失,此处保存一下焦点的记录信息,手动赋予焦点通过OnTouch方法保存当前postition到index,在后面部分手动设置焦点 private Integer index = -1; @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder.et_age.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { index = (Integer) v.getTag(); } return false; } }); //省略... } else { //省略.... } //省略.... if (index != -1 && index == position) { holder.et_age.setFocusableInTouchMode(true); holder.et_age.requestFocus(); holder.et_age.setSelection(bean.getAge().length()); } return convertView; }
    转载请注明原文地址: https://ju.6miu.com/read-38947.html

    最新回复(0)