Android RecyclerView嵌套EditView实时更新Item数据
一、场景(例如:购物车)
1、当我们需要以列表样式管理某些数据时,可能需要列表项的某个字段可编辑
2、编辑Item上的某个字段后可能还要更新相关字段的值
二、可能遇到的问题
1、列表滑动导致输入框中的数据错位(或者焦点错位)
2、无法更新Item上相关的字段项的值
3、监听输入框文本更改时陷入死循环
三、可行方案(RecyclerView+TextWatcher)
1、用RecyclerView 实现一个ListView的效果:
package com.zhn.edit.recycler; import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem; import java.util.ArrayList;
import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener,
EditAbleListAdapter.EditAbleListAdapterListener{ private FloatingActionButton mFLoatingBtnEmail; private RecyclerView mRecyclerEditAble;
private LinearLayoutManager mEditAbleLayoutManager;
private EditAbleListAdapter mEditAbleListAdapter;
private List<datagoods> mDataGoods=new ArrayList<datagoods>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mFLoatingBtnEmail = (FloatingActionButton) findViewById(R.id.floating_btn_email);
mFLoatingBtnEmail.setOnClickListener(this); mRecyclerEditAble= (RecyclerView) findViewById(R.id.recycler_editable); initData(); } private void initData() {
mEditAbleLayoutManager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
mRecyclerEditAble.setLayoutManager(mEditAbleLayoutManager);
mEditAbleListAdapter=new EditAbleListAdapter(this,this);
mRecyclerEditAble.setAdapter(mEditAbleListAdapter); for (int i=;i<;i++){
mDataGoods.add(new DataGoods("Goods"+i,i,i,i*i));
} mEditAbleListAdapter.refreshDatas(mDataGoods);
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.floating_btn_email:
for (int i=;i<mdatagoods.size();i++){
log.e(mainactivity.class.getsimplename(),mdatagoods.get(i).tostring());="" }="" break;="" default:="" @override="" public="" void="" onedittextchanged(int="" position,="" string="" value)="" {="" todo="" 此处或者回调前应做值合法性验证="" mdatagoods.get(position).setnum(integer.parseint(value));="" <="" pre=""></mdatagoods.size();i++){></datagoods></datagoods>
2、在Adapter中自定义一个Interface 用来将输入的值回传给Activity
3、定义TxtWatcher 接收position和要同步更新的文本框
4、给EditText添加焦点变化的监听器,根据焦点状态绑定和解绑TxtWatcher
package com.zhn.edit.recycler; import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView; import java.util.ArrayList;
import java.util.List; /**
* Created by zhn
* 2017/7/9 下午4:20
*/
public class EditAbleListAdapter extends RecyclerView.Adapter{ public void refreshDatas(List<datagoods> mDataGoods) {
mDatas.clear();
mDatas.addAll(mDataGoods);
notifyDataSetChanged();
} public interface EditAbleListAdapterListener{
public void onEditTextChanged(int position,String value);
} private Context mContext;
private List<datagoods> mDatas=new ArrayList<datagoods>(); private EditAbleListAdapterListener mListener;
public EditAbleListAdapter(Context context,EditAbleListAdapterListener listener){
this.mContext=context;
this.mListener=listener;
} @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new EditAbleListViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_editable_view,null));
} @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((EditAbleListViewHolder)holder).setContent(position,mDatas.get(position)); } @Override
public int getItemCount() {
return mDatas.size();
} public class EditAbleListViewHolder extends RecyclerView.ViewHolder{ private TextView mTvItemNo;
private TextView mTvGoodsName;
private TextView mTvPrice;
private EditText mEtNum;
private TextView mTvTotalPrice; private TxtWatcher mTxtWatcher; public EditAbleListViewHolder(View itemView) {
super(itemView); mTvItemNo= (TextView) itemView.findViewById(R.id.tv_item_no);
mTvGoodsName= (TextView) itemView.findViewById(R.id.tv_goods_name);
mTvPrice= (TextView) itemView.findViewById(R.id.tv_price);
mEtNum= (EditText) itemView.findViewById(R.id.et_num);
mTvTotalPrice= (TextView) itemView.findViewById(R.id.tv_total_price); mTxtWatcher=new TxtWatcher();
} public void setContent(int position,DataGoods data){ mTvItemNo.setText(String.valueOf(position+));
mTvGoodsName.setText(data.getGoodsName());
mTvPrice.setText(String.valueOf(data.getPrice()));
mEtNum.setText(String.valueOf(data.getNum()));
mTvTotalPrice.setText(String.valueOf(data.getTotalPrice())); mTxtWatcher.buildWatcher(position,mTvTotalPrice); mEtNum.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus){
mEtNum.addTextChangedListener(mTxtWatcher);
}else{
mEtNum.removeTextChangedListener(mTxtWatcher);
}
}
});
} } public class TxtWatcher implements TextWatcher{ private int mPosition;
private TextView mTvTotalPrice; public void buildWatcher(int position,TextView view){
this.mPosition=position;
this.mTvTotalPrice=view;
} @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.length()>){
if(mListener!=null){
mListener.onEditTextChanged(mPosition,s.toString());
mTvTotalPrice.setText(String.valueOf(mDatas.get(mPosition).getPrice()*Double.parseDouble(s.toString())));
}
}else{
if(mListener!=null){
mListener.onEditTextChanged(mPosition,"");
mTvTotalPrice.setText("");
}
}
} @Override
public void afterTextChanged(Editable s) { }
} }
四、选择RecyclerView而不是ListView的原因
RecyclerView 在滑动的时候会使EditText失去焦点,这样可以触发OnFocusChangeListener,这样可以更准确的绑定和解绑TxtWatcher。为什么要解绑TxtWatcher?因为在RecyclerView刷新的时候会重复触发TextWatcher导致很多次无用的回调(甚至死循环)。
ListView在滑动的时候不会使EditText失去焦点,导致了滑动时输入框焦点错位,并且因为输入框是复用的所以导致TextWatcher重复触发很多次(可能是死循环)。
五、注意在布局中设置列表是尽量降低RecyclerView布局重绘的可能性(例如:固定大小等等)
Android RecyclerView嵌套EditView实时更新Item数据的更多相关文章
- android ListView中含有按钮事件实时更新ListView数据案例
1.布局文件Listview <?xml version="1.0" encoding="utf-8"?> <android.support. ...
- Android网络开发之实时获取最新数据
在实际开发中更多的是需要我们实时获取最新数据,比如道路流量.实时天气信息等,这时就需要通过一个线程来控制视图的更新. 示例:我们首先创建一个网页来显示系统当前的时间,然后在Android程序中每隔5秒 ...
- Android RecyclerView嵌套RecyclerView
原理 RecyclerView嵌套RecyclerView的条目,项目中可能会经常有这样的需求,但是我们将子条目设置为RecyclerView之后,却显示不出来.自己试了很久,终于找到了原因:必须先设 ...
- WebSocket 实时更新mysql数据到页面
使用websocket的初衷是,要实时更新mysql中的报警信息到web页面显示 没怎么碰过web,代码写的是真烂,不过也算是功能实现了,放在这里也是鞭策自己,web也要多下些功夫 准备 引入依赖 & ...
- Python tkinter库将matplotlib图表显示在GUI窗口上,并实时更新刷新数据
代码 1 ''' 2 使用matplotlib创建图表,并显示在tk窗口 3 ''' 4 import matplotlib.pyplot as plt 5 from matplotlib.pylab ...
- Web实时更新客户端数据
1 轮询方式实现客户端数据及时更新 在基于Web的即时通信.股票行情这样的系统中,需要客户端能够及时更新内容.由于B/S架构的特性(Http连接是无状态连接, 即服务器处理完客户的请求, ...
- solr实时更新mysql数据的方法
第一步:创建core core是solr的特有概念,每个core是一个查询数据,.索引等的集合体,你可以把它想象成一个独立数据库,我们创建一个新core:名字[core1] 进入linux命令行,进入 ...
- WinForm DataGridView实时更新表格数据
前言 一个特殊的项目没有用第三方控件库,但用到了DataGridView,由于是客户端产生的数据,所以原始数据源就是一个集合. 根据需要会向集合中添加数据项,或是修改某些数据项的值,但DataGrid ...
- Jquery无刷新实时更新表格数据
html代码: <style> .editbox { display:none } .editbox { font-size:14px; width:70px; background-co ...
随机推荐
- Sql查询一个列对应多个列
Sql查询一个列对应多个列 今天遇到一个问题,表table1有两个字段col1.col2两个字段.先记录下来,以后有个参考. 现在需要查询出的数据满足如下要求: 1.col1重复.col2重复的数据只 ...
- jquery校验框架
http://www.validform.club/ http://craftpip.github.io/jquery-confirm/
- Android之AssetManager使用
1. 获取AssetManager AssetManager assetManager = context.getAssets(); 2. 列出assets文件夹下全部文件 String[] file ...
- centos7 禁止 root ssh login
CentOS 7 默认容许任何帐号透过 ssh 登入,包括 root 和一般帐号,为了不让 root 帐号被黑客暴力入侵,我们必须禁止 root 帐号的 ssh 功能,事实上 root 也没有必要 s ...
- 【cocos2d-x 3.7 飞机大战】 决战南海I (三) 敌机实现
如今来实现敌机类 敌机和我方飞机相似,具有生命值.能够发射子弹.而且有自己的运动轨迹.事实上能够为它们设计一个共同的基类,这样能够更方便扩展. 不同的敌机,应设置不同的标识.属性 // 敌机生命值 c ...
- 使用shell分页读取600万+的MySQL数据脚本
shell-mysql 脚本背景 因为要在Linux上.远程读取mysql的表的数据,然后做一定清洗后.把数据上传至Hadoop集群中,使用Java写吧,感觉太麻烦了.得在Win上开发好,还得打成ja ...
- 改动ScrollView的滑动速度和解决ScrollView与ViewPager的冲突
话不多说,非常easy,能够从凝视中知道做法,直接上代码: 1.改动ScrollView的滑动速度: public class MyHorizontalScrollView extends Horiz ...
- 自己定义ViewGroup控件(一)----->流式布局进阶(一)
main.xml <? xml version="1.0" encoding="utf-8"?> <com.example.SimpleLay ...
- go4--break,continue + 标签
package main /* 指针 Go虽然保留了指针,但与其它编程语言不同的是,在Go当中不 支持指针运算以及”->”运算符,而直接采用”.”选择符来操作指针 目标对象的成员 操作符”&am ...
- 编程细节 —— 按值传递、按引用传递(final、const)
System.out,out 是 System 类内定义的静态 final PrinterStream 变量: public final class System { ... public final ...