343N 343N - 2 months ago 17
Java Question

onTextChangedListener goes into loop, but only on first ListView element, any following elements don't loop

I have a moneyConversion class which converts strings as I type them into an EditText which there are multiple of due to being contained in a listview. The conversion works fine for the EditText, but for some reason, the first list item always goes into a loop and hangs when typing something in, where as all other identical EditText boxes work absolutely fine and format without issue.

Here's my adapter.

public class DietyAmountAdapter extends ArrayAdapter {
Context context;
int layoutResourceId;
ArrayList<Dieties> data = null;
int counterTotal;
int currentlyActive;


public DietyAmountAdapter(Context context, int layoutResourceId, ArrayList<Dieties> data){
super(context, layoutResourceId, data);
this.context = context;
this.layoutResourceId = layoutResourceId;
this.data = data;
}


public void addViews(){
SharedPreferences sharedPref = ((Activity) context).getPreferences(Context.MODE_PRIVATE);
currentlyActive = 0;
this.clear();
for(int i = 1; i <= counterTotal; i++) {
boolean a = sharedPref.getBoolean(Integer.toString(i), false);
if (a) {
currentlyActive = currentlyActive + 1;
}
}
}

public View getView(int position, View convertView, ViewGroup parent) {
View ListItem = convertView;

Holder holder;

final Dieties Diety = data.get(position);


if (ListItem == null) {

LayoutInflater inflater = ((Activity) context).getLayoutInflater();
ListItem = inflater.inflate(layoutResourceId, parent, false);

holder = new Holder();
holder.banner = (ImageView) ListItem.findViewById(R.id.DietyBanner);
holder.title = (TextView) ListItem.findViewById(R.id.titleText);
holder.text1 = (EditText) ListItem.findViewById(R.id.text1Amount);
holder.text2 = (EditText) ListItem.findViewById(R.id.text2Amount);
holder.text1Text = (TextView) ListItem.findViewById(R.id.text1Text);
holder.text2Text = (TextView) ListItem.findViewById(R.id.text2Text);

ListItem.setTag(holder);

} else {
holder = (Holder) ListItem.getTag();
}


MyTextWatcher text2Watcher = (new MyTextWatcher() {

public Holder holder;

public void setView(Holder newHolder){
holder = newHolder;
}

@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 (holder.text2.isFocused()) {
holder.text2.removeTextChangedListener(this);
String raw = moneyConversion.unformatToString(s.toString());
double text1Value = moneyConversion.gettext1Value(Double.parseDouble(raw));
holder.text2.setText(moneyConversion.formatLive(raw));
holder.text1.setText(moneyConversion.format(text1Value));
holder.text2.addTextChangedListener(this);
}
}
@Override
public void afterTextChanged(Editable s) {

}
});
MyTextWatcher text1Watcher = (new MyTextWatcher() {

public Holder holder;

public void setView(Holder newHolder){
holder = newHolder;
}
@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 (holder.text1.isFocused()) {
holder.text1.removeTextChangedListener(this);
String text1Value = moneyConversion.unformatToString(s.toString());
String formattedValue = moneyConversion.formatLive(text1Value);
double text2Value = moneyConversion.gettext2Value(Double.parseDouble(text1Value));
holder.text1.setText(formattedValue);
holder.text2.setText(moneyConversion.format(text2Value));
holder.text1.addTextChangedListener(this);
}
}

@Override
public void afterTextChanged(Editable s) {
}
});


