Android监听view尺寸变化

本文介绍了一种解决横屏切换时启动动画的问题方法。通过监听全局布局变化,确保视图宽度非零后再启动动画,避免了因尺寸未更新导致的动画异常。

问题引出: 切换到横屏时有一个view要启动动画,但是获取的宽度为零

解决方案:

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                float mLayerWidth = (float) view.getWidth();
                float mTextWidth = (float) view.getWidth();
                if (mLayerWidth != 0 && mTextWidth != 0) {
                    startAnimation(mLayerWidth,mTextWidth);
                }
            }
 });
### 如何在 Android监听屏幕尺寸变化 #### 方法一:通过 `android:configChanges` 属性实现 为了防止 Activity 在屏幕旋转或其他配置更改时被销毁并重新创建,可以在 `AndroidManifest.xml` 文件中为对应的 Activity 添加 `android:configChanges` 属性。这可以阻止默认的行为,并允许手动处理这些事件。 以下是常见的配置项及其作用: - **orientation**: 横竖屏切换。 - **screenSize**: 当前窗口的可用空间发生改变(适用于 API Level 13 及以上版本)。 - **keyboardHidden**: 虚拟键盘隐藏或显示的状态变化。 具体配置如下所示[^1][^3]: ```xml <activity android:name=".MainActivity" android:configChanges="orientation|keyboardHidden|screenSize"> </activity> ``` 当设置了上述属性后,可以通过重写 `onConfigurationChanged(Configuration newConfig)` 方法来响应屏幕尺寸变化。例如: ```java @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { // 处理横屏逻辑 } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ // 处理竖屏逻辑 } if (newConfig.screenWidthDp != previousScreenWidthDp || newConfig.screenHeightDp != previousScreenHeightDp) { // 屏幕分辨率发生了变化 updateUIForNewDimensions(); } } ``` --- #### 方法二:使用 `ComponentCallbacks2` 接口 对于更复杂的场景,比如折叠屏设备上的展开和收起操作,推荐使用 `ComponentCallbacks2` 接口中的 `onConfigurationChanged()` 方法。这种方式不仅能够检测屏幕方向的变化,还可以感知实际物理屏幕尺寸变化[^2]: 下面是一个完整的例子: ```java public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 注册回调 getApplicationContext().registerComponentCallbacks(this); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { // 横屏模式下的特殊处理 } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { // 竖屏模式下的特殊处理 } if (newConfig.smallestScreenWidthDp > thresholdValue) { // 如果最小宽度超过某个阈值,则认为是大屏模式 } } @Override protected void onDestroy() { super.onDestroy(); // 解除回调注册 getApplicationContext().unregisterComponentCallbacks(this); } } ``` 注意:这里的 `thresholdValue` 是开发者自定义的一个数值,用来判断是否进入某种特定的大屏模式。 --- #### 方法三:动态监控视图布局调整 如果需要实时监测 UI 的可见区域大小变化(如虚拟导航栏的显示/隐藏),可以利用 `ViewTreeObserver.OnGlobalLayoutListener` 来监听全局布局的变化[^4]。这种方法特别适合于那些依赖精确像素计算的应用程序。 示例代码如下: ```java private View rootView; private int initialHeight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rootView = findViewById(android.R.id.content); rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> { Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); int screenHeight = rootView.getRootView().getHeight(); int keypadHeight = screenHeight - r.bottom; if (keypadHeight > screenHeight * 0.15 && initialHeight == 0) { // 键盘弹出 initialHeight = screenHeight - keypadHeight; } else if (initialHeight > 0 && Math.abs(initialHeight - screenHeight) >= 100) { // 导航栏状态发生变化 Log.d("DEBUG", "Navigation bar state changed"); } }); } ``` --- #### 总结 三种方法各有优劣: - 使用 `android:configChanges` 和 `onConfigurationChanged()` 更加简单直接,适合大多数常规需求。 - 对于复杂场景(如可折叠设备),建议采用 `ComponentCallbacks2` 提供更强的灵活性。 - 动态监控视图布局更适合针对某些特殊情况(如软键盘遮挡输入框)进行优化。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值