Skip to content

横竖屏切换 布局异常~问题所在及解决方案 (升级版) #418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Fly-Felix opened this issue Aug 4, 2022 · 13 comments
Closed

Comments

@Fly-Felix
Copy link

Fly-Felix commented Aug 4, 2022

当刚开始在使用这个适配方案时,运行起来看起来非常好,基本上不用修改什么就能达到适配效果,但在一次app前台后台横屏竖屏切换操作后,布局和文字会变的特别大或特别小,显然是有问题的,得治

在发生问题之后我先是百度一下,解决了,运行时横竖屏幕方向不一致时适配问题,再来在官方这里寻找旋转后适配失效问题,幸运的是我找到了:#388 ,根据大佬的描述意思就是
ScreenUtils.getScreenSize()这个方法在旋转屏幕抓取到的size还旋转之前的size,加了500ms延迟之后获取size就正常了,使用了大佬提供的解决方案之后好多了,不过有时还是会出现问题,于是开始调试发现大佬的代码好像有一点点小问题,以下是问题代码:

`

                //获取当前屏幕的宽高
                int[] screenSize = ScreenUtils.getScreenSize(sAppContext);

                if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                    //竖屏
                    AutoSizeConfig.getInstance().setScreenWidth(screenSize[0]);
                    AutoSizeConfig.getInstance().setScreenHeight(screenSize[1]);

                } else {
                    //横屏下需要 转换 宽高的值
                    AutoSizeConfig.getInstance().setScreenWidth(screenSize[1]);
                    AutoSizeConfig.getInstance().setScreenHeight(screenSize[0]);

                }

`
在延迟获取之后既然screenSize都正常了为什么还要给setScreenWidth和setScreenHeight取反操作,screenSize[0]代表宽度screenSize[1]代表高度,在screenSize正常时:
横屏:screenSize[0]=1024,screenSize[1]=600
竖屏:screenSize[0]=600,screenSize[1]=1024

所以在加了500ms延迟获取screenSize之后完全不需要故意取反设置宽度和高度,在按照自己的想法修改一番之后最后的问题也解决了

经虚拟机和真机横竖屏旋转和切换第三方来回测试均无发现适配失效问题,最后我给出以下代码:

`

class App : Application() {

private var mHandler = Handler(Looper.getMainLooper())

private var mCurrentActivity: Activity? = null

private var mAutoSizeRunnable: Runnable? = null

override fun onCreate() {
    super.onCreate()

    //屏幕适配监听器
    AutoSizeConfig.getInstance().setOnAdaptListener(object : onAdaptListener {

        override fun onAdaptBefore(target: Any?, activity: Activity?) {
            if (activity == null) {
                return
            }

            //使用以下代码, 可以解决横竖屏切换时的屏幕适配问题
            //首先设置最新的屏幕尺寸,ScreenUtils.getScreenSize(activity) 的参数一定要不要传 Application !!!
            AutoSizeConfig.getInstance().screenWidth =
                ScreenUtils.getScreenSize(activity)[0];
            AutoSizeConfig.getInstance().screenHeight =
                ScreenUtils.getScreenSize(activity)[1];
            //根据屏幕方向,设置设计尺寸
            if (activity.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                //设置横屏设计尺寸
                AutoSizeConfig.getInstance()
                    .setDesignWidthInDp(1024)
                    .setDesignHeightInDp(600);
            } else {
                //设置竖屏设计尺寸
                AutoSizeConfig.getInstance()
                    .setDesignWidthInDp(600)
                    .setDesignHeightInDp(1024)

            }
        }

        override fun onAdaptAfter(target: Any?, activity: Activity?) {
        }
    });

    registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
            mCurrentActivity = activity
        }

        override fun onActivityStarted(activity: Activity) {
            mCurrentActivity = activity
        }

        override fun onActivityResumed(activity: Activity) {
            mCurrentActivity = activity
        }

        override fun onActivityPaused(activity: Activity) {
            mCurrentActivity = activity
        }

        override fun onActivityStopped(activity: Activity) {
            mCurrentActivity = activity
        }

        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
            mCurrentActivity = activity
        }

        override fun onActivityDestroyed(activity: Activity) {
            mCurrentActivity = null
        }
    })

    registerComponentCallbacks(object : ComponentCallbacks {
        override fun onConfigurationChanged(newConfig: Configuration) {
            if (mCurrentActivity == null) {
                return
            }
            if (mAutoSizeRunnable != null) {
                mHandler.removeCallbacks(mAutoSizeRunnable!!)
            }
            mAutoSizeRunnable = Runnable {
                //获取当前屏幕的宽高
                val screenSize = ScreenUtils.getScreenSize(mCurrentActivity);
                //横屏
                AutoSizeConfig.getInstance().screenWidth = screenSize[0]
                AutoSizeConfig.getInstance().screenHeight = screenSize[1]

                if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    //设置横屏设计尺寸
                    AutoSizeConfig.getInstance()
                        .setDesignWidthInDp(1024)
                        .setDesignHeightInDp(600)
                } else {
                    //设置竖屏设计尺寸
                    AutoSizeConfig.getInstance()
                        .setDesignWidthInDp(600)
                        .setDesignHeightInDp(1024)
                }
                //重新设置 dpi
                if (mCurrentActivity != null) {
                    AutoSize.autoConvertDensityOfGlobal(mCurrentActivity)
                }
            }
            mHandler.postDelayed(mAutoSizeRunnable!!, 500)
        }

        override fun onLowMemory() {

        }
    })
}
}

`

