每行都有一个带有EditText(数量框)的ListView。当用户设置所需数量时,新值将更新SQLite数据库中的相应列,而不是使用修改后的值重新填充ListView。 要触发此过程,我在EditText上使用 addTextChangedListener ,它可以正常工作。
我的问题是每次滚动时都会调用侦听器,这会触发上述过程,甚至不会触及数量框。
如何在滚动时避免触发addTextChangedListener?我的 spinner.setOnItemSelectedListener 也会出现同样的问题。我试图让getView方法之外的监听器,但没有任何运气...... :(
自定义ListView:
public class PhotosListViewAdapter extends ArrayAdapter<ImageItemsSetter> {
DeleteImageListener dListener;
private Context context;
private int layoutResourceId;
private ArrayList<ImageItemsSetter> data = new ArrayList<ImageItemsSetter>();
//standard constructor
public PhotosListViewAdapter(Context context, int layoutResourceId, ArrayList<ImageItemsSetter> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
static class ViewHolder {
public ImageView Img;
public EditText quantity;
public Spinner spinner;
public Button delete;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
ImageItemsSetter image = data.get(position);
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new ViewHolder();
holder.Img = (ImageView) row.findViewById(R.id.Img);
holder.quantity = (EditText) row.findViewById(R.id.quantity);
// holder.quantity.addTextChangedListener(new GenericTextWatcher(holder.quantity));
holder.spinner = (Spinner) row.findViewById(R.id.photo_format);
holder.delete = (Button) row.findViewById(R.id.deleteImage);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
holder.Img.setImageBitmap(image.getTheImage());
holder.quantity.setText(image.getQuantity());
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context,
R.array.formats_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
holder.spinner.setAdapter(adapter);
//The delete button
holder.delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (dListener != null) {
dListener.onDeletePressed(position);
}
}
});
holder.spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
dListener.onFormatChanged(parent.getItemAtPosition(pos).toString(), data.get(position).getName());
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
});
holder.quantity.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) { }
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) { }
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
dListener.onQuantityChanged(s.toString(), data.get(position).getName());
}
});
return row;
}
/*
private class GenericTextWatcher implements TextWatcher {
private View view;
private GenericTextWatcher(View view) {
this.view = view;
}
// 3. saving the quantity box before it gets outside the visible area
@Override
public void afterTextChanged(Editable s) {
final EditText editText = (EditText) view;
dListener.onQuantityChanged(editText.getText().toString(), "tom");
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
}
*/
//Interface to send selected image's position for deletion
public void setDeleteImageListener(DeleteImageListener listener) {
this.dListener = listener;
}
public static interface DeleteImageListener {
public void onDeletePressed(int position);
public void onQuantityChanged(String quantity, String name);
public void onFormatChanged(String format, String name);
}
主机活动部分(这里我使用2个自定义界面接收响应):
@Override
public void onQuantityChanged(String quantity, String name) {
System.out.println("quantity set to: " + quantity + " " + name );
datasource.updateImageQuantiry(name, quantity);
rePopulateList();
}
@Override
public void onFormatChanged(String format, String name) {
System.out.println("format set to: " + format + " name: " + name);
}
答案 0 :(得分:1)
向ListView添加滚动侦听器,并在某处设置一个标志以了解ListView是否滚动。
然后在onTextChanged中,在调用你的监听器之前检查那个标志
这将起作用,因为在滚动发生之前调用AbsListView.OnScrollListener.onScrollStateChanged方法。
public abstract void onScrollStateChanged(AbsListView视图,int scrollState)
列表视图时要调用的回调方法 或正在滚动网格视图。如果正在滚动视图,这个 在渲染滚动的下一帧之前将调用方法。 特别是,它会在调用getView之前被调用(int, View,ViewGroup)。
您甚至可以使您的类PhotosListViewAdapter实现OnScrollListener接口,然后将您的适配器设置为ListView的滚动侦听器。这样您就可以管理适配器内的滚动标志状态。
public class PhotosListViewAdapter extends ArrayAdapter<String> implements AbsListView.OnScrollListener {
public boolean scrolling;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
scrolling = scrollState != SCROLL_STATE_IDLE ;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
//...
//TextWatcher.onTextChanged()
//if(!scrolling) dListener.onQuantityChanged(s.toString(), data.get(position));
//...
}
//In your activity or fragment:
//myListView.setOnScrollListener(myPhotoListViewAdapter);
答案 1 :(得分:0)
这是因为您的适配器在滚动时在视图上设置文本,这应该会启动您的监听器。
此外,您应该只设置一次听众,而不是每次都调用getView()
。