Android N App分屏模式完全解析(上)

发表于 2016-03-12 |  分类于 技术 |

上手了Android N Preview,第一个不能错过的新特性就是App分屏的支持。Android7.0原生系统就可以支持两个App横屏并排或者竖屏上下摆放了。第二个新特性就是在Android TV上,原生系统也可以支持App实现画中画,用户可以一边看视频一边操作其他的应用。

其实早先在国内部分厂商以及鹅厂的微信App就已经支持在大尺寸手机上进行分屏浏览。也有一些视频播放器,如MoboPlayer就已经实现了按下Home键回到首页时以迷你播放器的形式进行播放。这种体验非常棒,我猜测一般是通过WindowManager来添加悬浮播放器界面的。但是这次是原生系统增加了对这种特性的支持,相信我们会有更多理由为用户的体验做出更多新的尝试。

下面介绍一下我参考multi-window-support对App分屏模式进行的实践。

首先引用一下官方的说法:

如果你使用Android N Preview SDK来构建你的App,你可以给添加App一些分屏浏览的配置。例如设置Activity的最小尺寸,也可以禁止自己的App进入分屏模式,保证你的App只能在全屏模式下展示。

概述

Android N允许用户一次在屏幕中使用两个App,例如将屏幕一分为二,左边浏览网页,右边查看邮件。具体的体验取决于你的设备。

  • 手持设备中,用户可以左右并排/上下摆放两个App来使用。用户还可以左右/上下拖拽中间的那个小白线来改变两个App的尺寸。

  • 在运行Android N的Nexus Player上,App可以实现画中画模式,允许用户使用一个App浏览内容的同时,在另一个App上操作。

  • 大尺寸设备的厂商甚至可以实现自由模式,这样就可以使得用户可以完全自由地改变界面的尺寸。这又是与分屏更为不同一种体验。

用户是如何操作来进入分屏模式的呢:

  1. 点击右下角的方块,进入任务管理器,长按一个App的标题栏,将其拖入屏幕的高亮区域,这个App金进入了分屏模式。然后在任务管理器中选择另一个App,单击它使得这个App也进入分屏模式。
  2. 打开一个App,然后长按右下角的方块,此时已经打开的这个App将进入分屏模式。然后在屏幕上的任务管理器中选择另外一个App,单击它使得这个App也进入分屏模式。
  3. 最新发现:下拉通知栏,长按右上角的设置图标,将开启隐藏设置功能“系统界面调谐器”,进入设置界面,最下方有系统界面调谐器选项,进入后选择“Other”->“启用分屏上滑手势”,就可以从任务管理器上上滑进入分屏模式了。具体操作是当一个App已经处于全屏模式时,用手指从右下角的小方块向上滑动。这个设置将来在正式版可能有变化,所以还是不要太依赖。

用户还可以在这两个App之间拖动数据,例如将一个App的Activity上的文件拖动到另外一个App的Activity中去。具体的实现下面会介绍,谷歌官方也有拖拽相关的教程。

分屏模式的生命周期

首先要说明的一点是,分屏模式没有改变Activity的生命周期。

官方说法是:

在分屏模式下,用户最近操作、激活过的Activity将被系统视为topmost。而其他的Activity都属于paused状态,即使它是一个对用户可见的Activity。但是这些可见的处于paused状态的Activity将比那些不可见的处于paused状态的Activity得到更高优先级的响应。当用户在一个可见的paused状态的Activity上操作时,它将得到恢复resumed状态,并被系统视为topmost。而之前那个那个处于topmpst的Activity将变成paused状态。

怎么理解这段话,看下图:

其实就是说处于分屏模式下的两个Ap各自处于生命周期的什么状态。上图中我打开了两个App,上面的是一个Gmail App,下面这个是一个Demo App(ApkParser先感谢作者的分享~)是个开源应用,能够解析Apk,后面会用到它)。现在这两个App都是进入了分屏模式,我们还可以拖动中间这条白线来调整两个App占用的大小。

我点击了Gmail,浏览了一封邮件,那么此时Gmail就被系统视为topmost状态,它是处于resumed状态的,而下面的ApkPaserDemo虽然对用户可见,但是它仍然是处于paused状态的。接着我点击了系统的back按钮返回,响应的是上面的Gmail(因为它被视为topmost)。然后我又点击了下面的ApkParserDemo,这时它从paused状态变成了resumed状态。而上面的Gmail进入了 paused状态。

注意,这两个App对于用户都是始终可见的,当它们处于paused状态时,也将比那些后台的处于不可见的App得到更高系统优先级。这个优先级怎么体现呢?两个App进入分屏模式后,一定有一个处于resume/topmost状态,假如我一直按back返回,当这个topmost状态App的task返回栈已经为空时,那么系统将把另外一个可见的App恢复为全屏模式,这就是我的理解。

那么这种可见的pause的状态将带来什么影响呢?引用下官方说法是:

在分屏模式中,一个App可以在对用户可见的状态下进入paused状态,所以你的App在处理业务时,应该知道自己什么时候应该真正的暂停。例如一个视频播放器,如果进入了分屏模式,就不应该在onPaused()回调中暂停视频播放,而应该在onStop()回调中才暂停视频,然后在onStart回调中恢复视频播放。关于如果知道自己进入了分屏模式,在Android N的Activity类中,增加了一个void onMultiWindowChanged(boolean inMultiWindow)回调,所以我们可以在这个回调知道App是不是进入了分屏模式。

当App进入分屏模式后,将会触发Activity的onConfigurationChanged(),这与以前我们在处理App从横竖屏切换时的方法一样,不同于的是这里是宽/高有所改变,而横竖屏切换是宽高互换。至于如何处理,可以参考官方文档处理运行时变更。我们最好处理好这种运行时状态的改变,否则我们的Activity将被重新创建,即以新的宽高尺寸重新onCreate()一遍。

注意,如果用户重新调整窗口的大小,系统在必要的时候也可能触发onConfigurationChanged()。当App的窗口被用户拖动,其尺寸改变后界面的还没有绘制完成时,系统将用App主题中的windowBackground属性指定的背景来暂时填充这些区域。

如何设置App的分屏模式

说了一堆分屏的操作方法、生命周期,那么作为开发者,怎样才能让App进入分屏模式呢?有下面这几个属性。

android:resizeableActivity

如果你适配到了Android N,即build.gradle是这样的:

1

2

3

4

5

6

7

8

9

10

11

12

13

android {

compileSdkVersion 'android-N'

buildToolsVersion '24.0.0 rc1'

defaultConfig {

applicationId "com.example.noughtchen.andndemo"

minSdkVersion 'N'

targetSdkVersion 'N'

versionCode 1

versionName "1.0"

}

...

}

那么直接在AndroidManifest.xml中的<application>或者<activity>标签下设置新的属性android:resizeableActivity="true"

设置了这个属性后,你的App/Activity就可以进入分屏模式或者自由模式了。

如果这个属性被设为false,那么你的App将无法进入分屏模式,如果你在打开这个App时,长按右下角的小方块,App将仍然处于全屏模式,系统会弹出Toast提示你无法进入分屏模式。这个属性在你targetAndroid N后,android:resizeableActivity的默认值就是true

注意:假如你没有适配到Android NtargetSDKVersion < Android N),打包App时的compileSDKVersion < Android N,你的App也是可以支持分屏的!!!!原因在于:如果你的App没有 设置 仅允许Activity竖屏/横屏,即没有设置类型android:screenOrientation="XXX"属性时,运行Android N系统的设备还是 可以 将你的App 分屏!! 但是这时候系统是不保证运行时的稳定性的,在进入分屏模式时,系统首先也会弹出Toast来提示你说明这个风险。

所以其实我们在视频里看到那么多系统自带的App都是可以分屏浏览,原因就在于此。这些App其实也并没有全部适配到Android N。我不是骗你,不信你用ApkParser打开前面分屏过Gmail App的xml文件看看!

android:supportsPictureInPicture

这里不多说,Activity标签下,添加android:supportsPictureInPicture="true"即可。

