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等等。