java - 按下按钮时重复任务(来自适配器)
问题描述
我试图在按下按钮时重复一个动作。
我已经搜索了一些解决方案,但都是无用的。我的假设是这可能会发生,因为我button
的 s 在一个ListView
项目内。
我想处理以下应用程序:
我可以EditText
通过单次按下或按住按钮一段时间来增加(+1)或减少(-1)每个(计数)的值。
我的适配器代码:
public class ItemAdapter extends ArrayAdapter<SizeCount> {
private Collection<SizeCount> list;
private static final String LOG_TAG = "MemoListAdapter";
EditText tbCount;
TextView tvSize;
Button btAdd, btSubstract;
public ItemAdapter (Context context,List<SizeCount> list){
super(context,0,list);
this.list = list;
}
public Collection<SizeCount> getList() {
return list;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
View v = convertView;
if(v == null){
v = LayoutInflater.from(getContext()).inflate(
R.layout.entry_size_count,parent,false
);
}
final SizeCount item = getItem(position);
tvSize = (TextView) v.findViewById(R.id.tvSize);
tvSize.setFocusable(false);
tbCount= (EditText) v.findViewById(R.id.tbCount);
tvSize .setText(item.getArticles().getSize());
tbCount.setText(item.getCount()+"");
btAdd= v.findViewById(R.id.btAdd);
btAdd.setOnTouchListener(new View.OnTouchListener() {
private Handler mHandler;
@Override public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mHandler != null) return true;
mHandler = new Handler();
mHandler.postDelayed(mAction, 500);
break;
case MotionEvent.ACTION_UP:
if (mHandler == null) return true;
mHandler.removeCallbacks(mAction);
mHandler = null;
break;
}
return false;
}
Runnable mAction = new Runnable() {
@Override public void run() {
float currentCount = item.getCount();
float nextCount = currentCount + 1;
item.setCount(nextCount);
item.setModified(true);
notifyDataSetChanged();
mHandler.postDelayed(this, 500);
}
};
});
return v;
} catch (Exception ex) {
Log.e(LOG_TAG, "error", ex);
return null;
}
}
}
我得到的行为:
- 当我单击 (+)
button
一次时:没有任何变化。 - 当我按住 (+)
button
时:它开始增加并且永不停止。即使我释放它。
解决方案
当您按下按钮并使用 notifyDataSetChanged() 方法时,它将导致 MotionEvent.ACTION_UP 失败。
请使用 viewHolder.tbCount.setText() 方法替换 notifyDataSetChanged() 并且不要忘记更新 SizeCount(item) 对象值。
public class ItemAdapter extends ArrayAdapter<SizeCount> {
private static final String LOG_TAG = "MemoListAdapter";
private Collection<SizeCount> list;
public ItemAdapter(Context context, List<SizeCount> list) {
super(context, 0, list);
this.list = list;
}
public Collection<SizeCount> getList() {
return list;
}
@SuppressLint("ClickableViewAccessibility")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final SizeCount item = getItem(position);
if (item == null) return convertView;
final ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.entry_size_count, parent, false);
viewHolder = new ViewHolder();
viewHolder.tbCount = (EditText) convertView.findViewById(R.id.tbCount);
viewHolder.tvSize = (TextView) convertView.findViewById(R.id.tvSize);
viewHolder.btAdd = convertView.findViewById(R.id.btAdd);
viewHolder.btAdd.setOnTouchListener(new View.OnTouchListener() {
private Handler mHandler = new Handler();
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mHandler.postDelayed(mAction, 500);
break;
case MotionEvent.ACTION_UP:
mHandler.removeCallbacks(mAction);
break;
}
return false;
}
Runnable mAction = new Runnable() {
@Override
public void run() {
float currentCount = item.getCount();
float nextCount = currentCount + 1;
item.setModified(true);
// update SizeCount value
item.setCount(nextCount);
// set value to tbCount
viewHolder.tbCount.setText(String.valueOf(item.getCount()));
// this will cause the MotionEvent.ACTION_UP fail
// notifyDataSetChanged();
mHandler.postDelayed(this, 500);
}
};
});
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tvSize.setFocusable(false);
viewHolder.tvSize.setText(item.getArticles().getSize());
viewHolder.tbCount.setText(item.getCount() + "");
return convertView;
}
private class ViewHolder {
TextView tvSize;
TextView tbCount;
Button btAdd;
}
}
我认为在这种情况下调用 notifyDataSetChanged() 方法并不好。刷新整个视图只是为了更改单个项目的值是错误的。
推荐阅读
- laravel - Laravel nova api 性能缓慢
- docker - Docker 组合语法
- android - Android - 以无代码方式集成您的库以显示视图
- python - 如何使用百分位数数组查找一个值的百分位数
- node.js - FieldPath 字段名称可能不以“$”开头
- python - 将一个迭代序列乘以另一个迭代序列
- r - 有人可以向我解释为什么这个平等测试不起作用吗?
- angular - Angular Sanctum 基于会话的跨域 CSRF Cookie
- html - 使用 Visual Studio Code 在经典 ASP 中测试 HTML
- apache-kafka-streams - KStream - KTable join:使用 Ktable 数据丰富流