1

2

3

4

5

6

7

8

<activity

android:name=".MainActivity"

android:label="@string/app_name"

android:resizeableActivity="true"

android:supportsPictureInPicture="true"

android:theme="@style/AppTheme.NoActionBar">

...

</activity>

Layout attributes

在Android N中,我们可以向manifest文件中添加layout节点,并设置一些新增加的属性,通过这些属性来设置分屏模式的一些行为,如最小尺寸等。

  • android:defaultWidth
  • android:defaultHeight
  • android:gravity
  • android:minimalSize

我们可以给一个Activity增加一个layout子节点:

1

2

3

4

5

6

7

8

9

10

11

12

13

<activity

android:name=".MainActivity"

android:label="@string/app_name"

android:resizeableActivity="true"

android:supportsPictureInPicture="true"

android:theme="@style/AppTheme.NoActionBar">

...

<layout android:defaultHeight="500dp"

android:defaultWidth="600dp"

android:gravity="top|end"

android:minimalSize="450dp" />

...

</activity>

下一篇Android N App分屏模式完全解析(下)将介绍一下分屏模式下运行的App将有哪些行为回调以及应该怎么处理等。

Android N App分屏模式完全解析(下)

发表于 2016-03-12 |  分类于 技术 |

在上篇中,介绍了什么是App分屏模式,以及如何设置我们的App来进入分屏模式。这次我们看一下,作为开发者,我们应该如何让自己的App进入分屏模式,当App进入分屏模式时,我们注意哪些问题。

简单地说,我认为除了保证分屏时App功能、性能正常以外,我们需要重点学习 如何在分屏模式下打开新的Activity 以及 如何实现跨App/Activity的拖拽功能

用分屏模式运行你的App

Android N中新增了一些方法来支持App的分屏模式。同时在分屏模式下,也禁用了App一些特性。

分屏模式下被禁用的特性

  • 自定义系统UI,例如分屏模式下无法隐藏系统的状态栏。
  • 无法根据屏幕方向来旋转App的界面,也就是说android:screenOrientation属性会被系统忽略。

分屏模式的通知回调、查询App是否处于分屏状态

最新的Android N SDK中,Activity类中增加了下面的方法。

  • inMultiWindow():返回值为boolean,调用此方法可以知道App是否处于分屏模式。
  • inPictureInPicture():返回值为boolean,调用此方法可以知道App是否处于画中画模式。

注意:画中画模式其实是一个特殊的分屏模式,如果mActivity.inPictureInPicture()返回true,那么mActivity.inMultiWindow()一定也是返回true

  • onMultiWindowChanged(boolean inMultiWindow):当Activity进入或者退出分屏模式时,系统会回调这个方法来通知开发者。回调的参数inMultiWindow为boolean类型,如果inMultiWindow为true,表示Activity进入分屏模式;如果inMultiWindow为false,表示退出分屏模式。
  • onPictureInPictureChanged(boolean inPictureInPicture):当Activity进入画中画模式时,系统会回调这个方法。回调参数inPictureInPicturetrue时,表示进入了画中画模式;inPictureInPicturefalse时,表示退出了画中画模式。

Fragment类中,同样增加了以上支持分屏模式的方法,例如Fragment.inMultiWindow()

如何进入画中画模式

调用Activity类的enterPictureInPicture()方法,可以使得我们的App进入画中画模式。如果运行的设备不支持画中画模式,调用这个方法将不会有任何效果。更多画中画模式的资料,请参考picture-in-picture。

在分屏模式下打开新的Activity

当你打开一个新的Activity时,只需要给Intent添加Intent.FLAG_ACTIVITY_LAUNCH_TO_ADJACENT,系统将尝试将它设置为与当前的Activity共同以分屏的模式显示在屏幕上。

