github地址android
本产品不提供远程依赖,仅提供思路与实现方式git
分三种方法实现github
PageViewLifecycleHelper.with(this).addPageViewListener(PageViewType.frameLayout,basePageViewListener)
复制代码
参数 | 参数类型 | 参数说明 |
---|---|---|
PageViewType.frameLayout | int | 具体实现方式 |
basePageViewListener | BasePageViewListener | 点击回调 |
onClick(view) 普通View的点击事件apache
参数 | 参数类型 | 参数说明 |
---|---|---|
view | View | 当前点击的控件布局 |
onItemClick(parent,view,position,id) AdapterView的点击事件api
参数 | 参数类型 | 参数说明 |
---|---|---|
parent | AdapterView | 当前的AdapterView |
view | View | 当前的AdapterView的item的view的布局 |
position | int | 当前item在AdapterView中适配器里的位置 |
id | long | 当前item在AdapterView中的行数 |
onItemSelected(parent,view,position,id) AdapterView的选择事件app
参数 | 参数类型 | 参数说明 |
---|---|---|
parent | AdapterView | 当前的AdapterView |
view | View | 当前的AdapterView的item的view的布局 |
position | int | 当前item在AdapterView中适配器里的位置 |
id | long | 当前item在AdapterView中的行数 |
onNothingSelected(parent,view,position,id) AdapterView的未选择事件框架
参数 | 参数类型 | 参数说明 |
---|---|---|
parent | AdapterView | 当前的AdapterView |
onItemClick(RecyclerView recyclerView, View view, int position) RecyclerView的点击事件异步
参数 | 参数类型 | 参数说明 |
---|---|---|
recyclerView | RecyclerView | 当前的RecyclerView |
view | View | 当前的RecyclerView的item的view的布局 |
position | int | 当前item在RecyclerView中适配器里的位置 |
- 在Application中经过registerActivityLifecycleCallbacks来注册Activity的生命周期。
- 在onActivityStarted对当前页面的View进行遍历并保存至List中。
- 在每个Activity的最外层实现FrameLayout。
- 经过onInterceptTouchEvent的触摸事件来遍历View来实现。
- 对AdapterView与RecyclerView则经过重写点击事件来实现。
- 在onActivityPaused对当前页面的View进行清空。
PageViewLifecycleHelper.with(this).addPageViewListener(PageViewType.hookView,basePageViewListener)
复制代码
参数 | 参数类型 | 参数说明 |
---|---|---|
PageViewType.frameLayout | int | 具体实现方式 |
basePageViewListener | BasePageViewListener | 点击回调 |
- 在Application中经过registerActivityLifecycleCallbacks来注册Activity的生命周期。
- 在onActivityStarted对当前页面的View进行遍历并保存至List中。
- 反射在View的mOnClickListener中设置自定义的点击事件。
- 对AdapterView与RecyclerView则经过重写点击事件来实现。
- 在onActivityPaused对当前页面的View进行清空。
PageViewAspectjHelper.with().setBasePageViewListener(basePageViewListener)
复制代码
参数 | 参数类型 | 参数说明 |
---|---|---|
basePageViewListener | BasePageViewListener | 点击回调 |
- 经过Aspectj框架来对全局的View进行切入。
- 使用@Aspect表示切入的类。
- 使用@After在切入的方法执行异步执行自定义的相关逻辑。
现阶段有开源的框架,能够简单的在Android中使用,如gradle_plugin_android_aspectjx。 若是想本身集成,则步骤以下:svg
- 在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'
}
复制代码
- 在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,AdapterView,RecycleView这几个,固然一样的思路能够放在更多的View上,如:ExpandableListView等等。