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 ...
随机推荐
- Elasticsearch学习系列之配置文件详解
################################### Cluster ################################### #定义集群名称,默认是elasticse ...
- IntelliJ IDEA在行尾增加分号
IntelliJ IDEA在行尾增加分号 Ctrl+Shift+Enter - 本身的含义是自动完成,如果需要的话,会在行尾添加分号:
- Codeforces Round #271 (Div. 2) D. Flowers (递推 预处理)
We saw the little game Marmot made for Mole's lunch. Now it's Marmot's dinner time and, as we all kn ...
- 如何在其他js 引入main.js 中 vue 的实例?
1.原因解析 经测试发现,代码先执行了 index.js >> main.js >> Home.vue scr/api/index.js src/main.js src/co ...
- react 执行 yarn build 页面无法显示
资源文件路径问题 如果你使用create-react-app创建项目,执行命令 yarn build 后,直接以静态方式打开build文件夹内的index.html,会看到页面显示出现问题,打开con ...
- 科普:google的数字图书馆
https://books.google.com/ngrams Google Ngram Viewer,她利用google所拥有的所有图书作为资源,为你提供单词和短语历年使用次数的展示图标.数据化了数 ...
- 第一章:Android系统介绍android虚拟机
学习android,我们是要了解他的历史的,这里我也就不在累述什么大家都知道的东东了,简单的介绍下内部的相关内容: 1:android虚拟机 我们学习java知道java用的是JVM虚拟机,而开发An ...
- SpringMVC_2
web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=" ...
- [测试]单元测试框架NUnit
说到测试,相信大家都或多或少了解. 按照各自分类,就自己知道包括 A.单元测试.集成测试.系统测试 B.白盒测试.黑盒测试 C.压力测试.性能测试.安全测试 ...... 反正是太多太多.就做开发以来 ...
- 【BJOI 2018】 求和
[题目链接] 点击打开链接 [算法] 预处理i^k的前缀和,对于每次询问,树上倍增即可 时间复杂度 : O(nk + mlog(n)) [代码] #include<bits/stdc++.h&g ...