注意:这里只是尝试,但这不一定是100%生效的,前一篇博客里也说过,假如新打开的Activity的android:resizeableActivity属性设置为false,就会禁止分屏浏览这个Activity。所以系统只是尝试去以分屏模式打开一个新的Activity,如果条件不满足,将不会生效!此外,我实际用Android N Preview SDK实践的时候发现这个FLAG实际得值是FLAG_ACTIVITY_LAUNCH_ADJACENT,并非是FLAG_ACTIVITY_LAUNCH_TO_ADJACENT

当满足下面的条件,系统会让这两个Activity进入分屏模式:

  • 当前Activity已经进入到分屏模式。
  • 新打开的Activity支持分屏浏览(即android:resizeableActivity=true)。

此时,给新打开的Activity,设置intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK);才会有效果。

建议参考官方的Sample:MultiWindow Playground Sample

那么为何还需要添加FLAG_ACTIVITY_NEW_TASK?看一下官方解释:

注意:在同一个Activity返回栈中,打开一个新的Activity时,这个Activity将会继承上一个Activity所有和分屏模式有关的属性。如果你想要在一个独立的窗口以分屏模式打开一个新的Activity,那么必须新建一个Activity返回栈。

此外,如果你的设备支持自由模式(官方名字叫freeform,暂且就这么翻译它,其实我认为这算也是一种尺寸更自由的分屏模式,上一篇博客里提到过如果设备厂商支持用户可以自由改变Activity的尺寸,那么就相当于支持自由模式,这将比普通的分屏模式更加自由),打开一个Activity时,还可通过ActivityOptions.setLaunchBounds()来指定新的Activity的尺寸和在屏幕中的位置。同样,这个方法也需要你的Activity已经处于分屏模式时,调用它才会生效。

支持拖拽

在上一篇博客里也提到过,现在我们可以实现在两个分屏模式的Activity之间拖动内容了。Android N Preview SDK中,View已经增加支持Activity之间拖动的API。具体的类和方法,可以参考N Preview SDK Reference,主要用到下面几个新的接口:

  • View.startDragAndDrop():View.startDrag()) 的替代方法,需要传递View.DRAG_FLAG_GLOBAL来实现跨Activity拖拽。如果需要将URI权限传递给接收方Activity,还可以根据需要设置View.DRAG_FLAG_GLOBAL_URI_READ或者View.DRAG_FLAG_GLOBAL_URI_WRITE
  • View.cancelDragAndDrop():由拖拽的发起方调用,取消当前进行中的拖拽。
  • View.updateDragShadow():由拖拽的发起方调用,可以给当前进行的拖拽设置阴影。
  • android.view.DropPermissions:接收方App所得到的权限列表。
  • Activity.requestDropPermissions():传递URI权限时,需要调用这个方法。传递的内容存储在DragEvent中的ClipData里。返回值为前面的android.view.DropPermissions

下面是我自己写的一个demo,实现了在分屏模式下,把一个Activity中ImageView中保存的内容到另外一个Activity中进行显示。实际应用中,可以还可以传递图片的url或者Bitmap对象。

上图是一个最基本的例子,实现了把MainActivity中的图片保存的内容,拖拽到SecondActivity中。实现步骤如下:

在MainActivity中,发起拖拽。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

// 1.首先我们在分屏模式下,打开自己App中的SecondActivity

findViewById(R.id.launch_second_activity).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

Intent intent = new Intent(MainActivity.this, SecondActivity.class);

intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(intent);

}

});

// 2.然后我们在MainActivity中发出拖拽事件

imageView = (ImageView) findViewById(R.id.img);

/** 拖拽的发送方Activity和ImageView */

imageView.setTag("I'm a ImageView from MainActivity");

imageView.setOnTouchListener(new View.OnTouchListener() {

public boolean onTouch(View view, MotionEvent motionEvent) {

if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {

/** 构造一个ClipData,将需要传递的数据放在里面 */

ClipData.Item item = new ClipData.Item((CharSequence) view.getTag());

String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};

ClipData dragData = new ClipData(view.getTag().toString(), mimeTypes, item);

View.DragShadowBuilder shadow = new View.DragShadowBuilder(imageView);

/** startDragAndDrop是Android N SDK中的新方法,替代了以前的startDrag,flag需要设置为DRAG_FLAG_GLOBAL */

view.startDragAndDrop(dragData, shadow, null, View.DRAG_FLAG_GLOBAL);

return true;

} else {

return false;

}

}

});

