343N 343N - 10 days ago 6
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.

Comments