HolderOnFocusChangeListener text1FocusListener = new HolderOnFocusChangeListener() {

public DietyAmountAdapter.Holder holder;

public void setHolder(Holder newHolder){
holder = newHolder;
}

@Override
public void onFocusChange(View v, boolean hasFocus) {
// Timer timer = new Timer();
// TimerTask t1 = new TimerTask() {
// @Override
// public void run() {
// holder.text1.clearFocus();
// }
// };

if (hasFocus){
holder.text1.setBackgroundColor(Color.parseColor("#5aa0ce"));
holder.text1Text.setBackgroundColor(Color.parseColor("#5aa0ce"));
holder.text1.setSelection(holder.text1.getText().length());

}
if (!hasFocus) {
if (!holder.text1.getText().toString().isEmpty()) {
holder.text1.setSelection(holder.text1.getText().length());
// holder.text2.setText(moneyConversion.format());
}

holder.text1.setBackgroundColor(Color.parseColor("#424242"));
holder.text1Text.setBackgroundColor(Color.parseColor("#424242"));

// timer.scheduleAtFixedRate(runOnUiThread(t1), 1, 500);

}
}
};

HolderOnFocusChangeListener text2FocusListener = new HolderOnFocusChangeListener() {

public DietyAmountAdapter.Holder holder;

public void setHolder(Holder newHolder){
holder = newHolder;
}

@Override
public void onFocusChange(View v, boolean hasFocus) {
// Timer timer = new Timer();
// TimerTask t2 = new TimerTask() {
// @Override
// public void run() {
// holder.text2.clearFocus();
// }
// };
if (hasFocus){
holder.text2.setBackgroundColor(Color.parseColor("#5aa0ce"));
holder.text2Text.setBackgroundColor(Color.parseColor("#5aa0ce"));
holder.text2.setSelection(holder.text2.getText().length());
}
if (!hasFocus) {
if (!holder.text2.getText().toString().isEmpty()) {
holder.text2.setSelection(holder.text2.getText().length());
}
holder.text2.setBackgroundColor(Color.parseColor("#424242"));
holder.text2Text.setBackgroundColor(Color.parseColor("#424242"));

}
}
};

text2FocusListener.setHolder(holder);
text1FocusListener.setHolder(holder);
text1Watcher.setView(holder);
text2Watcher.setView(holder);

holder.text2.addTextChangedListener(text2Watcher);
holder.text1.addTextChangedListener(text1Watcher);

holder.text2.setOnFocusChangeListener(text2FocusListener);
holder.text1.setOnFocusChangeListener(text1FocusListener);

holder.title.setText(Diety.title);
holder.banner.setImageResource(Diety.banner);


return ListItem;
}
static class Holder {
ImageView banner;
TextView title;
EditText text1;
EditText text2;
TextView text2Text;
TextView text1Text;
}
}


Here's my moneyConversion class:

public class moneyConversion {

public int currentlyActive;
public int counterTotal;
Context context;

public static double gettext1Value(double value){
double newValue = (value / 1.05);
return newValue;
}

public static double gettext2Value(double value){
double newValue = (value * 1.05);
return newValue;
}
public static String format(double value){
DecimalFormat df = new DecimalFormat();
df.applyPattern("###,###,###,###.##");
String formattedValue = df.format(value);
Log.d(TAG, formattedValue);
return formattedValue;

}

public static String formatLive(String s) {
if (s.endsWith(".")) {
return s;
}

DecimalFormat df = new DecimalFormat();
df.applyPattern("###,###,###,###.##");
Double value = Double.parseDouble(s);
String formattedValue = df.format(value);
// Log.d(TAG, formattedValue);
return formattedValue;
}

public static double unformat(String s){
if (s != null && s.isEmpty() ){
return 0;
}
String string = s.replace(",", "");

if (string.isEmpty()) {
return 0;
}
// if (string.equals(".")){
// return Double.parseDouble("0");
// }


return Double.parseDouble(string);
}

public static String unformatToString(String s){
if (s != null && s.isEmpty() ){
return "0";
}
String string = s.replace(",", "");

if (string.isEmpty()) {
return "0";
}
// if (string.equals(".")){
// return Double.parseDouble("0");
// }


return string;
}



}

Answer

Write your textchangeListener inside if (ListItem == null) { condition block, it will work.

What actually happening in your case is whenever you scroll your listview on change listener will call for each and every row that is visible.