SecondActivity中,接收这个拖拽的结果,在ACTION_DROP事件中,把结果显示出来。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

dropedText = (TextView) findViewById(R.id.text_drop);

dropedText.setOnDragListener(new View.OnDragListener() {

@Override

public boolean onDrag(View view, DragEvent dragEvent) {

switch (dragEvent.getAction()) {

case DragEvent.ACTION_DRAG_STARTED:

Log.d(TAG, "Action is DragEvent.ACTION_DRAG_STARTED");

break;

case DragEvent.ACTION_DRAG_ENTERED:

Log.d(TAG, "Action is DragEvent.ACTION_DRAG_ENTERED");

break;

case DragEvent.ACTION_DRAG_EXITED:

Log.d(TAG, "Action is DragEvent.ACTION_DRAG_EXITED");

break;

case DragEvent.ACTION_DRAG_LOCATION:

break;

case DragEvent.ACTION_DRAG_ENDED:

Log.d(TAG, "Action is DragEvent.ACTION_DRAG_ENDED");

break;

case DragEvent.ACTION_DROP:

Log.d(TAG, "ACTION_DROP event");

/** 3.在这里显示接收到的结果 */

dropedText.setText(dragEvent.getClipData().getItemAt(0).getText());

break;

default:

break;

}

return true;

}

});

这里实现的关键在新增加的startDragAndDrop方法,看下官方的API文档:

清楚地提到了,发出的DragEvent能够被所有可见的View对象接收到,所以在分屏模式下,SecondActivity可以监听View的onDrag事件,于是我们监听它!

接着,我们看下DragEvent.ACTION_DROP事件发生的条件:

当被拖拽的View的阴影进入到接收方View的坐标区域,如果此时用户松手,那么接收方View就可以接收到这个Drop事件。一目了然,我们通过拖拽ImageView到图上的灰色区域,松手,便可以触发DragEvent.ACTION_DROP,把数据传到SecondActivity中了。

其实还有更复杂的一些情况,需要调用requestDropPermissions,后续我再进一步实践一下。

这个demo的地址在这里,先分享出来,后面我再接着完善它。

在分屏模式下测试你的App

无论你是否将自己的App适配到了Android N,或者是支持分屏模式,都应该找个Android N的设备,来测试一下自己的App在分屏模式下会变成什么样。

设置你的测试设备

如果你有一台运行Android N的设备,它是默认支持分屏模式的。

如果你的App不是用Android N Preview SDK打包的

