Error in monetary mask, saved with the right digits but at display time 2 digits are missing

Asked

Viewed 404 times

3

inserir a descrição da imagem aqui

Colleagues! When I save the product gets the correct digits as on the screen above. However, when I enter the list of products and click on the product Scissors it opens on the registration screen missing two digits as on the screen below. Does anyone have any suggestions ? I ask you to be as specific as possible because I don’t have much experience. I thank anyone who can help. Thank you.

inserir a descrição da imagem aqui

My Class Product Registration:

 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.Toast;
 import br.gestaoBd.BancoDeDados.ProdutoDao;
 import br.gestaoBd.Beans.Produto;
 import java.text.NumberFormat;
 import java.util.Locale;

 public class CadProdutos extends Activity {

private ImageView imgView = null;
static final int SALVAR = 0, EXCLUIR = 1, LIMPAR = 2;
EditText edId, edDescricao, edPrecoDeCusto, edPercDeLucro, edPrecoDeVenda;
ProdutoDao prodDao;
Produto produto;

@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.cad_produtos);
    edId = (EditText) findViewById(R.id.cadEdId);
    edDescricao = (EditText) findViewById(R.id.cadEdDescricao);
    edPrecoDeCusto = (EditText) findViewById(R.id.cadEdPrecoDeCusto);
    edPrecoDeCusto.addTextChangedListener(new MonetaryMask(edPrecoDeCusto));
    edPercDeLucro = (EditText) findViewById(R.id.cadEdPercDeLucro);
    edPrecoDeVenda = (EditText) findViewById(R.id.cadEdPrecoDeVenda);
    edPrecoDeVenda.addTextChangedListener(new MonetaryMask(edPrecoDeVenda));

    imgView = (ImageView) findViewById(R.id.imgFoto);

    Produto produtoRecebido = (Produto) getIntent().getSerializableExtra("Produto");
    if (produtoRecebido != null) {
        montaTela(produtoRecebido);
    } else {
        montaTela(new Produto());
    }

    Button btn1Salvar = (Button) findViewById(R.id.btSalvar);
    btn1Salvar.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            Produto pro = new Produto();
            pro.setId(Integer.valueOf(edId.getText().toString()));
            pro.setDescricao(edDescricao.getText().toString());
            pro.setPrecoDeCusto(MonetaryMask.stringMonetarioToDouble(edPrecoDeCusto.getText().toString()));
            pro.setPercDeLucro(Double.valueOf(edPercDeLucro.getText().toString()));
            pro.setPrecoDeVenda(MonetaryMask.stringMonetarioToDouble(edPrecoDeVenda.getText().toString()));

            if (pro.getId() > 0) {
                getProDao().alterar(pro);
            } else {
                getProDao().inserirProduto(pro);
            }
            ToastManager.show(getBaseContext(), "Salvo com Sucesso",
                    ToastManager.INFORMATION);

        }
    });

    Button btnLimpar = (Button) findViewById(R.id.btLimpar);

    btnLimpar.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            montaTela(new Produto());
        }
    });

    Button bt2Excluir = (Button) findViewById(R.id.bt2Excluir);
    bt2Excluir.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            final Produto pro = new Produto();
            pro.setId(Integer.valueOf(edId.getText().toString()));
            pro.setDescricao(edDescricao.getText().toString());
            pro.setPrecoDeCusto(Double.valueOf(edPrecoDeCusto.getText().toString()));
            pro.setPercDeLucro(Double.valueOf(edPercDeLucro.getText().toString()));
            pro.setPrecoDeVenda(Double.valueOf(edPrecoDeVenda.getText().toString()));

            AlertDialog.Builder builder = new AlertDialog.Builder(CadProdutos.this);
            builder.setTitle("Deseja Excluir?");
            builder.setMessage("O produto será deletado!");

            builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    getProDao().excluir(pro);
                    montaTela(new Produto());
                    ToastManager.show(getBaseContext(), "Produto Excluído",
                            ToastManager.INFORMATION);

                }

            });

            builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    Toast.makeText(CadProdutos.this, "Cancelado", Toast.LENGTH_LONG).show();
                }
            });

            AlertDialog alert = builder.create();
            alert.show();

        }
    });
}

private void montaTela(Produto produto) {
    edId.setText(String.valueOf(produto.getId()));
    edDescricao.setText(produto.getDescricao());
    edPrecoDeCusto.setText(String.valueOf(produto.getPrecoDeCusto()));
    edPercDeLucro.setText(String.valueOf(produto.getPercDeLucro()));
    edPrecoDeVenda.setText(String.valueOf(produto.getPrecoDeVenda()));


}

public ProdutoDao getProDao() {
    if (prodDao == null) {
        prodDao = new ProdutoDao();
    }
    return prodDao;
}

