最近项目中需要实现一个GridView显示6*5=30项,并铺满整个界面,界面中还有自定义ActionBar等其他控件,所以需要获取剩下屏幕的高度。通过百度得知View有一个监听函数,亲测使用有效,特此记录,方便日后查阅。
gv_test.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //给GridView设置Adapter,在adapter的getView中获取GridView的高度,在这个回调之前获取的高度都是0 //处理完后remove掉,至于为什么,后面有解释 gv_test.getViewTreeObserver() .removeOnGlobalLayoutListener(this); } });
通过源码追溯进去,找到ViewTreeObserver这个类,里面有很多interface,都是用来追踪View的各种状态变化的。
找到OnGlobalLayoutListener
/** * Interface definition for a callback to be invoked when the global layout state * or the visibility of views within the view tree changes. */ public interface OnGlobalLayoutListener { /** * Callback method to be invoked when the global layout state or the visibility of views * within the view tree changes */ public void onGlobalLayout(); }
注释的大概意思就是这个回调在布局状态和可见状态发生变化时回调,所以准确的说,这个不是监听View的加载完成,而是监听布局变化的。
我们来测试一下。
public class MainActivity extends AppCompatActivity { TextView tv_test; private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_test = (TextView)findViewById(R.id.tv_test); //app切换到后台,再点开会调用一次,屏幕关闭运行程序会调用两次 tv_test.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Log.e(TAG, "onGlobalLayout: "); } }); } public void test(View v){ //改变可见性,调用一次 // tv_test.setVisibility(View.GONE); //改变文字布局,没有效果 // tv_test.setGravity(Gravity.CENTER); //修改控件大小,调用一次 // LinearLayout.LayoutParams para = (LinearLayout.LayoutParams) tv_test.getLayoutParams(); // para.; // para.weight = 100; // tv_test.setLayoutParams(para); //修改layoutgravity,这个是在LayoutParams中,调用一次 LinearLayout.LayoutParams para = (LinearLayout.LayoutParams) tv_test.getLayoutParams(); para.gravity = Gravity.CENTER_HORIZONTAL; tv_test.setLayoutParams(para); } }
运行程序,得到从android monitor中可以看到,启动后调用了三次onGlobalLayout,很奇怪,为什么是三次?后来有一次屏幕锁了,发现调用了两次。经过测试,app退到后台后重新进入会调用一次,屏幕锁屏后重新打开会调用两次(小米两次,努比亚1次),其中一次猜测是控件的可见性改变了。
通过按键的测试,分别修改控件的可见性和布局,都会调用一次,修改控件内部布局,不会调用,同时修改布局和可见性,只调用一次。
到此三次之谜依旧没有解决,不过,可以肯定的是,这个会重复
调用多次,使用的时候需要注意。解决的办法就是第一次回调后,就把回调remove掉,如:gv_test.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
如有错误,敬请雅正。
茶杯头甜蜜终章dlc 官方手机版v1.0.0.3
下载火柴人传说暗影格斗内置菜单 最新版v3.0.1
下载荒野乱斗测试服 安卓版v61.10.3
下载荒野乱斗彩虹服 安卓版v61.10.3
下载寒霜启示录 安卓版v1.25.10
寒霜启示录是一款生存模拟游戏,不少玩家可能对于末日都有着自己
末日城堡免广告版 安卓最新版v0.7.1
末日城堡免广告版是一款非常好玩的模拟经营类游戏,内部可以不看
甜蜜人生模拟器 最新版v1.4.5
甜蜜人生模拟器是一款非常好玩的模拟恋爱手游,玩家在这里能够对
武器锻造师内置功能菜单 v10.4
武器锻造师内置菜单版是游戏的破解版本,在该版本中为玩家提供了
开放空间overfield 安卓版v1.0.5
开放空间Overfield是一款箱庭养成经营手游,让你在广阔