Android 实现长按连续点击响应功能

作者: i小灰 | 来源:发表于2023-09-25 16:43 被阅读0次

    这篇文章 特别简单是给刚学Android的粉丝写的 前两天有人问这顺便就写了一下 主要介绍了Android编程实现长按Button按钮连续响应功能,涉及Android自定义按钮及事件响应操作相关技巧,需要的朋友可以参考下

    本文实例讲述了Android编程实现长按Button按钮连续响应功能。分享给大家供大家参考,具体如下:

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

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


    1. 布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="horizontal"
        tools:context=".MainActivity">
    
    <!--  注意 这里要填写你自定义View的包名  -->
        <com.p.h.view.LongClickButton
            android:id="@+id/long_click_button1"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:background="#00c483"
            android:gravity="center"
            android:text="+"
            android:textColor="#FFFFFF"
            android:textSize="50dp" />
    
        <TextView
            android:id="@+id/main_number"
            android:layout_width="wrap_content"
            android:layout_height="80dp"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            android:gravity="center"
            android:text="0"
            android:textColor="#000000"
            android:textSize="28dp" />
    
        <com.p.h.view.LongClickButton
            android:id="@+id/long_click_button2"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:background="#00c483"
            android:gravity="center"
            android:text="-"
            android:textColor="#FFFFFF"
            android:textSize="50dp" />
    
    </LinearLayout>
    

    2. 自定义View代码

    1. 第一种实现

    import android.content.Context;
    import android.os.Handler;
    import android.os.Message;
    import android.os.SystemClock;
    import android.util.AttributeSet;
    import android.view.View;
    import android.widget.Button;
    
    import java.lang.ref.WeakReference;
    
    /**
     * 长按连续响应的Button 第一种实现方法
     */
    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中调用:

    public class OnLongClickActivity extends AppCompatActivity {
        private LongClickButton buttonAdd;
        private LongClickButton buttonSub;
        private TextView numberTV;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_onlongclick);
            initViews();
            initOnClick();
        }
        private void initViews() {
            buttonAdd = findViewById(R.id.long_click_button1);
            buttonSub = findViewById(R.id.long_click_button2);
            numberTV = findViewById(R.id.main_number);
        }
        private void initOnClick() {
            // 长按连续加
            buttonAdd.setLongClickRepeatListener(() -> {
                numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) + 1));
            }, 50);
    
            // 长按连续减
            buttonSub.setLongClickRepeatListener(() -> {
                numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) - 1));
            }, 50);
    
            // 点击加1
            buttonAdd.setOnClickListener(v -> {
                numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) + 1));
            });
    
            // 点击减1
            buttonSub.setOnClickListener(v -> {
                numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) - 1));
            });
        }
    

    3. 第二种实现

    import android.content.Context;
    import android.os.Handler;
    import android.os.Message;
    import android.os.SystemClock;
    import android.util.AttributeSet;
    import android.widget.Button;
    
    import java.lang.ref.WeakReference;
    
    /**
     * 长按连续响应的Button 第二种实现方法
     * 很多时候,长按的事件和普通点击的事件是一样的(也就是说,长按相当于连续的快速点击)。
     * 这种情况下,自定义Button可以更加简洁:即在长按时,连续的调用普通的OnClickListener
     */
    public class LongClickButton2 extends Button {
        /**
         * 间隔时间(ms)
         */
        private long intervalTime = 100;
        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(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();
                }
            }
        }
    
        /**
         * 设置长按间隔时间
         * @param intervalTime 间隔时间
         */
        public void setIntervalTime(long intervalTime) {
            this.intervalTime = intervalTime;
        }
    }
    

    相关文章

      网友评论

        本文标题:Android 实现长按连续点击响应功能

        本文链接:https://www.haomeiwen.com/subject/kshcbdtx.html