@GHMike
Copy link

GHMike commented Aug 5, 2022

鸿蒙系统的好像还是有问题

@Fly-Felix
Copy link
Author

目前我还没在鸿蒙系统上尝试过,你可以详细的说一下你遇到的问题吗?我可以按照你说的去试试

@Fly-Felix
Copy link
Author

鸿蒙系统的好像还是有问题

我刚刚用HUAWEI Mate 30 鸿蒙2.0.0.236版本切换横屏竖屏旋转测试没有发生问题

@Fly-Felix Fly-Felix closed this as not planned Won't fix, can't repro, duplicate, stale Aug 5, 2022
@Fly-Felix
Copy link
Author

AndroidManifest.xml配置如下,你可以按照你的尺寸配置,再加上我上面给的Application代码,其它地方不要再多写什么,应该没什么问题,Application里面的代码一点都不能少,获取activity的方式可以修改,其它代码最好不要修改
<meta-data android:name="design_width_in_dp" android:value="1024" /> <meta-data android:name="design_height_in_dp" android:value="600" />

@GHMike
Copy link

GHMike commented Aug 5, 2022

我的横竖屏切换是竖屏页面进入横屏页面,横屏页面有很多个列表,然后来回进入退出横屏页面,横屏页面就会变形

@Fly-Felix
Copy link
Author

Fly-Felix commented Aug 5, 2022 via email

@ysj40540
Copy link

ysj40540 commented Oct 7, 2022

我也遇到一个列表页面变形 适配失败, 步骤是华为小米部分手机息屏 然后页面Onresume刷新列表就变形了,你怎么解决的呢

@wuyihao99
Copy link

我这里使用直接崩溃了,从activity返回的时候先执行的onActivityResumed,然后才是onActivityDestroyed,这样ScreenUtils.getScreenSize(mCurrentActivity)就是null的

@Fly-Felix
Copy link
Author

我这里使用直接崩溃了,从activity返回的时候先执行的onActivityResumed,然后才是onActivityDestroyed,这样ScreenUtils.getScreenSize(mCurrentActivity)就是null的

在Runnable的地方增加一个空指针判断
mAutoSizeRunnable = Runnable {
if (mCurrentActivity != null) {
//......
}
}

@wuyihao99
Copy link

我这里使用直接崩溃了,从activity返回的时候先执行的onActivityResumed,然后才是onActivityDestroyed,这样ScreenUtils.getScreenSize(mCurrentActivity)就是null的

在Runnable的地方增加一个空指针判断 mAutoSizeRunnable = Runnable { if (mCurrentActivity != null) { //...... } }

我认为只需要在onActivityResumed 赋值就行,activity回退过程 onPause(B)->onRestart(A)->onStart(A)->onResume(A)->oStop(B)

@Fly-Felix
Copy link
Author

我这里使用直接崩溃了,从activity返回的时候先执行的onActivityResumed,然后才是onActivityDestroyed,这样ScreenUtils.getScreenSize(mCurrentActivity)就是null的

在Runnable的地方增加一个空指针判断 mAutoSizeRunnable = Runnable { if (mCurrentActivity != null) { //...... } }

我认为只需要在onActivityResumed 赋值就行,activity回退过程 onPause(B)->onRestart(A)->onStart(A)->onResume(A)->oStop(B)

当时好像还遇到了一些其他问题,具体是什么问题我忘记了,可以试试看

@TonyChou
Copy link

初始化的时候使用ScreenSizeFactory 实时获取屏幕宽高不就得了,然后在onConfigurationChanged里面重新autoConvertDensityOfCustomAdapt一下就能解决横竖屏字体混乱的问题
AutoSizeConfig.getInstance().setScreenSizeFactory(new AutoSizeConfig.IScreenSizeFactory() {

                @Override
                public int screenWidth(int i) {
        
                }

                @Override
                public int screenHeight(int i) {
                  
                }
            })

override fun onConfigurationChanged(newConfig: Configuration) {
    AutoSize.autoConvertDensityOfCustomAdapt(this, this)
    super.onConfigurationChanged(newConfig)
    LogUtils.i(TAG, "onConfigurationChanged:$localClassName")
}

@ysj40540
Copy link

初始化的时候使用ScreenSizeFactory 实时获取屏幕宽高不就得了,然后在onConfigurationChanged里面重新autoConvertDensityOfCustomAdapt一下就能解决横竖屏字体混乱的问题 AutoSizeConfig.getInstance().setScreenSizeFactory(new AutoSizeConfig.IScreenSizeFactory() {

                @Override
                public int screenWidth(int i) {
        
                }

                @Override
                public int screenHeight(int i) {
                  
                }
            })

override fun onConfigurationChanged(newConfig: Configuration) {
    AutoSize.autoConvertDensityOfCustomAdapt(this, this)
    super.onConfigurationChanged(newConfig)
    LogUtils.i(TAG, "onConfigurationChanged:$localClassName")
}

mark

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants