Android:长按连续响应的Button

在电商类app的购物车页面,经常会有这样的需求:长按“+”按钮或者“-”按钮时,购物车中的商品数量连续的增加或减少。

本例的目的就是为了实现这个效果。预览图:


1.自定义Button.

/**
 * 长按连续响应的Button
 * Created by admin on 15-6-1.
 */
public class LongClickButton extends Button {
    /**
     * 长按连续响应的监听,长按时将会多次调用该接口中的方法直到长按结束
     */
    private LongClickRepeatListener repeatListener;
    /**
     * 间隔时间(ms)
     */
    private long intervalTime;

    private MyHandler handler;

    public LongClickButton(Context context) {
        super(context);

        init();
    }

    public LongClickButton(Context context, AttributeSet attrs) {
        super(context, attrs);

        init();
    }

    public LongClickButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    /**
     * 初始化监听
     */
    private void init() {
        handler = new MyHandler(this);
        setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                new Thread(new LongClickThread()).start();
                return true;
            }
        });
    }

    /**
     * 长按时,该线程将会启动
     */
    private class LongClickThread implements Runnable {
        private int num;

        @Override
        public void run() {
            while (LongClickButton.this.isPressed()) {
                num++;
                if (num % 5 == 0) {
                    handler.sendEmptyMessage(1);
                }

                SystemClock.sleep(intervalTime / 5);
            }
        }
    }

    /**
     * 通过handler,使监听的事件响应在主线程中进行
     */
    private static class MyHandler extends Handler {
        private WeakReference<LongClickButton> ref;

        MyHandler(LongClickButton button) {
            ref = new WeakReference<>(button);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            LongClickButton button = ref.get();
            if (button != null && button.repeatListener != null) {
                button.repeatListener.repeatAction();
            }
        }
    }

    /**
     * 设置长按连续响应的监听和间隔时间,长按时将会多次调用该接口中的方法直到长按结束
     *
     * @param listener     监听
     * @param intervalTime 间隔时间(ms)
     */
    public void setLongClickRepeatListener(LongClickRepeatListener listener, long intervalTime) {
        this.repeatListener = listener;
        this.intervalTime = intervalTime;
    }

    /**
     * 设置长按连续响应的监听(使用默认间隔时间100ms),长按时将会多次调用该接口中的方法直到长按结束
     *
     * @param listener 监听
     */
    public void setLongClickRepeatListener(LongClickRepeatListener listener) {
        setLongClickRepeatListener(listener, 100);
    }

    public interface LongClickRepeatListener {
        void repeatAction();
    }
}
2.在Activity中调用:

LongClickButton buttonSub = (LongClickButton) findViewById(R.id.long_click_button1);
        LongClickButton buttonAdd = (LongClickButton) findViewById(R.id.long_click_button2);
        final TextView numberTV = (TextView) findViewById(R.id.main_number);

        //连续减
        buttonSub.setLongClickRepeatListener(new LongClickButton.LongClickRepeatListener() {
            @Override
            public void repeatAction() {
                numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) - 1));
            }
        }, 50);
        //连续加
        buttonAdd.setLongClickRepeatListener(new LongClickButton.LongClickRepeatListener() {
            @Override
            public void repeatAction() {
                numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) + 1));
            }
        }, 50);

        //减1
        buttonSub.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) - 1));
            }
        });
        //加1
        buttonAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) + 1));
            }
        });

3.很多时候,长按的事件和普通点击的事件是一样的(也就是说,长按相当于连续的快速点击)。这种情况下,自定义Button可以更加简洁:即在长按时,连续的调用普通的OnClickListener。

public class LongClickButton2 extends Button {
    /**
     * 间隔时间(ms)
     */
    private long intervalTime = 50;

    private MyHandler handler;

    public LongClickButton2(Context context) {
        super(context);

        init();
    }

    public LongClickButton2(Context context, AttributeSet attrs) {
        super(context, attrs);

        init();
    }

    public LongClickButton2(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    /**
     * 初始化监听
     */
    private void init() {
        handler = new MyHandler(this);
        setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                new Thread(new LongClickThread()).start();
                return true;
            }
        });
    }

    /**
     * 长按时,该线程将会启动
     */
    private class LongClickThread implements Runnable {
        private int num;

        @Override
        public void run() {
            while (LongClickButton2.this.isPressed()) {
                num++;
                if (num % 5 == 0) {
                    handler.sendEmptyMessage(1);
                }

                SystemClock.sleep(intervalTime / 5);
            }
        }
    }

    /**
     * 通过handler,使监听的事件响应在主线程中进行
     */
    private static class MyHandler extends Handler {
        private WeakReference<LongClickButton2> ref;

        MyHandler(LongClickButton2 button) {
            ref = new WeakReference<>(button);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            LongClickButton2 button = ref.get();
            if (button != null) {
                //直接调用普通点击事件
                button.performClick();
            }
        }
    }

    public void setIntervalTime(long intervalTime) {
        this.intervalTime = intervalTime;
    }
}



  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值