I have a form. I want to display a calculation in "live time" when the user enters different values into some int fields. I made my Activity implement the TextWatcher interface and set a listener on 3 different EditText fields but it appears the Textwatcher only detects the first EditText declared in the Activity's code.
You can see from the code below, I'm trying to grabe a few fields, convert them to ints and display the output in an EditText field at the bottom of the form. Where am I going wrong? Do I need to implement a textWatcher individually on all of the EditText fields involved? That would be a rather verbose solution making my code a lot longer than I would like
public class NewStageFormActivity extends AppCompatActivity implements TextWatcher{
Context mContext;
EditText mStageName, mPaperTargets, mHitsPerTarget, mSteelTargets, mSteelNPMs, mOutput;
Spinner mScoringType, mStrings;
CheckBox mNoShoots, mNPMs;
Button mSaveButton;
Match mGlobalMatch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stage_form);
mContext = this;
mGlobalMatch = GlobalMatch.getMatch();
mStageName = (EditText)findViewById(R.id.stage_name_et);
mPaperTargets = (EditText)findViewById(R.id.paper_targets_et);
mHitsPerTarget = (EditText)findViewById(R.id.hits_per_target_et);
mSteelTargets = (EditText)findViewById(R.id.steel_targets_et);
mSteelNPMs = (EditText)findViewById(R.id.steel_npm_et);
mScoringType = (Spinner)findViewById(R.id.scoring_type_spinner);
mStrings = (Spinner)findViewById(R.id.strings_spinner);
mNoShoots = (CheckBox)findViewById(R.id.no_shoots_cb);
mNPMs = (CheckBox)findViewById(R.id.npm_cb);
mSaveButton = (Button)findViewById(R.id.save_button);
mOutput = (EditText)findViewById(R.id.output_et);
// paper * hitsPer + steel
mPaperTargets.addTextChangedListener(this);
mSteelTargets.addTextChangedListener(this);
mSteelTargets.addTextChangedListener(this);
mSaveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(mStageName.getText().toString().equals("") || mPaperTargets.getText().toString().equals("") ||
mHitsPerTarget.getText().toString().equals("") || mSteelTargets.getText().toString().equals("") ||
mSteelNPMs.getText().toString().equals("")){
Toast.makeText(mContext, "You must fill in all form fields", Toast.LENGTH_SHORT).show();
} else {
String name = mStageName.getText().toString();
String type = mScoringType.getSelectedItem().toString();
int strings = Integer.valueOf(mStrings.getSelectedItem().toString());
int paperTargets = Integer.valueOf(mPaperTargets.getText().toString());
int hitsPerTarget = Integer.valueOf(mHitsPerTarget.getText().toString());
boolean noShoots;
boolean npms;
if(mNoShoots.isChecked()){
noShoots = true;
} else {
noShoots = false;
}
if(mNPMs.isChecked()){
npms = true;
} else {
npms = false;
}
int steelTargets = Integer.valueOf(mSteelTargets.getText().toString());
int steelNPMs = Integer.valueOf(mSteelNPMs.getText().toString());
MatchStage matchStage = new MatchStage(name, type, strings, paperTargets, hitsPerTarget,
noShoots, npms, steelTargets, steelNPMs);
mGlobalMatch.getStages().add(matchStage);
String jsonString = new Gson().toJson(mGlobalMatch);
MatchHelper.updateFile(mContext, MatchHelper.createFileName(mGlobalMatch.getMatchId()),
jsonString);
Intent intent = new Intent(mContext, StagesListActivity.class);
startActivity(intent);
}
}
});
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
int paper = Integer.valueOf(mPaperTargets.getText().toString());
int hitsPer = Integer.valueOf(mHitsPerTarget.getText().toString());
int steel = Integer.valueOf(mSteelTargets.getText().toString());
int minRound = (paper * hitsPer) + steel;
int points = minRound * 5;
mOutput.setText("Minimum rounds: " + (minRound) + "\t\t Points: " + points);
}
#Override
public void afterTextChanged(Editable editable) {
}
}
In my experience I've had issues with using the same TextWatcher on multiple EditText. You could get around this by creating a method that produces a new instance of TextWatcher for each EditText so your code isn't all verbose. Try something like this:
Get rid of implements TextWatcher for your Activity and it's associated methods. Implement a method createTextWatcher():
private TextWatcher createTextWatcher() {
return new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
// Copy your original code
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
// Copy your original code
}
#Override
public void afterTextChanged(Editable editable) {
// Copy your original code
}
};
}
Now to use it like this:
mPaperTargets.addTextChangedListener(createTextWatcher());
mSteelTargets.addTextChangedListener(createTextWatcher());
The most up-voted answer on #Natan Felipe's link also demonstrates using one instance of TextWatcher per EditText.
Related
I have multiple EditTexts and I want to change the input of all of them at the same time, as I modify only one.(all of them take decimal numbers as input)
I stored the EditTexts in an array named 'editTexts'.
Here's what I tried
//Set the listener for each element
for (int i=0; i<editTexts.length; i++) {
final int finalI = i;
editTexts[i].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 the editText which is currently edited is empty, set the input for all the rest to be '0.0'
if (editTexts[finalI].getText().toString().trim().length() == 0) {
for(EditText e : editTexts) {
if (e == editTexts[finalI])
continue;
e.setText("0.0");
}
} else {
float no = Float.parseFloat(s.toString() + "");
//Set the input of all the other editTexts to be the decimal number entered, multiplied by 2
for(EditText e : editTexts){
if(e == editTexts[finalI])
continue;
e.setText(no*2+"");
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
})
}
In this case the multiplication coefficient is just an example, it's not always gonna be 2. I used it just to test it out.
For some reason, when I change the input value, the app freezes.
Any help? Thanks!
Use LiveData to store your user input values.
Once it's value changes you can set value to each EditText. I think it is an easy way to implement.
Try it like this:
// et_x1, et_x2 and et_x3 are ids of EditTexts
//set inputType for all EditTexts as numberDecimal
EditText editText1 = findViewById(R.id.et_x1);
final EditText editText2 = findViewById(R.id.et_x2);
final EditText editText3 = findViewById(R.id.et_x3);
editText1.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) {
String value = s.toString();
double x;
if (!value.equals("")) {
x = Double.parseDouble(value);
} else {
x = 0.0;
}
editText2.setText(Editable.Factory.getInstance().newEditable((String.valueOf(Math.pow(x, 2)))));
editText3.setText(
Editable.Factory.getInstance().newEditable((String.valueOf(Math.pow(x, 3)))));
}
#Override
public void afterTextChanged(Editable s) {
}
});
Hope it helps you!
How can I sum all the total of my multiple EditText without using a Button but only on TextWatcher's onTextChanged() method. assuming this is my layout:
EditText1 = 5
EditText2 = 5
EditText3 = 5
EditText4 = 5
Total = 20
and so on
and getting the total of it?. the total should be CHANGING when the EditText's value is changing.
I have read this answer. but I can't execute it well on my program.
This is my Layout of it
You need to use a TextWatcher()
instead of using 5 TextWatcher() you can manage it using only a single TextWatcher()
Try this
Using below answer if all your 4 four edittext is not empty then it will calculate the sum of editext value
public class MainActivity extends AppCompatActivity {
EditText edtOne, edtTwo, edtThree, edtFour;
TextView tvResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtOne = findViewById(R.id.edtOne);
edtTwo = findViewById(R.id.edtTwo);
edtThree = findViewById(R.id.edtThree);
edtFour = findViewById(R.id.edtFour);
tvResult = findViewById(R.id.tvResult);
edtOne.addTextChangedListener(textWatcher);
edtTwo.addTextChangedListener(textWatcher);
edtThree.addTextChangedListener(textWatcher);
edtFour.addTextChangedListener(textWatcher);
}
TextWatcher textWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (!TextUtils.isEmpty(edtOne.getText().toString().trim())
|| !TextUtils.isEmpty(edtTwo.getText().toString().trim())
|| !TextUtils.isEmpty(edtThree.getText().toString().trim())
|| !TextUtils.isEmpty(edtFour.getText().toString().trim())
) {
int answer = Integer.parseInt(edtOne.getText().toString().trim()) +
Integer.parseInt(edtTwo.getText().toString().trim()) +
Integer.parseInt(edtThree.getText().toString().trim()) +
Integer.parseInt(edtFour.getText().toString().trim());
Log.e("RESULT", String.valueOf(answer));
tvResult.setText(String.valueOf(answer));
}else {
tvResult.setText("");
}
}
#Override
public void afterTextChanged(Editable editable) {
}
};
}
UPDATE
if you want to calculate value of all editext evenif your editext is empty than try below TextWatcher()
TextWatcher textWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (!TextUtils.isEmpty(edtOne.getText().toString().trim())
|| !TextUtils.isEmpty(edtTwo.getText().toString().trim())
|| !TextUtils.isEmpty(edtThree.getText().toString().trim())
|| !TextUtils.isEmpty(edtFour.getText().toString().trim())
) {
int firtValue = TextUtils.isEmpty(edtOne.getText().toString().trim()) ? 0 : Integer.parseInt(edtOne.getText().toString().trim());
int secondValue = TextUtils.isEmpty(edtTwo.getText().toString().trim()) ? 0 : Integer.parseInt(edtTwo.getText().toString().trim());
int thirdValue = TextUtils.isEmpty(edtThree.getText().toString().trim()) ? 0 : Integer.parseInt(edtThree.getText().toString().trim());
int forthValue = TextUtils.isEmpty(edtFour.getText().toString().trim()) ? 0 : Integer.parseInt(edtFour.getText().toString().trim());
int answer = firtValue + secondValue + thirdValue + forthValue;
Log.e("RESULT", String.valueOf(answer));
tvResult.setText(String.valueOf(answer));
}else {
tvResult.setText("");
}
}
#Override
public void afterTextChanged(Editable editable) {
}
};
I'm going to tell you how to do it, but I won't post the solution as a total code.
First of all, define integers that is the amount of your edit text count. If there is 4 edit texts, define 4 integers with like int first = 0, second = 0, third = 0, fourth = 0;
Then, add separate text watchers to your edit texts, and on your afterTextChanged methods, get the integer value from the string by using Integer.parseInt(Editable s.getText.toString()) and make sure the input is convertable, otherwise you will get a NumberFormatException. Then, assign this value to the related edit text, for example on your first edit text use first = Integer.parse(s.getText().toString()).
Create a function that uses these variables to display on a textview. For instance:
private void showResult() {
textView.setText(String.valueOf(first + second + third + fourth));
}
Then, at every afterTextChanged methods call this function to display the total amount.
I need to change positive button's text of an AlertBox from nothing to OK or Add according to the entered text. I have the following code for the AlertBox creation and displaying:
public void show() {
View inputView = LinearLayout.inflate(mContext, R.layout.goal_tag_input, null);
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setView(inputView);
mInput = inputView.findViewById(R.id.goal_tag_input);
mInput.addTextChangedListener(mTagNameTextWatcher);
List<Tag> availableTags = AppDatabase.getInstance(mContext).tagDao().getAll();
mAvailableTagLabels = new ArrayList<>();
for (Tag tag : availableTags) {
mAvailableTagLabels.add(tag.getName());
}
ArrayAdapter<String> inputAdapter = new ArrayAdapter<>(mContext,
android.R.layout.select_dialog_item, mAvailableTagLabels);
mInput.setAdapter(inputAdapter);
builder.setCancelable(true);
builder.setPositiveButton("", mAddTagClickListener);
builder.setNegativeButton(R.string.Cancel, null);
mDialog = builder.create();
mDialog.show();
}
Also I have a TextWatcher implementation:
private TextWatcher mTagNameTextWatcher = 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) {}
#Override
public void afterTextChanged(Editable s) {
String tagName = mInput.getText().toString();
if (tagName.trim() != "") {
Button buttonPositive = mDialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (mAvailableTagLabels.contains(tagName)) {
buttonPositive.setText(R.string.OK);
} else {
buttonPositive.setText(R.string.Add);
}
}
}
};
During debugging I observed that the text value of the buttonPositive is changed appropriately, but it is not reflected in the interface. Do you have any ideas why is it so? I checked this answer but it didn't help.
Well, it appeared that the problem was in the setting a positive button using the AlertDialog builder here: builder.setPositiveButton("", mAddTagClickListener);. Apparently, a button is not created if you pass an empty string as the first argument. The minute I tried to change it to (at least) one-space-string - everything began to work as expected.Later on I changed the approach to enabling/disabling the button.
Well you can try this
public void show() {
View inputView = LinearLayout.inflate(AppIntroActivity.this, R.layout.goal_tag_input, null);
AlertDialog.Builder builder = new AlertDialog.Builder(AppIntroActivity.this);
builder.setView(inputView);
final EditText mInput =(EditText) inputView.findViewById(R.id.goal_tag_input);
final Button buttonPositive = (Button) inputView.findViewById(R.id.button_id);
mInput.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) {}
#Override
public void afterTextChanged(Editable s) {
String tagName = mInput.getText().toString();
if (tagName.trim() != "") {
if (mAvailableTagLabels.contains(tagName)) {
buttonPositive.setText(R.string.OK);
} else {
buttonPositive.setText(R.string.Add);
}
}
}
};);
List<Tag> availableTags = AppDatabase.getInstance(mContext).tagDao().getAll();
mAvailableTagLabels = new ArrayList<>();
for (Tag tag : availableTags) {
mAvailableTagLabels.add(tag.getName());
}
ArrayAdapter<String> inputAdapter = new ArrayAdapter<>(mContext,
android.R.layout.select_dialog_item, mAvailableTagLabels);
mInput.setAdapter(inputAdapter);
builder.setCancelable(true);
builder.setPositiveButton("", mAddTagClickListener);
builder.setNegativeButton(R.string.Cancel, null);
mDialog = builder.create();
mDialog.show();
}
I have multiple EditText views , each EditText view can contain only 1 char.
I need to make this rule - if I focus on one EditText , and it already has some text inside - then overwrite it . Also - if I press on delete key - I need the text to be cleared inside that view.
Then - I am checking if the EditText views has 1 empty cell - if not - checking if the EditText views has the correct letters.
I could have managed to make the clear button work, but I can not make the overwrite.
I did tried to use the TextWatcher , but it didn't work for me.
The EditText views are created dynamically .
Here is my code :
Answer.java
public class Answer {
String answer;
int answer_length;
int cell_margin=10;
int cell_size=180;
EditText[] EditTextArray;
public Answer(RelativeLayout rLayout1, Context context , String answer) {
this.answer = answer;
answer_length = answer.length();
if (answer_length>6){
cell_margin = 4;
cell_size = 110;
}
EditTextArray = new EditText[answer_length];
AnswerCell EditTextToSeeFirst = new AnswerCell(context,cell_size);
setListener(EditTextToSeeFirst);
EditTextArray[0] = EditTextToSeeFirst;
RelativeLayout.LayoutParams fparams = new RelativeLayout.LayoutParams
(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
fparams.setMargins(cell_margin,0,cell_margin,0);
rLayout1.addView(EditTextToSeeFirst, fparams);
for (int i = 1; i<answer_length ; i++){
RelativeLayout.LayoutParams lparams = new RelativeLayout.LayoutParams
(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lparams.addRule(RelativeLayout.LEFT_OF, EditTextArray[i-1].getId());
lparams.setMargins(cell_margin,0,cell_margin,0);
AnswerCell newEditText = new AnswerCell(context,cell_size);
setListener(newEditText);
EditTextArray[i] = newEditText;
rLayout1.addView(EditTextArray[i], lparams);
}
rLayout1.setGravity(Gravity.CENTER );
}
public void setListener(AnswerCell ac){
ac.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d("test","test");
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
goToNextAvailableCell();
}
});
}
public void goToNextAvailableCell(){
for (int i = 0; i<answer_length ; i++) {
if(EditTextArray[i].getText().toString().matches("")){
EditTextArray[i].requestFocus();
return;
}
}
//Did not found empty cell
checkCorrectAnswer();
}
private void checkCorrectAnswer(){
String tryAnswer = "";
for (int i = 0; i<answer_length ; i++) {
tryAnswer += EditTextArray[i].getText().toString();
}
if (tryAnswer.matches(answer)){
Log.d("Correct !!","Correct Answer");
}
}
}
AnswerCell.java
public class AnswerCell extends EditText{
public AnswerCell(final Context context, int cell_size) {
super(context);
this.setId(View.generateViewId());
this.setBackgroundResource(R.color.answerCellBackground);
this.setHeight(cell_size);
this.setWidth(cell_size);
this.setFilters(new InputFilter[] {new InputFilter.LengthFilter(1)});
this.setCursorVisible(false);
this.setGravity(Gravity.CENTER);
this.setOnFocusChangeListener( new View.OnFocusChangeListener(){
public void onFocusChange( View view, boolean hasfocus){
if(hasfocus){
view.setBackgroundResource( R.drawable.answer_cell_has_focus);
}
else{
view.setBackgroundResource( R.drawable.answer_cell_lost_focus);
}
}
});
this.setOnKeyListener(new OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
//You can identify which key pressed buy checking keyCode value with KeyEvent.KEYCODE_
if(keyCode == KeyEvent.KEYCODE_DEL) {
((EditText)v).setText("");
return true;
}
return false;
}
});
}
}
thanks !
It will work with this code
TextWatcher watcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//YOUR CODE
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//YOUR CODE
}
#Override
public void afterTextChanged(Editable s) {
String outputedText = s.toString();
// mOutputText.setText(outputedText);
}
};
Then add this in oncreate
mInputText.addTextChangedListener(watcher);
e2.addTextChangedListener(watcher);
e3.addTextChangedListener(watcher);
e4.addTextChangedListener(watcher);
I'm having problems to get the position of my View inside a ListView when TextWatcher triggers for changes in EditText.
Each CardView has two EditTexts and two Spinners. When I make some change in the values for the name of the product (the EditText in the left) and for the spinners, my code get the correctly the position of the CardView in the list.
However, when I change the value of the price by typing it, my code cannot get it's position.
The position of the CardView is gotten in the line...
final int posicao = Integer.parseInt(consumableInfo.getName()), which consumableInfo is the class listed in my Adapater, and consumableInfo.getName gets the name of the card, which is equal to the position of the card. Like "0", "1", "2"...
This happens because everytime I call...
holder.mAutoCompleteTextView.setOnItemClickListener for the AutoCompleteEditText on the left;
holder.mDivideConsumableSpinner.setOnItemSelectedListener for each spinner;
...my code iterates again over BindData. However, when I call...
holder.mConsumablePriceTextView.addTextChangedListener(priceTextWatcher) for the EditText on the right;
... my code DO NOT iterates again.
I'm trying to find another way to get it's position, but I'm having problems with that. Maybe forcing a way to posicao get the value, or creating a customTextWatcher that implements TextWatcher and gets consumableInfo as a parameter.
public class ConsumableAdapter extends RecyclerView.Adapter<ConsumableAdapter.ConsumableViewHolder> {
/*...some code ommited...*/
int posicaoGlobal;
public ConsumableAdapter(Context context, List<ConsumableInfo> contactList) {...}/*...some code ommited...*/
}
public class ConsumableViewHolder extends RecyclerView.ViewHolder {
public AutoCompleteTextView mAutoCompleteTextView;
public Spinner mDivideConsumableSpinner;
public Spinner mUnitsConsumableSpinner;
public EditText mConsumablePriceTextView;
public ConsumableViewHolder(View itemView) {
/*...*/
}
public void bindData(ConsumableInfo consumableInfo, ConsumableViewHolder holder, Context context) {
final int posicao = Integer.parseInt(consumableInfo.getName());
posicaoGlobal = posicao;
ArrayAdapter adapter = new ArrayAdapter(mContext, android.R.layout.select_dialog_item,
Constants.CONSUMABLE_CONSTANTS);
holder.mAutoCompleteTextView.setAdapter(adapter);
/* position is updated withmAutoCompleteTextView.setOnItemClickListener */
holder.mAutoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener({
updateTotalPrice(posicao);
/*...*/
});
/*position is NOT updated with addTextChangedListener*/
holder.mConsumablePriceTextView.addTextChangedListener(priceTextWatcher);
/*position is updated with setOnItemSelectedListener in both Spinners*/
holder.mDivideConsumableSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
updateTotalPrice(posicao);
/*...*/
});
//product units
holder.mUnitsConsumableSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
updateTotalPrice(posicao);
/*...*/
});
}
private void updateTotalPrice(int posicao) {
/*...*/
mTotalPrice = getTotalPrice(BotequimActivity.mProductList, mPercent);
BotequimActivity.mTotalPriceTextView.setText(getTotalPriceString());
FormatStringAndText.setPriceTextViewSize(mTotalPrice, BotequimActivity.mTotalPriceTextView);
}
}
private void updateTotalPrice(int posicao, String priceString) {
/*...*/
BotequimActivity.mTotalPriceTextView.setText(getTotalPriceString());
FormatStringAndText.setPriceTextViewSize(mTotalPrice, BotequimActivity.mTotalPriceTextView);
}
private final TextWatcher priceTextWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (count != 0) {
if (FormatStringAndText.isNumeric(s.toString())) {
mProductPriceBeforeChange = Double.parseDouble(s.toString());
}
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Toast.makeText(mContext, "posicao =" + posicaoGlobal, Toast.LENGTH_SHORT).show();
if (s.toString().length() == 0) {
updateTotalPrice(posicaoGlobal, "0.00");
} else {
if (!isAutoCompleteClicked) {
if (FormatStringAndText.isNumeric(s.toString())) {
mProductPriceAfterChange = Double.parseDouble(s.toString());BotequimActivity.mTotalPriceTextView.setText(getTotalPriceString());
// FormatStringAndText.setPriceTextViewSize(mTotalPrice, BotequimActivity.mTotalPriceTextView);
updateTotalPrice(posicaoGlobal, s.toString());
} else {
}
} else {
isAutoCompleteClicked = false;
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
public Double getTotalPrice(ArrayList<Product> productList, Double percent) {
mTotalPrice = 0;
for (Product product : productList) {
mTotalPrice = mTotalPrice + percent * (product.getUnits() * (product.getDoublePrice()) / product.getDividedBy());
}
return mTotalPrice;
}
}
You need to save the position when you create the TextWatcher. I would do this with an inner subclass:
// this is an inner class so it will have an implicit reference to
// the adapter (ConsumableAdapter.this)
public class PriceTextWatcher implements TextWatcher {
private int mPos;
public PriceTextWatcher(int position) {
super();
mPos = position;
}
// now add your TextWatcher implementation here and use mPos for position
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// ...
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// ...
}
#Override
public void afterTextChanged(Editable s) {}
}
Now you can initialize the position when you create the TextWatcher:
holder.mConsumablePriceTextView.addTextChangedListener(new PriceTextWatcher(posicao));
You will have multiple TextWatchers instead of the single final TextWatcher you currently have, but that's the trade-off for getting the position value where it needs to be.
Solved. I had to call priceTextWatcher as an argument with it's constructor, just like AdapterView.OnItemSelectedListener(). The correct one is:
holder.mConsumablePriceTextView.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//...
}
//...methods inside here
}