获取Android点击事件,Android获取所有控件的点击事件很难?

以下几种方式

1:FrameLayout方式

2: 反射方式

3:AOP方式

疑问解答

Aspectj框架的集成方式

三种方法的区别

获取更多View的点击方法

第一种:FrameLayout方式

代码实现

PageViewLifecycleHelper.with(this).addPageViewListener(PageViewType.frameLayout,basePageViewListener)

3568d428b568?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image.png

原理说明

1:在Application中通过registerActivityLifecycleCallbacks来注册Activity的生命周期。

2:

在onActivityStarted对当前页面的View进行遍历并保存至List中。

3:

在每一个Activity的最外层实现FrameLayout。

4:

通过onInterceptTouchEvent的触摸事件来遍历View来实现。

5:

对AdapterView与RecyclerView则通过重写点击事件来实现。

6:

在onActivityPaused对当前页面的View进行清空。

第二种:反射方式

代码实现

PageViewLifecycleHelper.with(this).addPageViewListener(PageViewType.hookView,basePageViewListener)

3568d428b568?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image.png

原理说明

1:

在Application中通过registerActivityLifecycleCallbacks来注册Activity的生命周期。

2:在onActivityStarted对当前页面的View进行遍历并保存至List中。

3:

反射在View的mOnClickListener中设置自定义的点击事件。

4:

对AdapterView与RecyclerView则通过重写点击事件来实现。

5:

在onActivityPaused对当前页面的View进行清空。

第三种:AOP方式

代码实现

PageViewAspectjHelper.with().setBasePageViewListener(basePageViewListener)

3568d428b568?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image.png

原理说明

1:通过Aspectj框架来对全局的View进行切入。

2:使用@Aspect表示切入的类。

3:使用@After在切入的方法执行异步执行自定义的相关逻辑。

疑问解答

Aspectj框架的集成方式

现阶段有开源的框架,可以简单的在Android中使用,如gradle_plugin_android_aspectjx。 如果想自己集成,则步骤如下:

在aspectj上找到最新的版本。

在项目的根build文件内加入相关依赖。如: classpath 'org.aspectj:aspectjtools:1.9.4'

在使用Aspectj的module中的build文件内加入相关代码与依赖。如

import com.android.build.gradle.LibraryPlugin

import org.aspectj.bridge.IMessage

import org.aspectj.bridge.MessageHandler

import org.aspectj.tools.ajc.Main

android.libraryVariants.all {

variant -> LibraryPlugin plugin = project.plugins.getPlugin(LibraryPlugin)

JavaCompile javaCompile = variant.javaCompile

javaCompile.doLast {

String[] args = ["-showWeaveInfo",

"-1.8",

"-inpath", javaCompile.destinationDir.toString(),

"-aspectpath", javaCompile.classpath.asPath,

"-d", javaCompile.destinationDir.toString(),

"-classpath", javaCompile.classpath.asPath,

"-bootclasspath", plugin.project.android.bootClasspath.join(

File.pathSeparator)]

MessageHandler handler = new MessageHandler(true)

new Main().run(args, handler)

def log = project.logger

for (IMessage message : handler.getMessages(null, true)) {

switch (message.getKind()) {

case IMessage.ABORT:

case IMessage.ERROR:

case IMessage.FAIL:

log.error message.message, message.thrown

break

case IMessage.WARNING:

case IMessage.INFO:

log.info message.message, message.thrown

break

case IMessage.DEBUG:

log.debug message.message, message.thrown

break

}

}

}

}

dependencies {

api 'org.aspectj:aspectjrt:1.9.4'

}

1:在app中的build文件中加入相关代码,如:

import org.aspectj.bridge.IMessage

import org.aspectj.bridge.MessageHandler

import org.aspectj.tools.ajc.Main

final def log = project.logger

final def variants = project.android.applicationVariants

variants.all { variant ->

if (!variant.buildType.isDebuggable()) {

log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")

return

}

JavaCompile javaCompile = variant.javaCompile

javaCompile.doLast {

String[] args = ["-showWeaveInfo",

"-1.8",

"-inpath", javaCompile.destinationDir.toString(),

"-aspectpath", javaCompile.classpath.asPath,

"-d", javaCompile.destinationDir.toString(),

"-classpath", javaCompile.classpath.asPath,

"-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]

log.debug "ajc args: " + Arrays.toString(args)

MessageHandler handler = new MessageHandler(true)

new Main().run(args, handler)

for (IMessage message : handler.getMessages(null, true)) {

switch (message.getKind()) {

case IMessage.ABORT:

case IMessage.ERROR:

case IMessage.FAIL:

log.error message.message, message.thrown

break

case IMessage.WARNING:

log.warn message.message, message.thrown

break

case IMessage.INFO:

log.info message.message, message.thrown

break

case IMessage.DEBUG:

log.debug message.message, message.thrown

break

}

}

}

}

相关配置完成之后,即可根据相关方法来实现自己的逻辑。

三种方法的区别

AOP的方式侵入的更全面一点,动态的静态的布局都可以使用。但是只针对设置了相关方法的View才可以。比如View未设置OnClick事件则无法监听。

FrameLayout的方式只能获取到静态的布局,但是所有控件的点击都可以拿到,无论是否设置了相关方法。

反射的方式速度相对比较慢,但也是只能拿到静态布局。

获取更多View的点击方法

现阶段只获取了普通View,AdapterView,RecycleView这几个,当然同样的思路可以放在更多的View上,如:ExpandableListView等等。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值