Abi*_*san 7 android android-edittext android-viewholder android-recyclerview
在EditText中输入输入后,如果向上或向下滚动非常快,则输入值会在RecyclerView中的另一个EditText中交换其位置.
在滚动之前,数据位于第一个EditText中.
在向上和向下滚动之后,第一个EditText的值将其位置更改为第4个,并且交换是随机的.是否有任何工作来稳定数据.
这是模型类:
public class Product {
public int pId;
public String pName;
public double unit_price;
public double discount;
}
Run Code Online (Sandbox Code Playgroud)
这是适配器类:
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductListHolder> {
Context context;
List<Product> productList;
public ProductAdapter(Context c, List<Product> lp){
this.context = c;
this.productList = lp;
}
public class ProductListHolder extends RecyclerView.ViewHolder{
TextView tvName;
TextView tvPrice;
TextView tvDiscount;
TextView tvTotal;
EditText etQuantity;
public ProductListHolder(View itemView) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.tvName);
tvPrice = (TextView) itemView.findViewById(R.id.tvPrice);
tvDiscount = (TextView) itemView.findViewById(R.id.tvDiscount);
tvTotal = (TextView) itemView.findViewById(R.id.tvTotal);
etQuantity = (EditText) itemView.findViewById(R.id.etQuantity);
}
}
@Override
public ProductListHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_row, viewGroup, false);
ProductListHolder ph = new ProductListHolder(v);
return ph;
}
@Override
public void onBindViewHolder(final ProductListHolder productListHolder, final int i) {
productListHolder.tvName.setText(productList.get(i).pName);
productListHolder.tvPrice.setText(String.valueOf(productList.get(i).unit_price));
productListHolder.tvDiscount.setText(String.valueOf(productList.get(i).discount));
productListHolder.etQuantity.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) {
if (!s.toString().equals("")){
double totalPrice = (productList.get(i).unit_price-productList.get(i).discount)* (Double.valueOf(s.toString()));
productListHolder.tvTotal.setText(String.valueOf(totalPrice));
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
@Override
public int getItemCount() {
return productList.size();
}
Run Code Online (Sandbox Code Playgroud)
}
这是MainActivity:
public class MainActivity extends AppCompatActivity {
List<Product> productList;
RecyclerView recyclerView;
RecyclerView.Adapter mAdapter;
String[] names = {"A", "B", "C","D"};
double[] prices = {1000, 2000, 3000, 100};
double[] discounts = {10, 20, 30, 2};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecyclerView(); // Initializing Recycler View
new MyTask().execute();
}
public void initRecyclerView(){
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
}
private class MyTask extends AsyncTask<Void, Void, List<Product>> {
@Override
protected List<Product> doInBackground(Void... params) {
int sz = 24;
productList = new ArrayList<Product>();
for(int i=0; i<sz; i++){
Product p = new Product();
p.pId = i%4;
p.pName = names[i%4];
p.unit_price = prices[i%4];
p.discount = discounts[i%4];
productList.add(p);
}
return productList;
}
@Override
protected void onPostExecute(List<Product> products) {
super.onPostExecute(products);
mAdapter = new ProductAdapter(MainActivity.this, productList);
recyclerView.setAdapter(mAdapter);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Bar*_*rno 14
我觉得你做得很好.但是你解决的问题可以通过一种非常简单的方式解决.您只需要实现一个重写方法:
public int getItemViewType(int position){return super.getItemViewType(position); }
取代─
return super.getItemViewType(position);
刚回来 -
返回位置;
我认为你的所有问题都将以一种简单的方式解决.这是你修改了一下的适配器类:
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductListHolder> {
Context context;
List<Product> productList;
public ProductAdapter(Context c, List<Product> lp) {
this.context = c;
this.productList = lp;
}
public class ProductListHolder extends RecyclerView.ViewHolder {
TextView tvName;
TextView tvPrice;
TextView tvDiscount;
TextView tvTotal;
EditText etQuantity;
public ProductListHolder(View itemView) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.tvName);
tvPrice = (TextView) itemView.findViewById(R.id.tvPrice);
tvDiscount = (TextView) itemView.findViewById(R.id.tvDiscount);
tvTotal = (TextView) itemView.findViewById(R.id.tvTotal);
etQuantity = (EditText) itemView.findViewById(R.id.etQuantity);
}
}
@Override
public ProductListHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
View v = LayoutInflater.from(context).inflate(R.layout.single_row, viewGroup, false);
ProductListHolder ph = new ProductListHolder(v);
return ph;
}
@Override
public void onBindViewHolder(final ProductListHolder productListHolder, final int i) {
productListHolder.tvName.setText(productList.get(i).pName);
productListHolder.tvPrice.setText(String.valueOf(productList.get(i).unit_price));
productListHolder.tvDiscount.setText(String.valueOf(productList.get(i).discount));
productListHolder.etQuantity.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) {
productListHolder.tvTotal.setText(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
@Override
public int getItemCount() {
return productList.size();
}
@Override
public int getItemViewType(int position) {
return position;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我在onBindViewHolder中添加了addTextChangedListener.所以EditText中的值总是混乱,导致焦点移动时另一个addTextChangedListener被注册.所以我做的是,我实现了另一个名为CustomEtListener的自定义类并实现了TextWatcher.所以现在我在onCreateViewHolder中为每个EditText 注册了自定义监听器.并使用一个字符串数组来存储编辑文本的值.并且数组的大小是RecyclerView中的项目数.并且方法updatePosition用于获取焦点项的位置.然后onTextChanged我只是存储在数组中的EDITTEXT的值,并且更新在的EditText的值onBindViewHolder.之后我每次滚动时,EditText的值都不会改变.
这是我的适配器类.
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductListHolder> {
Context context;
List<Product> productList;
String[] etValArr;
double[] totalValue;
public ProductAdapter(Context c, List<Product> lp) {
this.context = c;
this.productList = lp;
// Create a new array which size matches the number of Edit Texts
etValArr = new String[productList.size()];
// and an array for holding all the values of each edit text
totalValue = new double[productList.size()];
}
public class ProductListHolder extends RecyclerView.ViewHolder {
TextView tvName;
TextView tvPrice;
TextView tvDiscount;
TextView tvTotal;
EditText etQuantity;
// Instance of a Custom edit text listener
public CustomEtListener myCustomEditTextListener;
public ProductListHolder(View itemView, CustomEtListener myLis) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.tvName);
tvPrice = (TextView) itemView.findViewById(R.id.tvPrice);
tvDiscount = (TextView) itemView.findViewById(R.id.tvDiscount);
tvTotal = (TextView) itemView.findViewById(R.id.tvTotal);
etQuantity = (EditText) itemView.findViewById(R.id.etQuantity);
// assign a new instance of addTextChangedListener for each item
myCustomEditTextListener = myLis;
etQuantity.addTextChangedListener(myCustomEditTextListener);
}
}
@Override
public ProductListHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_row, viewGroup, false);
ProductListHolder ph = new ProductListHolder(v, new CustomEtListener());
return ph;
}
@Override
public void onBindViewHolder(final ProductListHolder productListHolder, int i) {
productListHolder.tvName.setText(productList.get(i).pName);
productListHolder.tvPrice.setText(String.valueOf(productList.get(i).unit_price));
productListHolder.tvDiscount.setText(String.valueOf(productList.get(i).discount));
// Update the position when focus changes
productListHolder.myCustomEditTextListener.updatePosition(i);
// Setting the values accordingly
productListHolder.etQuantity.setText(etValArr[i]);
productListHolder.tvTotal.setText(String.valueOf(totalValue[i]));
}
@Override
public int getItemCount() {
return productList.size();
}
/**
* Custom class which implements Text Watcher
*/
private class CustomEtListener implements TextWatcher {
private int position;
/**
* Updates the position according to onBindViewHolder
*
* @param position - position of the focused item
*/
public void updatePosition(int position) {
this.position = position;
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
// Change the value of array according to the position
etValArr[position] = charSequence.toString();
// Doing the calculation
if (!etValArr[position].equals("")) {
totalValue[position] = (productList.get(position).unit_price - productList.get(position).discount) * (Double.valueOf(etValArr[position]));
} else {
totalValue[position] = 0.00;
}
}
@Override
public void afterTextChanged(Editable editable) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
我还有问题.我无法更新Total列的值.我向上和向下滚动后,值改变了.所以我必须实现一个调用backListener来立即获取Total列的值.我现在有一个接口TextCallBackListener,并在Adapters ProductListHoldersClass上实现它.因此,每当调用onTextChanged时,它都会触发我的updateText方法来更改行Total的值.如果您不理解该视图,则问题中会有截图.
这是接口TextCallBackListener.
public interface TextCallBackListener {
public void updateText(String val);
}
Run Code Online (Sandbox Code Playgroud)
这是我更改的适配器类.
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductListHolder> {
Context context;
List<Product> productList;
String[] etValArr;
double[] totalValue;
public ProductAdapter(Context c, List<Product> lp) {
this.context = c;
this.productList = lp;
// Create a new array which size matches the number of Edit Texts
etValArr = new String[productList.size()];
// and an array for holding all the values of each edit text
totalValue = new double[productList.size()];
}
public class ProductListHolder extends RecyclerView.ViewHolder implements TextCallBackListener {
TextView tvName;
TextView tvPrice;
TextView tvDiscount;
TextView tvTotal;
EditText etQuantity;
// Instance of a Custom edit text listener
public CustomEtListener myCustomEditTextListener;
public ProductListHolder(View itemView, CustomEtListener myLis) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.tvName);
tvPrice = (TextView) itemView.findViewById(R.id.tvPrice);
tvDiscount = (TextView) itemView.findViewById(R.id.tvDiscount);
tvTotal = (TextView) itemView.findViewById(R.id.tvTotal);
etQuantity = (EditText) itemView.findViewById(R.id.etQuantity);
// assign a new instance of addTextChangedListener for each item
myCustomEditTextListener = myLis;
etQuantity.addTextChangedListener(myCustomEditTextListener);
}
@Override
public void updateText(String val) {
tvTotal.setText(val);
}
}
@Override
public ProductListHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_row, viewGroup, false);
ProductListHolder ph = new ProductListHolder(v, new CustomEtListener());
return ph;
}
@Override
public void onBindViewHolder(final ProductListHolder productListHolder, int i) {
productListHolder.tvName.setText(productList.get(i).pName);
productListHolder.tvPrice.setText(String.valueOf(productList.get(i).unit_price));
productListHolder.tvDiscount.setText(String.valueOf(productList.get(i).discount));
// Update the position when focus changes
productListHolder.myCustomEditTextListener.updatePosition(i, productListHolder);
// Setting the values accordingly
productListHolder.etQuantity.setText(etValArr[i]);
//productListHolder.tvTotal.setText(String.valueOf(totalValue[i]));
}
@Override
public int getItemCount() {
return productList.size();
}
/**
* Custom class which implements Text Watcher
*/
private class CustomEtListener implements TextWatcher {
private int position;
TextCallBackListener textCallBackListener;
/**
* Updates the position according to onBindViewHolder
*
* @param position - position of the focused item
* @param pa - object of ProductListHolder Class
*/
public void updatePosition(int position, ProductListHolder pa) {
this.position = position;
// assigning it to the instance of the CallBackListener
textCallBackListener = (TextCallBackListener) pa;
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
// Change the value of array according to the position
etValArr[position] = charSequence.toString();
// Doing the calculation
if (!etValArr[position].equals("")) {
totalValue[position] = (productList.get(position).unit_price - productList.get(position).discount) * (Double.valueOf(etValArr[position]));
// triggering the callback function to update the total
textCallBackListener.updateText(String.valueOf(totalValue[position]));
} else {
totalValue[position] = 0.00;
textCallBackListener.updateText("0.00");
}
}
@Override
public void afterTextChanged(Editable editable) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
你正在调用,etQuantity.addTextChangedListener但你永远不会删除监听器,所以当视图持有者被回收(也就是用于显示另一个项目)时,它将添加另一个文本更改的监听器(因此它将改变两个不同的文本)听众注册).
最简单的修复可能是只调用addTextChangedListener一次onCreateViewHolder并使用getAdapterPosition而不是i获取位置.
| 归档时间: |
|
| 查看次数: |
7291 次 |
| 最近记录: |