public void tirarFoto(View view) {
    Intent i = new Intent("android.media.action.IMAGE_CAPTURE");
    startActivityForResult(i, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (data != null) {
        Bundle bundle = data.getExtras();

        if (bundle != null) {

            Bitmap bitmap = (Bitmap) bundle.get("data");


            imgView.setImageBitmap(bitmap);
        }
    }
}
} 

My Monetary Mask Class

 import android.text.Editable;
 import android.text.TextWatcher;
 import android.widget.EditText;
 import java.text.NumberFormat;

 public class MonetaryMask implements TextWatcher {

final EditText campo;

public static double stringMonetarioToDouble(String str) {
    double retorno = 0;
    try {
        boolean hasMask = ((str.indexOf("R$") > -1 || str.indexOf("$") > -1) && (str
                .indexOf(".") > -1 || str.indexOf(",") > -1));
        if (hasMask) {
            str = str.replaceAll("[R$]", "").replaceAll("\\,\\w+", "")
                    .replaceAll("\\.\\w+", "");
        }

        retorno = Double.parseDouble(str);
    } catch (NumberFormatException e) {

    }
    return retorno;
}

public MonetaryMask(EditText campo) {
    super();
    this.campo = campo;
}

private boolean isUpdating = false;

private NumberFormat nf = NumberFormat.getCurrencyInstance();

@Override
public void onTextChanged(CharSequence s, int start, int before,
        int after) {

    if (isUpdating) {
        isUpdating = false;
        return;
    }

    isUpdating = true;
    String str = s.toString();

    boolean hasMask = ((str.indexOf("R$") > -1 || str.indexOf("$") > -1)
            && (str.indexOf(".") > -1 || str.indexOf(",") > -1));

    if (hasMask) {

        str = str.replaceAll("[R$]", "").replaceAll("[,]", "")
                .replaceAll("[.]", "");
    }

    try {

        str = nf.format(Double.parseDouble(str) / 100);
        campo.setText(str);
        campo.setSelection(campo.getText().length());
    } catch (NumberFormatException e) {
        s = "";
    }
}

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

}

@Override
public void afterTextChanged(Editable s) {

}

}

1 answer

3


The problem is the static method stringMonetarioToDouble(String): it loses information while converting the String and returns erroneously to the persistence layer that while recovering a Produto displays incorrect values. Some examples:

"R$ 0,10" = 0,0

"R$ 0,01" = 0,0

"R$ 1,00" = 1.0

"R$ 10,00" = 10.0

"R$ 10,00" = 10.0

"R$ 10,50" = 10.0

A way out would be in class MonetaryMask save the original user input and add a method that would return the value double based on the original and not on the "masked". For example:

public class MonetaryMask implements TextWatcher {

    // ...

    private String mRawInput;
    
    // ...

    @Override
    public void onTextChanged(CharSequence s, int start, int before,
            int after) {

        // ...
        
        mRawInput = new String(s.toString());
        
        String str = s.toString();

        // ...
    }

    public double getMonetarioAsDouble() {
        if (mRawInput == null) {
            return 0.0d;
        }
        
        return Double.parseDouble(mRawInput) / 100.0d;
    }
}

That way you should save the instances of MonetaryMask used. As in this section:

    private MonetaryMask mPrecoDeCustoMonetaryMask;
    
    // ...
    
    mPrecoDeCustoMonetaryMask = new MonetaryMask(edPrecoDeCusto);
    
    edPrecoDeCusto.addTextChangedListener(mPrecoDeCustoMonetaryMask);
    
    // ...

And before persisting, the method shall be used getMonetarioAsDouble() of the instance to save the Produto:

    pro.setPrecoDeCusto(mPrecoDeCustoMonetaryMask.getMonetarioAsDouble());

Another point is that by recovering the Produto you need to transform the value double in the entry the user inserts into the mask. For example, if the user entered "100" is masked as "R$ 1,00", but is persisted as 1.00 and needs to turn "100" to be set in EditText. Something like this might:

    private void montaTela(Produto produto) {

        // ...

        edPrecoDeCusto.setText(String.valueOf(produto.getPrecoDeCusto() * 100.0d)));

        // ... 
    }

I hope I’ve helped.

  • Next.. when I add the value in the field it includes values but is not removing the zeros on the left. Over the days I have made a method to calculate the cost price plus the profit percentage and the result comes out in the sales price. It is occurring that when I shift the focus to the selling price, that the result should appear, the application hangs. I looked at the logs and saw Invalid double "R$0,010".

  • This must be because you are treating the masked value as the final value. But I believe this is another problem. If you do not fix the static method error stringMonetarioToDouble(String) somehow, the problems will continue.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.