博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android RecyclerView嵌套EditView实时更新Item数据
阅读量:4641 次
发布时间:2019-06-09

本文共 6933 字,大约阅读时间需要 23 分钟。

一、场景(例如:购物车)

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
mDataGoods=new ArrayList
(); @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=1;i<11;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=0;i
<="" pre="">

       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
mDataGoods) { mDatas.clear(); mDatas.addAll(mDataGoods); notifyDataSetChanged(); } public interface EditAbleListAdapterListener{ public void onEditTextChanged(int position,String value); } private Context mContext; private List
mDatas=new ArrayList
(); 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+1)); 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()>0){ 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,"0"); mTvTotalPrice.setText("0"); } } } @Override public void afterTextChanged(Editable s) { } }}

四、选择RecyclerView而不是ListView的原因

        RecyclerView 在滑动的时候会使EditText失去焦点,这样可以触发OnFocusChangeListener,这样可以更准确的绑定和解绑TxtWatcher。为什么要解绑TxtWatcher?因为在RecyclerView刷新的时候会重复触发TextWatcher导致很多次无用的回调(甚至死循环)。

        ListView在滑动的时候不会使EditText失去焦点,导致了滑动时输入框焦点错位,并且因为输入框是复用的所以导致TextWatcher重复触发很多次(可能是死循环)。

五、注意在布局中设置列表是尽量降低RecyclerView布局重绘的可能性(例如:固定大小等等)

转载于:https://www.cnblogs.com/zhujiabin/p/8176915.html

你可能感兴趣的文章
谈谈对web标准的理解
查看>>
求二进制中1的个数(编程之美2.1)
查看>>
58前端内推笔试2017(含答案)
查看>>
Java学习笔记
查看>>
sprintf 和strcpy 的差别
查看>>
打表打表何谓打表?
查看>>
MPEG4与.mp4
查看>>
实验5
查看>>
git 下载 安装
查看>>
录制终端信息并回放
查看>>
JS中window.event事件使用详解
查看>>
ES6深入学习记录(一)class方法相关
查看>>
《BI项目笔记》用Excel2013连接和浏览OLAP多维数据集
查看>>
C语言对mysql数据库的操作
查看>>
SQL Server 数据库备份
查看>>
INNO SETUP 获得命令行参数
查看>>
Charles抓取https请求
查看>>
LAMP环境搭建
查看>>
C语言的变量的内存分配
查看>>
clientcontainerThrift Types
查看>>