android横屏

文章介绍了Android项目中进行平板适配的一些关键方法,包括基于屏幕尺寸和分辨率判断是否为平板设备,检测是否启用平行视界模式,以及如何处理分屏和旋转屏幕的情况。此外,还提到了防止Activity因屏幕旋转重建的配置和针对手机和平板不同设备设置封面的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近负责了项目中平板适配工作,总结了一些相关方法记录下来

方法介绍

1、判断是否是平板设备

官方给出的方法如下

   public static boolean isTabletDevice(Context context) {
        return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >=
                Configuration.SCREENLAYOUT_SIZE_LARGE;
    }

但是这个方法在极少机型上也有不准确的时候,另一种方法是根据屏幕的尺寸判断

public static boolean isPadDevice(Context context) {
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    DisplayMetrics dm = new DisplayMetrics();
    display.getMetrics(dm);
    double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
    double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
    double screenInches = Math.sqrt(x + y); // 屏幕尺寸
    return screenInches >= 7.0;
}

但是随着手机屏幕越来越大,这个方法也可能不准确了。

2、判断是否在平行视界(平行窗口)

有时候我们需要判断当前的横竖屏状态来决定使用哪种布局,但是有些平板设备横屏使用时,是平行视界模式,这是应该使用的是竖屏布局,所以也要判断一下是否在平行世界模式

public static boolean isMagicWindow(Context context){
    String confString = context.getResources().getConfiguration().toString();
    return confString.contains("hwMultiwindow-magic") || confString.contains("miui-magic-windows") || confString.contains("hw-magic-windows");
}

上面仅仅是华为和小米平板,为了普遍性,可以改成

    public static boolean isMagicWindow(Context context){
        String confString = context.getResources().getConfiguration().toString();
//        return confString.contains("hwMultiwindow-magic") || confString.contains("miui-magic-windows") || confString.contains("hw-magic-windows");
        // 上面的两种方法只能判断小米和华为,下面这种写法应该更普遍一些
        return confString.contains("magic-window") || confString.contains("window-magic");
    }

小米平行世界提供了关闭的方法,让程序默认横屏进入

        <!-- 小米不进入平行视窗模式-->
        <meta-data
            android:name="LandscapeForPad"
            android:value="true" />

3、获取窗口和设备大小

只有一个应用显示时,应用所在的窗口大小和屏幕大小是一样的,但是在分屏或者平行视界模式下,应用窗口的大小和设备的大小不一致。

  • 获取窗口大小

    int widthPixels = context.getApplicationContext()
            .getResources().getDisplayMetrics().widthPixels;
    int heightPixels = context.getApplicationContext()
            .getResources().getDisplayMetrics().heightPixels;
    
  • 获取设备大小

    平行视界种该方法不准确,得到的还是应用窗口大小

    /**
     * 获取设备的物理宽
     * @param context
     * @return
     */
    public static int getPhysicsWidth(Context context){
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display;
        if (Build.VERSION.SDK_INT >= 30){
            display = context.getDisplay();
        } else {
            display = windowManager.getDefaultDisplay();
        }
        DisplayMetrics mMetrics = new DisplayMetrics();
        display.getRealMetrics(mMetrics);
        return  mMetrics.widthPixels;
    }
    

4、是否处于分屏模式

在activity中,重写onMultiWindowModeChanged方法,在进入分屏模式时会被回调到

@Override
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
    super.onMultiWindowModeChanged(isInMultiWindowMode);
}

或者还可以直接通过mActivity.isInMultiWindowMode()方法判断是否处于多窗口模式。

5、旋转时不重建activity

很多时候旋转屏幕我们都不希望重建activity,通过在AndroidManifest.xml中可以配置为

android:name=".module.course.flutter.FCourseDetailActivity"
android:configChanges="keyboardHidden|orientation|screenSize|screenLayout"

同样重写onConfigChanges方法可以接收到回调。

7、手机禁止旋转,pad允许旋转

很多页面禁止手机旋转,但是允许pad旋转到横屏展示更多的内容,要让我们的应用满足这种要求,就必须去先掉原先的横竖屏配置

<activity
    android:name=".commonview.activity.TransparentActivity"
    android:screenOrientation="portrait"
    android:theme="@style/transparent_activity" />

因为在manifest中,我们是没法判断当前是pad还是手机的,也不能说创建两个配置文件分别给平板和手机使用。

  • 方法一

    Activity提供了一个方法setRequestedOrientation()来控制屏幕旋转,如果当前是竖屏,我们再次调用setRequestedOrientation()旋转到竖屏的话,屏幕不会变化,也不会闪屏,但是相当于告诉了系统,我这个界面要始终保持竖屏,以后就忽略重力感应吧,只有调用setRequestedOrientation()才会发生旋转。于是我们可以进入界面时判断一下如果是手机的话就将其旋转到竖屏。

  • 方法二

​ 配置screenOrientation所有可选参数如下

		unspecified,默认值,由系统决定,不同手机可能不一致
		landscape,强制横屏显示
    portrait,强制竖屏显
    behind,与前一个activity方向相同
    sensor,根据物理传感器方向转动,用户90度、180度、270度旋转手机方向,activity都更着变化
    sensorLandscape,横屏旋转,一般横屏游戏会这样设置
    sensorPortrait,竖屏旋转
    nosensor,旋转设备时候,界面不会跟着旋转。初始化界面方向由系统控制
    user,用户当前设置的方向

​ 这里也可以设置为behind来保持和上一个activity相同,从而禁止旋转,但是这种方式可能达不到我们的需要。

实例分享

1、手机和平板如何设置不同的封面

app启动页如果不设置背景,会有一个白屏的效果,通常我们会在启动页的主题中配置上的背景图片,例如

<style name="AppWindowBackgroudSplash" parent="android:Theme.NoTitleBar">
    <item name="android:windowBackground">@drawable/starting_bkg</item>
    <item name="android:windowAnimationStyle">@style/noAnimation</item>
    <item name="android:windowFullscreen">true</item>
</style>

通过设置windowBackground属性可以设置背景图片,文字等显示效果,这里我们使用一个layer-list来实现文字和图片重叠显示

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white"/>
        </shape>
    </item>

    <item
        android:bottom="128dp">
        <bitmap android:src="@drawable/launch_bg" />
    </item>

    <item
        android:gravity="top"
        android:top="123dp">
        <bitmap
            android:gravity="center_horizontal|top"
            android:src="@drawable/launch_title" />
    </item>

    <item
        android:bottom="44dp"
        android:gravity="bottom">
        <bitmap
            android:gravity="center_horizontal|bottom"
            android:src="@drawable/launch_bottom" />
    </item>
</layer-list>

问题来了,横屏进入时,封面会被拉伸,如何为横屏单独配置一张背景图呢?很简单,创建一个drawable-land目录,创建一个同名文件starting_bkg.xml,里面配置横屏图片,从而启动的时候会根据横竖屏自动选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值