这篇文章 特别简单是给刚学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;
}
}
网友评论