這篇文章 特別簡(jiǎn)單是給剛學(xué)Android的粉絲寫的 前兩天有人問這順便就寫了一下 主要介紹了Android編程實(shí)現(xiàn)長(zhǎng)按Button按鈕連續(xù)響應(yīng)功能,涉及Android自定義按鈕及事件響應(yīng)操作相關(guān)技巧,需要的朋友可以參考下
本文實(shí)例講述了Android編程實(shí)現(xiàn)長(zhǎng)按Button按鈕連續(xù)響應(yīng)功能涯捻。分享給大家供大家參考罩阵,具體如下:
在電商類app的購(gòu)物車頁面,經(jīng)常會(huì)有這樣的需求:長(zhǎng)按“+”按鈕或者“-”按鈕時(shí)搜骡,購(gòu)物車中的商品數(shù)量連續(xù)的增加或減少。
本例的目的就是為了實(shí)現(xiàn)這個(gè)效果佑女。預(yù)覽圖:
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. 第一種實(shí)現(xiàn)
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;
/**
* 長(zhǎng)按連續(xù)響應(yīng)的Button 第一種實(shí)現(xiàn)方法
*/
public class LongClickButton extends Button {
/**
* 長(zhǎng)按連續(xù)響應(yīng)的監(jiān)聽记靡,長(zhǎng)按時(shí)將會(huì)多次調(diào)用該接口中的方法直到長(zhǎng)按結(jié)束
*/
private LongClickRepeatListener repeatListener;
/**
* 間隔時(shí)間(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();
}
/**
* 初始化監(jiān)聽
*/
private void init() {
handler = new MyHandler(this);
setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
new Thread(new LongClickThread()).start();
return true;
}
});
}
/**
* 長(zhǎng)按時(shí),該線程將會(huì)啟動(dòng)
*/
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团驱,使監(jiān)聽的事件響應(yīng)在主線程中進(jìn)行
*/
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();
}
}
}
/**
* 設(shè)置長(zhǎng)按連續(xù)響應(yīng)的監(jiān)聽和間隔時(shí)間摸吠,長(zhǎng)按時(shí)將會(huì)多次調(diào)用該接口中的方法直到長(zhǎng)按結(jié)束
*
* @param listener 監(jiān)聽
* @param intervalTime 間隔時(shí)間(ms)
*/
public void setLongClickRepeatListener(LongClickRepeatListener listener, long intervalTime) {
this.repeatListener = listener;
this.intervalTime = intervalTime;
}
/**
* 設(shè)置長(zhǎng)按連續(xù)響應(yīng)的監(jiān)聽(使用默認(rèn)間隔時(shí)間100ms),長(zhǎng)按時(shí)將會(huì)多次調(diào)用該接口中的方法直到長(zhǎng)按結(jié)束
*
* @param listener 監(jiān)聽
*/
public void setLongClickRepeatListener(LongClickRepeatListener listener) {
setLongClickRepeatListener(listener, 100);
}
public interface LongClickRepeatListener {
void repeatAction();
}
}
2. 在Activity中調(diào)用:
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() {
// 長(zhǎng)按連續(xù)加
buttonAdd.setLongClickRepeatListener(() -> {
numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) + 1));
}, 50);
// 長(zhǎng)按連續(xù)減
buttonSub.setLongClickRepeatListener(() -> {
numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) - 1));
}, 50);
// 點(diǎn)擊加1
buttonAdd.setOnClickListener(v -> {
numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) + 1));
});
// 點(diǎn)擊減1
buttonSub.setOnClickListener(v -> {
numberTV.setText(String.valueOf(Integer.parseInt(numberTV.getText().toString()) - 1));
});
}
3. 第二種實(shí)現(xiàn)
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;
/**
* 長(zhǎng)按連續(xù)響應(yīng)的Button 第二種實(shí)現(xiàn)方法
* 很多時(shí)候嚎花,長(zhǎng)按的事件和普通點(diǎn)擊的事件是一樣的(也就是說寸痢,長(zhǎng)按相當(dāng)于連續(xù)的快速點(diǎn)擊)。
* 這種情況下紊选,自定義Button可以更加簡(jiǎn)潔:即在長(zhǎng)按時(shí)啼止,連續(xù)的調(diào)用普通的OnClickListener
*/
public class LongClickButton2 extends Button {
/**
* 間隔時(shí)間(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();
}
/**
* 初始化監(jiān)聽
*/
private void init() {
handler = new MyHandler(this);
setOnLongClickListener(v -> {
new Thread(new LongClickThread()).start();
return true;
});
}
/**
* 長(zhǎng)按時(shí),該線程將會(huì)啟動(dòng)
*/
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兵罢,使監(jiān)聽的事件響應(yīng)在主線程中進(jìn)行
*/
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) {
//直接調(diào)用普通點(diǎn)擊事件
button.performClick();
}
}
}
/**
* 設(shè)置長(zhǎng)按間隔時(shí)間
* @param intervalTime 間隔時(shí)間
*/
public void setIntervalTime(long intervalTime) {
this.intervalTime = intervalTime;
}
}