Android N实现分屏

开篇语:

Android原生一直是信仰,之前用的moto Xt1060更新到了5.1就不支持更新了,就一直在纠结换Google Nexus系列的对比一下,4和5太老旧,5x和6p太贵,那么只有选择6了。下决心买了一台,到手之后迫不及待的升了N。升级之后确实流畅了很多,分屏是一个不错的功能,国内的厂商有的早已经有分屏,于是就想研究研究原生N是怎么实现分屏的,看了官方的文档以及搜索来的资料,写了一个小的Demo,所以写这篇博客记录一下。


以下来自官方的文档说明:


Android N 添加了对同时显示多个应用窗口的支持。 在手持设备上,两个应用可以在“分屏”模式中左右并排或上下并排显示。 在电视设备上,应用可以使用“画中画”模式,在用户与另一个应用交互的同时继续播放视频。

如果您使用 N Preview SDK 构建应用,则可以配置应用处理多窗口显示的方法。 例如,您可以指定 Activity 的最小允许尺寸。 您还可以禁用应用的多窗口显示,确保系统仅以全屏模式显示应用。


就是说Android N支持多窗口,你可以在浏览网页的时候看视频或者聊微信。(前提是应用支持分屏)




用户可以通过以下方式切换到多窗口模式:


  • 若用户打开Overview并长按 Activity 标题,则可以拖动该 Activity 至屏幕突出显示的区域,使 Activity 进入多窗口模式。
  • 若用户长按 Overview 按钮,设备上的当前 Activity 将进入多窗口模式,同时将打开 Overview 屏幕,用户可在该屏幕中选择要共享屏幕的另一个 Activity。
多窗口的生命周期:

多窗口不会改变Activity的生命周期
在多窗口模式中,在指定时间只有最近与用户交互过的 Activity 为活动状态。 该 Activity 将被视为顶级 Activity。  所有其他 Activity 虽然可见,但均处于暂停状态。 但是,这些已暂停但可见的 Activity 在系统中享有比不可见 Activity 更高的优先级。 如果用户与其中一个暂停的 Activity 交互,该 Activity 将恢复,而之前的顶级 Activity 将暂停。
注:在多窗口模式中,用户仍可以看到处于暂停状态的应用。 应用在暂停状态下可能仍需要继续其操作。 例如,处于暂停模式但可见的视频播放应用应继续显示视频。 因此,我们建议播放视频的 Activity 不要暂停其 onPause()处理程序中的视频。 应暂停 onStop()中的视频,并恢复 onStart()中的视频播放。

如处理运行时变更中所述,用户使用多窗口模式显示应用时,系统将通知 Activity 发生配置变更。 这也会发生在当用户调整应用大小,或将应用恢复到全屏模式时。 该变更与系统通知应用设备从纵向模式切换到横向模式时的 Activity 生命周期影响基本相同,但设备不仅仅是交换尺寸,而是会变更尺寸。 如处理运行时变更中所述,您的 Activity 可以自行处理配置变更,或允许系统销毁 Activity,并以新的尺寸重新创建该 Activity。

如果用户调整窗口大小,并在任意维度放大窗口尺寸,系统将调整 Activity 以匹配用户操作,同时根据需要发布运行时变更。 如果应用在新公开区域的绘制滞后,系统将使用windowBacground 属性或默认 windowBackgroundFallback 样式属性指定的颜色暂时填充该区域。

如何进行分屏:

新建应用使用 N Preview SDK 构建
你的build.gradle文件如下:
compileSdkVersion 24
    buildToolsVersion "24.0.0 rc4"

    defaultConfig {
        applicationId "com.zwb.fenping"
        minSdkVersion 24
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
针对多窗口进行配置:

android:resizeableActivity

在清单的 <activity> 或 <application> 节点中设置该属性,启用或禁用多窗口显示:

android:resizeableActivity=["true" | "false"]


如果该属性设置为 true,Activity 将能以分屏和自由形状模式启动。 如果此属性设置为 false,Activity 将不支持多窗口模式。 如果该值为 false,且用户尝试在多窗口模式下启动 Activity,该 Activity 将全屏显示。

如果您的应用面向 Android N,但未对该属性指定值,则该属性的值默认设为 true。

android:supportsPictureInPicture

在清单文件的 <activity> 节点中设置该属性,指明 Activity 是否支持画中画显示。 如果 android:resizeableActivity 为 false,将忽略该属性。

android:supportsPictureInPicture=["true" | "false"]

在清单文件的 <activity>节点中设置该属性,指明 Activity 是否支持画中画显示。如果 android:resizeableActivity为 false,将忽略该属性。

当然你还可以指定在自由形状模式时 Activity 的默认大小、位置和最小尺寸:

<activity android:name=".MainActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end"
          android:minimalSize="450dp" />
</activity>
对于 Android N,<layout>清单文件元素支持以下几种属性,这些属性影响 Activity 在多窗口模式中的行为:
  1. android:defaultWidth 以自由形状模式启动时 Activity 的默认宽度。
  2. android:defaultHeight 以自由形状模式启动时 Activity 的默认高度。
  3. android:gravity 以自由形状模式启动时 Activity 的初始位置。
  4. android:minimalSize 分屏和自由形状模式中 Activity 的最小高度和最小宽度。 如果用户在分屏模式中移动分界线,使 Activity 尺寸低于指定的最小值,系统会将 Activity 裁剪为用户请求的尺寸。

在多窗口模式中运行应用

Android N 添加了新功能,以支持可在多窗口模式中运行的应用。

多窗口模式中被禁用的功能

在设备处于多窗口模式中时,某些功能会被禁用或忽略,因为这些功能对与其他 Activity 或应用共享设备屏幕的 Activity 而言没有意义。 此类功能包括:

  • 某些系统UI自定义选项将被禁用;例如,在非全屏模式中,应用无法隐藏状态栏。
  • 系统将忽略对android:screenOrientation属性所作的更改。

Activity类中添加了以下新方法,以支持多窗口显示。

  1. Activity.inMultiWindow() 调用该方法以确认 Activity 是否处于多窗口模式。
  2. Activity.inPictureInPicture() 调用该方法以确认 Activity 是否处于画中画模式。:画中画模式是多窗口模式的特例。 如果 myActivity.inPictureInPicture()返回 true,则 myActivity.inMultiWindow()也返回 true。
  3. Activity.onMultiWindowChanged() Activity 进入或退出多窗口模式时系统将调用此方法。 在 Activity 进入多窗口模式时,系统向该方法传递 true 值,在退出多窗口模式时,则传递 false 值。
  4. Activity.onPictureInPictureChanged() Activity 进入或退出画中画模式时系统将调用此方法。 在 Activity 进入画中画模式时,系统向该方法传递 true 值,在退出画中画模式时,则传递 false 值。

每个方法还有 Fragment版本,例如 Fragment.inMultiWindow()。

进入画中画模式:

如需在画中画模式中启动 Activity,请调用新方法 Activity.enterPictureInPictureMode()

在多窗口模式中启动新 Activity

在启动新 Activity 时,用户可以提示系统如果可能,应将新 Activity 显示在当前 Activity 旁边。 要执行此操作,可使用标志Intent.FLAG_ACTIVITY_LAUNCH_TO_ADJACENT。 传递此标志将请求以下行为:

  • 如果设备处于分屏模式,系统会尝试在启动系统的 Activity 旁创建新 Activity,这样两个 Activity 将共享屏幕。 系统并不一定能实现此操作,但如果可以,系统将使两个 Activity 处于相邻的位置。
  • 如果设备不处于分屏模式,则该标志无效。

如果设备处于自由形状模式,则在启动新 Activity 时,用户可通过调用 ActivityOptions.setLaunchBounds() 指定新 Activity 的尺寸和屏幕位置。 如果设备不处于多窗口模式,则该方法无效。

注:如果您在任务栈中启动 Activity,该 Activity 将替换屏幕上的 Activity,并继承其所有的多窗口属性。 如果要在多窗口模式中以单独的窗口启动新 Activity,则必须在新的任务栈中启动此 Activity。

支持拖放:

用户可以在两个 Activity 共享屏幕的同时在这两个 Activity 之间拖放。因此,如果您的应用目前不支持拖放功能,您可以在其中添加此功能。

  1. android.view.DropPermissions令牌对象,负责指定对接收拖放数据的应用授予的权限。
  2. View.startDragAndDrop() View.startDrag()的新别名。要启用跨 Activity 拖放,请传递新标志 View.DRAG_FLAG_GLOBAL。如需对接收拖放数据的 Activity 授予 URI 权限,可根据情况传递新标志View.DRAG_FLAG_GLOBAL_URI_READ或 View.DRAG_FLAG_GLOBAL_URI_WRITE。
  3. View.cancelDragAndDrop() 取消当前正在进行的拖动操作。只能由发起拖动操作的应用调用。
  4. View.updateDragShadow() 替换当前正在进行的拖动操作的拖动阴影。只能由发起拖动操作的应用调用。
  5. Activity.requestDropPermissions() 请求使用 DragEvent中包含的 ClipData传递的内容 URI 的权限。

看完了官方的文档,于是乎就开始着手搞一把试试效果。

新建项目,Sdk的版本是N
布局资源文件activity_main.xml就只有一个按钮上面显示我是一个分屏的应用。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.zwb.fenping.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="我是一个分屏的应用" />
</RelativeLayout>

下面就是在AndroidManifest中设置相关的属性实现分屏。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zwb.fenping">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
           <strong><span style="color:#ff0000;"> android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
            android:resizeableActivity="true"</span></strong>>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

运行一下,的运行效果:

参考文档:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在 Android实现分屏,可以使用 Fragment 来实现。具体实现步骤如下: 1. 在 AndroidManifest.xml 文件中声明支持分屏功能: ```xml <activity android:name=".MainActivity" android:resizeableActivity="true" android:supportsPictureInPicture="true"> <meta-data android:name="android.max_aspect" android:value="2.1" /> </activity> ``` 2. 在布局文件中创建两个 Fragment: ```xml <fragment android:id="@+id/fragment1" android:name="com.example.fragmentdemo.Fragment1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> <fragment android:id="@+id/fragment2" android:name="com.example.fragmentdemo.Fragment2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> ``` 3. 在 MainActivity 中实现分屏功能: ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (isInMultiWindowMode()) { Fragment1 fragment1 = new Fragment1(); Fragment2 fragment2 = new Fragment2(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.fragment1, fragment1); transaction.add(R.id.fragment2, fragment2); transaction.commit(); } } } ``` 在 isInMultiWindowMode() 方法中判断是否处于分屏模式,如果是,则创建两个 Fragment 并添加到布局中。 4. 运行程序并进入分屏模式,即可看到两个 Fragment 并排显示在屏幕上。 注意:对于 Android 7.0 及以上版本,需要在 AndroidManifest.xml 文件中声明 android:resizeableActivity="true" 和 android:supportsPictureInPicture="true" 来支持分屏功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值