如果你的App是用低于Android N Preview SDK打包的,且你的Activity支持横竖屏切换。那么当用户在尝试使用分屏模式时,系统会强制将你的App进入分屏模式。(我在第一篇博客里提到过这个,Android N Preview的介绍视频中,很多Google家的App都可以进入分屏模式,但是打开它们的xml一看,其实targetSDKVersion = 23

因此,如果你的App/Activity支持横竖屏切换,那么你应该尝试一下让自己的App分屏,看看当系统强制改变你的App尺寸时,用户是否还可以接受这种体验。如果你的App/Activity不支持横竖屏切换,那么你可以确认一下,看看当尝试进入分屏时,你的App是不是仍然能够保持全屏模式。

如果你给App设置了支持分屏模式

如果你使用了Android N Preview SDK来开发自己的App,那么应该按照下面的要点检查一下自己的App。

  • 启动App,长按系统导航栏右下角的小方块(Google官方把这个叫做Overview Button),确保你的App可以进入分屏模式,且尺寸改变后仍然能正常工作。
  • 启动任务管理器(即单击右下角的小方块),然后长按你App的标题栏,将它拖动到屏幕上的高亮区域。确保你的App可以进入分屏模式,且尺寸改变后仍然能正常工作。

这两点在上一篇博客中介绍过,让自己的App进入分屏模式有三种方法。第三种方法,就是在打开自己的App时,用手指从右下角的小方块向上滑动,这样也可以使得正在浏览的App进入分屏模式。这种方法目前属于实验性功能,正式版不一定保留。

  • 当你的App进入分屏后,通过拖动两个App中间的分栏上面的小白线,从而改变App的尺寸,观察App中各个UI元素是否正常显示。
  • 如果你给自己的App/Activity设置了最小尺寸,可以尝试在改变App尺寸时,低于这个最小尺寸,观察App是不是会回到设定好的最小尺寸。
  • 在进行上面几项测试时,请同时验证自己的App功能和性能是否正常,并注意一下自己的App在更新UI时是否花费了太长的时间。

这几项测试,其实主要强调的是,我们的App可以顺利的进入/退出分屏模式,且改变App的尺寸时,UI依然可以也非常顺滑。

这里我想多说一句,如果进入了分屏模式,要注意下App弹出的对话框,因为屏幕被两个App分成两块之后,对话框也是可以弹出两个的。这时对话框上的UI元素可能就会变得比较小了,如果我们的代码是写死的大小,例如对话框是一个WebView,就需要特别注意了,搞不好显示出来就缺了一块了,这里需要我们做好适配。

测试清单

关于功能、性能方面测试,还可以按照下面的操作来进行。

  • 让App进入,再退出分屏模式,确保此时App功能正常。
  • 让App进入分屏模式,激活屏幕上的另外一个App,让自己的App进入可见、paused状态。举了例子来讲,如果你的App是一个视频播放器,那么当用户点击了屏幕上另外一个App时,你的App不应该停止播放视频,即使此时你的Activity/Fragment已经接到了onPaused()回调。
  • 让App进入分屏模式,拖动分栏上的小白线,改变App的尺寸。请在竖屏(两个App一上一下布局)和横屏(两个App一左一右布局)模式下分别进行改变尺寸的操作。确保App不会崩溃,各项功能正常,且UI的刷新没有花费太多时间。
  • 在短时间内、多次、迅速地改变App尺寸,确保App没有崩溃,且没有发生内存泄露。关于内存使用方面的更详细注意事项,请参考Investigating Your RAM Usage。
  • 在不同的窗口设置的情况下,正常使用App,确保App功能正常,文字仍然可读,其他的UI元素也没有变得太小,用户仍然可以舒适地操作App。

这几项测试,其实主要是说当App在分屏模式下运行时,仍然可以保持性能的稳定,不会Crash也不会OOM。

如果你给App设置了禁止分屏模式

如果你给App/Activity设置了android:resizableActivity="false",你应该试试当用户在Android N的设备上,尝试分屏浏览你的App时,它是否仍然能保持全屏模式。

以上就是参考Google最新的multi-window进行的实践,总结下,我认为有3点比较重要:

  1. 如何让自己的App/Activity顺利的进入和退出分屏模式,可以参考处理运行时改变这一章。
  2. 如何在分屏模式下打开新的Activity,可以参考Google官方的MultiWindow Playground Sample。
  3. 如何实现跨App/Activity的拖拽功能,可以参考Drag and Drop这一章。

关于App分屏模式的学习就到这里了,欢迎大家一起交流。我们还发挥更多的想象力,比如是否可以利用跨应用拖拽实现更方便操作,更好的用户体验。

  • 本文作者:unclechen
  • 本文链接: 2016/03/12/Android N App分屏模式完全解析-下篇/
  • 版权声明: 本文采用知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。转载请注明出处!

Android N App分屏模式完全解析相关推荐

  1. Android N App分屏模式完全解析(上)

    上手了Android N Preview,第一个不能错过的新特性就是App分屏的支持.Android7.0原生系统就可以支持两个App横屏并排或者竖屏上下摆放了.第二个新特性就是在Android TV ...

  2. Android N App分屏模式完全解析(下)

    转载地址:http://unclechen.github.io/2016/03/12/Android-N-App%E5%88%86%E5%B1%8F%E6%A8%A1%E5%BC%8F%E5%AE%8 ...

  3. Android 如何判断分屏模式是否开启或者多窗口显示

    Android N 添加了新功能,以支持可在多窗口模式中运行的应用. Activity 类中添加了以下新方法,以支持多窗口显示. Activity.isInMultiWindowMode() 调用该方 ...

  4. 安卓分屏模式的简单适配

    Android N 添加了对同时显示多个应用窗口的支持. 手机上两个应用可以在"分屏"模式中左右并排或上下并排显示. 如何进入分屏模式 打开App,长按底部Overview按键(底 ...

  5. Android之分屏模式解析(上)

    上手了Android N Preview,第一个不能错过的新特性就是App分屏的支持.Android7.0原生系统就可以支持两个App横屏并排或者竖屏上下摆放了.第二个新特性就是在Android TV ...

  6. Android 分屏模式-多窗口支持

    第一篇博客请多多担待,测试一下. 来自于https://developer.android.com/guide/topics/ui/multi-window.html#lifecycle Androi ...

  7. Android实现一键开启自由窗口、分屏、画中画模式——分屏模式

    转载请注明出处:https://blog.csdn.net/sunmmer123 Android实现一键开启自由窗口.分屏.画中画模式系列 一键开启自由窗口模式 一键开启进入分屏模式 一键开启画中画模 ...

  8. android分屏模式_浅谈 Android 7.0 多窗口分屏模式的实现

    从 Android 7.0 开始,Google 推出了一个名为"多窗口模式"的新功能,也就是我们常说的"分屏模式".那么,这个功能有什么用呢?作为开发者,我们又 ...

  9. Android开发笔记(一百五十九)Android7.0的分屏模式

    现在的手机屏幕越来越大,使得在屏幕上同时开多个窗口不再奢侈,因此Android从7.0开始顺势推出了分屏功能,也被称作多窗口模式.比如把竖长的手机屏幕分成上下两个窗口,一边在上面的窗口中观看电影,一边 ...

最新文章

  1. 关于整合spring+mybatis 第三种方式-使用注解
  2. python pyside简单布局_python – pyside显示/隐藏布局
  3. java集合(6):TreeMap源码分析(jdk1.8)
  4. 05-JDBC学习手册:JDBC2.0 新特性之批量处理数据
  5. 计算机信息系统安全保护条例最新,计算机信息系统安全保护条例.doc
  6. HDU - 3804 Query on a tree(主席树维护最大值+离散化)
  7. n个一位数字的数组中选取任意数目的数字,构成的3的最大倍数是多少?
  8. 谈晶体管的饱和状态和饱和压降
  9. AddTransient、AddSingleton、AddScoped 三者都应该在什么场景下使用
  10. 解决Latex报错latex Unknown float option `H‘.
  11. k-means聚类代码实现
  12. 双链表(线性表的链式存储)---C语言版
  13. 超赞!UX写手必备技能
  14. 如何在信用卡反欺诈检测中使用人工智能和机器学习
  15. linux c 调用c程序,Linux C调用C++库(用C封装C++接口)
  16. 统计学和计算机的关系,浅议统计学与其他学科的关系
  17. Ubuntu 下五笔拼音混合输入法
  18. Java语言高级(第三部分)异常多线程 ->(个人学习记录笔记)
  19. Golang学习(十五) 数组排序和二分查找
  20. 鸿蒙操作系统全面屏,首发鸿蒙操作系统!华为P50 Pro稳了:居中开孔全面屏

热门文章

  1. 兼容iOS 10 _升级xcode8_适配(一)
  2. JavaWeb - 软件开发的流程,综合案例
  3. 传奇装备元素属性设置教程
  4. 自定义view实现涂鸦(画板)功能
  5. 软件测试影响与分析,软件测试效率影响因素分析 - Mr.南柯 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  6. trick2-mobilenetv1、mobilenetv2、mobilenetv3替换YOLO主干
  7. 最短路径之弗洛伊德算法(Floyd)——动态规划
  8. 测试功能点----方法
  9. linux可执行文件怎么打开代码,linux可执行文件的加载和运行(转)
  10. 货郎问题的实例 c语言编程,货郎担问题的C语言解法