Android - why lost values EditText when scrolled RecyclerView?

时间:2017-12-18 06:28:06

标签: android android-recyclerview android-adapter

I am using from bellow code for converting numbers to currency format when text changes but when I scrolled the recyclerView I lost true data. What can I do :

public class ManagePriceProductsAdapter extends RecyclerView.Adapter<ManagePriceProductsAdapter.ViewHolder> {
    private List<ManagePriceProductsModel.DataValue> managePriceProductsModelList;
    private Context context;
    private getListDiscountInterface getListDiscountInterface;
    private int vendorId = -1;

    public ManagePriceProductsAdapter(Context context,
                                      List<ManagePriceProductsModel.DataValue> managePriceProductsModelList,
                                      getListDiscountInterface getListDiscountInterface,
                                      int vendorId) {
        this.context = context;
        this.managePriceProductsModelList = managePriceProductsModelList;
        this.getListDiscountInterface = getListDiscountInterface;
        this.vendorId = vendorId;
    }

    @Override
    public ManagePriceProductsAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View view = LayoutInflater.from(context)
                .inflate(R.layout.list_item_manage_price_products, viewGroup, false);

        return new ManagePriceProductsAdapter.ViewHolder(view,
                new DiscountNumberTextWatcherWithSeperator(),
                new OriginalNumberTextWatcherWithSeperator());
    }

    public void getListDiscount() {
        getListDiscountInterface.sendGetListDiscountToActivity(managePriceProductsModelList);
    }

    public void backButton() {
        getListDiscountInterface.backButtonForListDiscount(managePriceProductsModelList);
    }

    public void resetAdapter() {
        this.managePriceProductsModelList.clear();
        notifyDataSetChanged();
    }

    @Override
    public void onBindViewHolder(final ManagePriceProductsAdapter.ViewHolder viewHolder, int position) {

        viewHolder.discountNumberTextWatcherWithSeperator.updatePosition(viewHolder.getAdapterPosition(),
                viewHolder.discountPriceEdittext,
                viewHolder.originalPriceEdittext);

        viewHolder.originalNumberTextWatcherWithSeperator.updatePosition(viewHolder.getAdapterPosition(),
                viewHolder.originalPriceEdittext);

        try {
            if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle() != null) {
                if (!TextUtils.isEmpty(managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle().trim())) {
                    String productName = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getTitle().trim();
                    viewHolder.titleTextview.setText(productName);
                } else {
                    viewHolder.titleTextview.setText("----");
                }
            } else {
                viewHolder.titleTextview.setText("----");
            }
        } catch (Exception ex) {
            if (vendorId != -1) {
                Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
                FirebaseCrash.report(t);
            } else {
                Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
                FirebaseCrash.report(t);
            }
        }


        try {
            if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getPrice() != null) {
                Long productPrice = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getPrice();
                if (productPrice != null && productPrice != 0 && productPrice > 0) {
                    viewHolder.originalPriceEdittext.setText(String.valueOf(productPrice));
                } else {
                    viewHolder.originalPriceEdittext.setText("");
                }
            }
        } catch (Exception ex) {
            if (vendorId != -1) {
                Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
                FirebaseCrash.report(t);
            } else {
                Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
                FirebaseCrash.report(t);
            }
        }


        try {
            if (managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getDiscountedPrice() != null) {
                Long discountPrice = managePriceProductsModelList.get(viewHolder.getAdapterPosition()).getDiscountedPrice();
                if (discountPrice != null && discountPrice != 0 && discountPrice > 0) {
                    viewHolder.discountPriceEdittext.setText(String.valueOf(discountPrice));
                } else {
                    viewHolder.discountPriceEdittext.setText("");
                }
            }
        } catch (Exception ex) {
            if (vendorId != -1) {
                Throwable t = new Throwable(ex + ", vendorId: " + vendorId).fillInStackTrace();
                FirebaseCrash.report(t);
            } else {
                Throwable t = new Throwable(ex + ", vendorId: empty").fillInStackTrace();
                FirebaseCrash.report(t);
            }
        }

    }

    @Override
    public int getItemCount() {
        return managePriceProductsModelList.size();
    }

    public interface getListDiscountInterface {
        void sendGetListDiscountToActivity(List<ManagePriceProductsModel.DataValue> managePriceProductsModelList);

        void backButtonForListDiscount(List<ManagePriceProductsModel.DataValue> managePriceProductsModelList);
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        //region ViewBinding
        @BindView(R.id.title_textview)
        TextView titleTextview;
        @BindView(R.id.original_price_edittext)
        EditText originalPriceEdittext;
        @BindView(R.id.discount_price_edittext)
        EditText discountPriceEdittext;
        DiscountNumberTextWatcherWithSeperator discountNumberTextWatcherWithSeperator;
        OriginalNumberTextWatcherWithSeperator originalNumberTextWatcherWithSeperator;

        //endregion
        ViewHolder(View view,
                   DiscountNumberTextWatcherWithSeperator discountNumberTextWatcherWithSeperator,
                   OriginalNumberTextWatcherWithSeperator originalNumberTextWatcherWithSeperator) {
            super(view);
            ButterKnife.bind(this, itemView);
            this.discountNumberTextWatcherWithSeperator = discountNumberTextWatcherWithSeperator;
            this.discountPriceEdittext.addTextChangedListener(discountNumberTextWatcherWithSeperator);
            this.originalNumberTextWatcherWithSeperator = originalNumberTextWatcherWithSeperator;
            this.originalPriceEdittext.addTextChangedListener(originalNumberTextWatcherWithSeperator);
        }
    }

    private class DiscountNumberTextWatcherWithSeperator implements TextWatcher {

        private EditText discountEditText;
        private EditText originalEditText;
        private int position;

        private String getDecimalFormattedString(String value) {
            StringTokenizer lst = new StringTokenizer(value, ".");
            String str1 = value;
            String str2 = "";
            if (lst.countTokens() > 1) {
                str1 = lst.nextToken();
                str2 = lst.nextToken();
            }
            String str3 = "";
            int i = 0;
            int j = -1 + str1.length();
            if (str1.charAt(-1 + str1.length()) == '.') {
                j--;
                str3 = ".";
            }
            for (int k = j; ; k--) {
                if (k < 0) {
                    if (str2.length() > 0)
                        str3 = str3 + "." + str2;
                    return str3;
                }
                if (i == 3) {
                    str3 = "," + str3;
                    i = 0;
                }
                str3 = str1.charAt(k) + str3;
                i++;
            }

        }

        public void updatePosition(int position,
                                   EditText discountEditText,
                                   EditText originalEditText) {
            this.position = position;
            this.discountEditText = discountEditText;
            this.originalEditText = originalEditText;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
            if (charSequence.length() > 0) {
                originalEditText.setPaintFlags(originalEditText.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
                ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
                dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
                dataValue.setId(managePriceProductsModelList.get(position).getId());
                dataValue.setPrice(managePriceProductsModelList.get(position).getPrice());
                dataValue.setDiscountedPrice(Long.parseLong(charSequence.toString().replace(",", "")));
                managePriceProductsModelList.set(position, dataValue);
            } else if (charSequence.length() == 0) {
                originalEditText.setPaintFlags(originalEditText.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
                ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
                dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
                dataValue.setId(managePriceProductsModelList.get(position).getId());
                dataValue.setPrice(managePriceProductsModelList.get(position).getPrice());
                dataValue.setDiscountedPrice(null);
                managePriceProductsModelList.set(position, dataValue);
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {
            try {
                discountEditText.removeTextChangedListener(this);
                String value = discountEditText.getText().toString();

                if (!value.equals("")) {

                    if (value.startsWith(".")) {
                        discountEditText.setText("0.");
                    }
                    if (value.startsWith("0") && !value.startsWith("0.")) {
                        discountEditText.setText("");

                    }

                    String str = discountEditText.getText().toString().replaceAll(",", "");
                    if (!value.equals(""))
                        discountEditText.setText(getDecimalFormattedString(str));
                    discountEditText.setSelection(discountEditText.getText().toString().length());
                }
                discountEditText.addTextChangedListener(this);
            } catch (Exception ex) {
                ex.printStackTrace();
                discountEditText.addTextChangedListener(this);
            }
        }
    }


    private class OriginalNumberTextWatcherWithSeperator implements TextWatcher {

        private EditText editText;
        private int position;

        private String getDecimalFormattedString(String value) {
            StringTokenizer lst = new StringTokenizer(value, ".");
            String str1 = value;
            String str2 = "";
            if (lst.countTokens() > 1) {
                str1 = lst.nextToken();
                str2 = lst.nextToken();
            }
            String str3 = "";
            int i = 0;
            int j = -1 + str1.length();
            if (str1.charAt(-1 + str1.length()) == '.') {
                j--;
                str3 = ".";
            }
            for (int k = j; ; k--) {
                if (k < 0) {
                    if (str2.length() > 0)
                        str3 = str3 + "." + str2;
                    return str3;
                }
                if (i == 3) {
                    str3 = "," + str3;
                    i = 0;
                }
                str3 = str1.charAt(k) + str3;
                i++;
            }

        }

        public void updatePosition(int position,
                                   EditText editText) {
            this.position = position;
            this.editText = editText;
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
            if (charSequence.length() > 0) {
                ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
                dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
                dataValue.setId(managePriceProductsModelList.get(position).getId());
                dataValue.setPrice(Long.parseLong(charSequence.toString().replace(",", "")));
                dataValue.setDiscountedPrice(managePriceProductsModelList.get(position).getDiscountedPrice());
                managePriceProductsModelList.set(position, dataValue);
            } else if (charSequence.length() == 0) {
                ManagePriceProductsModel.DataValue dataValue = new ManagePriceProductsModel.DataValue();
                dataValue.setTitle(managePriceProductsModelList.get(position).getTitle().trim());
                dataValue.setId(managePriceProductsModelList.get(position).getId());
                dataValue.setPrice(null);
                dataValue.setDiscountedPrice(managePriceProductsModelList.get(position).getDiscountedPrice());
                managePriceProductsModelList.set(position, dataValue);
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {
            try {
                editText.removeTextChangedListener(this);
                String value = editText.getText().toString();

                if (!value.equals("")) {

                    if (value.startsWith(".")) {
                        editText.setText("0.");
                    }
                    if (value.startsWith("0") && !value.startsWith("0.")) {
                        editText.setText("");

                    }

                    String str = editText.getText().toString().replaceAll(",", "");
                    if (!value.equals(""))
                        editText.setText(getDecimalFormattedString(str));
                    editText.setSelection(editText.getText().toString().length());
                }
                editText.addTextChangedListener(this);
            } catch (Exception ex) {
                ex.printStackTrace();
                editText.addTextChangedListener(this);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

As the comments above it is not recommended to use edittext in recyclerview.

If you have to do this can you try to use

 viewHolder.setIsRecyclable(false);

in your onBindViewHolder method

答案 1 :(得分:0)

您可以使用此library to support

  1. 创建一个ViewState
new ViewState<>() {
    private String savedValue; /* here will be saved a value for each item by createViewStateID() */

    @Override
    public void clear(@NonNull final ViewHolder<ViewFinder> holder) {
        holder.getViewFinder().setText(R.id.text, "");
    }

    @Override
    public void save(@NonNull final ViewHolder<ViewFinder> holder) {
        savedValue = holder.getViewFinder().<EditText>find(R.id.text).getText().toString();
    }

    @Override
    public void restore(@NonNull final ViewHolder<ViewFinder> holder) {
        holder.getViewFinder().setText(R.id.text, savedValue);
    }
};
  1. 将该ViewState设置为您的ViewRenderer
adapter.registerRenderer(new ViewRenderer<>(
    R.layout.your_item_layout, //your layout
    YourItemModel.class, //your model
    (model, finder, payloads) -> finder.setText(R.id.text, model.getValue()), //your binding
    getYourViewStateProvider() // here is your ViewState
));

更多信息,您可以找到here