- 如何在onResume方法中获取到View的宽高?
有两种方式:post和addOnGlobalLayoutListener
override fun onResume() {super.onResume()Log.e("onresume",tabBottom.width.toString()+"--"+tabBottom.height.toString())//view.post之所以能够拿到宽高,是因为在绘制之前,会将获取宽高的任务放到Handler的消息队列,等到View的绘制结束之后,便会执行。tabBottom.post {Log.e("onresume:post",tabBottom.width.toString()+"--"+tabBottom.height.toString())}tabBottom.viewTreeObserver.addOnGlobalLayoutListener {tabBottom.viewTreeObserver.removeOnGlobalLayoutListener{this}//防止被多次绘制Log.e("onresume:viewTreeObserver",tabBottom.width.toString()+"--"+tabBottom.height.toString())}}
-
为什么无法在onCreate或onResume方法中获取到View的宽高?
因为这个时候view的绘制流程还没有开始。要拿到View的宽高,那么View的绘制流程(measure—layout—draw)至少要完成measure阶段。
有看过onCreate方法源码的同学应该知道:- onCreate流程中的setContentView只是解析了xml,初始化了DecorView,创建了各个控件的对象;即将xml中的 转化为一个TextView对象。并没有启动View的绘制流程。
- 调用performResumeActivity, 该方法中r.activity.performResume(r.startsNotResumed, reason);会调用Activity的onResume方法。执行完Activity的onResume后调用了wm.addView(decor, l);,到这里,开始将此前创建的DecorView添加到视图中,也就是在这之后才开始布局的绘制流程,真正开始是在ViewRootImpl类里面的。
-
子线程中真的不能更新UI吗?
各位读者可以参考这篇博客:https://www.jianshu.com/p/fbd748a533e1 -
接下来,我们来认识下ViewRootImpl类的相关功能:
-
View的三大流程主要涉及到的核心类,笔者列在下面了:
-
手势分发
具体逻辑可以参考靠=笔者之前写的博客:https://blog.csdn.net/qq_36828822/article/details/103658941 -
如何获取栈顶的activity以及监听activity前后台切换
总所周知:Android的sdk并没有提供相关的api。那么,我们如何设计一个管理任务栈的工具类呢?
package com.example.myapplication.demoimport android.app.Activity
import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import java.lang.ref.WeakReferenceclass ActivityManager private constructor() {private val activityRefs = ArrayList<WeakReference<Activity>>()private val frontbackCallback = ArrayList<FrontBackCallback>()private var activityStartCount =0private var front = truefun init(application: Application){application.registerActivityLifecycleCallbacks()}inner class InnerActivityLifecycleCallbacks:ActivityLifecycleCallbacks{override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {activityRefs.add(WeakReference(activity))}override fun onActivityStarted(activity: Activity) {activityStartCount++//activityStartCount>0 说明应用处于可见状态,也就是应用在前台//!front 之前是不是在后台if(!front && activityStartCount>0){front = trueonFrontBackChanged(front)}}override fun onActivityResumed(activity: Activity) {}override fun onActivityPaused(activity: Activity) {}override fun onActivityStopped(activity: Activity) {activityStartCount--;if(activityStartCount<=0&&front){front = falseonFrontBackChanged(front)}}override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}override fun onActivityDestroyed(activity: Activity) {for (activityRef in activityRefs){if(activityRef!=null && activityRef.get()==activity){activityRefs.remove(activityRef)break}}}}private fun onFrontBackChanged(front: Boolean){for (callback in frontbackCallback){callback.onChanged(front)}}val topActivity:Activity?get() {if (activityRefs.size<=0){return null}else{return activityRefs[activityRefs.size-1].get()}return null}fun addFrontBackCallback(callback: FrontBackCallback){frontbackCallback.add(callback)}fun removeFrontBackCallback(callback: FrontBackCallback){frontbackCallback.remove(callback)}interface FrontBackCallback {fun onChanged(front: Boolean)}
}