按下按钮时重复任务(来自适配器)

时间:2019-01-11 09:01:17

标签: java android multithreading button

我试图在按下按钮时重复执行一个动作。

我已经搜索了一些解决方案,但都没有用。我的假设是可能会发生这种情况,因为我的button位于ListView项内。

我要处理以下应用程序:

enter image description here

通过单次按下或按住按钮一会儿,我可以递增(+1)或递减(-1)每个EditText(计数)的值。

我的适配器代码:

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时:它开始增加,从不 停止。即使我释放它。

1 个答案:

答案 0 :(得分:1)

按下按钮并使用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()方法不是很好。刷新整个视图只是为了更改单个项目的值是错误的。