当前位置: 首页 > article >正文

安卓延迟自动点击

1. 自动点击

1.1. 调用View方法

直接调用view.performClick()即可实现单击;调用view.performLongClick()即可实现长按。

但是对一些复杂的操作,View自带的方法可能不够用了,就需要用到第二种方法

1.2. 使用MotionEvent设置触摸事件

可以通过设置MotionEvent对象的参数,再通过View的dispatchTouchEvent分发点击事件,完成一些复杂的触摸操作。

MotionEvent.obtain()参数说明:

参数说明
downTime触发当前触摸事件的手指第一次按下的时间,从手指接触屏幕到手指离开屏幕的时间内,该手指产生的所有触摸事件,其downTime都不会发生改变
eventTime当前触摸事件产生的时间。如果是第一次按下,则该时间与getDownTime相同
action事件类型。如MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE、MotionEvent.ACTION_UP
x事件的x坐标
y事件的y坐标

说明:

downTime、eventTime这两个参数并不控制事件的触发时间,推测是用于处理触摸事件时获取一些数据,比如从按下到当前触摸事件的时间间隔。虽然注释说这两个都需要通过SystemClock.uptimeMillis()
获取,但实测发现,设置任意值都可以触发touch事件。
2. 如果只是要实现点击,x、y设置任意值都可以,只要用对应的view去调用dispatchTouchEvent即可。

2. 延迟点击

我们希望实现的效果是:在延迟自动点击前,可以响应用户操作,延时时间到了以后,自动完成点击事件。

第一时间想到的是启动一个子线程,在子线程中sleep一段时间,然后进行点击,但是会有各种问题,详情如下:

2.1. TimerTask
Timer timer = new Timer();
timer.

schedule(new TimerTask() {
    @Override
    public void run () {
        button.performClick();
    }
},3000L);

这种方法在delayMillis结束之前可以交互,但delayMillis结束之后自动点击会抛出异常:

  • 若使用button.performClick();
    ,则报错android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.;
  • 若使用MotionEvent,则报错android.util.AndroidRuntimeException: Animators may only be run on Looper threads
2.2. new Handler(Looper.getMainLooper()).post()
new Handler(Looper.getMainLooper()).

post(() ->{
        try{
        Thread.

sleep(3000L);
            }catch(
InterruptedException e){
        throw new

RuntimeException(e);
            }
                    button.

performClick();
        }
                );

这种方法在delayMillis结束之前不可以交互,点击事件被累积,delayMillis结束之后自动点击正常,并响应之前积压的点击事件。

2.3. new Handler(Looper.getMainLooper()).postDelayed()
new Handler(Looper.getMainLooper()).

postDelayed(() ->{
        button.

performClick();
},3000L);

这种方法在delayMillis结束之前可以交互,delayMillis结束之后自动点击正常,满足需求。

3. 完整示例

布局文件activity_auto_click.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="horizontal">

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center">

        <Button
                android:id="@+id/auto_click_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@color/white"
                android:text="-" />
    </LinearLayout>
</LinearLayout>

activity类:

package org.tao.hetools.activities;

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;

import androidx.activity.ComponentActivity;
import androidx.annotation.Nullable;

import org.tao.hetools.R;

import java.text.SimpleDateFormat;
import java.util.Date;

public class AutoClickActivity extends ComponentActivity {
    private int index = 0;
    private Button button;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_auto_click);
        button = findViewById(R.id.auto_click_button);
        button.setText(String.valueOf(index));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        button.setOnClickListener(view -> {
            Log.i("AutoClick", "===>click once" + simpleDateFormat.format(new Date()));
            button.setText(String.valueOf(++index));
        });
        button.setOnLongClickListener(view -> {
            Log.i("AutoClick", "===>long click once" + simpleDateFormat.format(new Date()));
            int backgroundColor = ((ColorDrawable) button.getBackground()).getColor();
            button.setBackgroundColor(backgroundColor == Color.WHITE ? Color.BLUE : Color.WHITE);
            return true;
        });
        new Handler(Looper.getMainLooper()).postDelayed(() -> {
            // button.performClick(); // 单击
            // button.performLongClick(); // 长按
            clickOnce(button);
        }, 3000L);
    }

    public void clickOnce(View view) {
        int x = view.getWidth() / 2;
        int y = view.getHeight() / 2;
        long downTime = SystemClock.uptimeMillis();
        // 按下手指
        long actionDown = downTime;
        MotionEvent event = MotionEvent.obtain(downTime, actionDown, MotionEvent.ACTION_DOWN, x, y, 0);
        view.dispatchTouchEvent(event);
        // 抬起手指
        long actionUp = downTime + 500;
        event = MotionEvent.obtain(downTime, actionUp, MotionEvent.ACTION_UP, x, y, 0);
        view.dispatchTouchEvent(event);

        event.recycle();
    }
}

http://www.kler.cn/a/416998.html

相关文章:

  • Matlab机械手碰撞检测应用
  • TCN时间卷积神经网络多变量多步光伏功率预测(Matlab)
  • 仿 RabbitMQ 实现的简易消息队列
  • Oracle的学习心得和知识总结(三十三)|Oracle数据库数据库的SQL ID的底层计算原理分析
  • 激活函数 05 ——Swish
  • 软件模拟I2C案例(寄存器实现)
  • pcb电路板·查错、维修心得笔记
  • 深入解析 Spring MVC:架构、组件与最佳实践
  • 联想Lenovo SR650服务器硬件监控指标解读
  • osg、osgearth源码编译(二)
  • 监控视频汇聚平台:Liveweb视频监控管理平台方案详细介绍
  • PYTHON让大模型固定的返回JSON
  • 泛化调用 :在没有接口的情况下进行RPC调用
  • Windows pc端桌面便签哪个好用?桌面简洁好用的便签软件推荐
  • `console.log`调试完全指南
  • deepin 安装 chrome 浏览器
  • 【Java基础入门篇】三、面向对象和JVM底层分析(2)
  • Artec Leo:航海设备维护的便携式3D扫描利器【沪敖3D】
  • Qt入门5——常用控件3
  • 六通道串口服务器
  • Unity XR Interaction Toolkit 开发教程:抓取交互【3.0以上版本】
  • 无人机的起降装置:探索起飞和降落的秘密 !
  • JS +CSS @keyframes fadeInUp 来定义载入动画
  • 【C语言】连接陷阱探秘(5):头文件
  • 在远程服务器和本地同步数据的指南
  • Java基于SSM框架的跑腿平台小程序【附源码、文档】