目前android 8.0 已经发布,针对android 8.0 的适配已经提上日程。要想使用android 8.0 的新特性,就要把targetsdk提升到26。下面就讲解一下,升级sdk之后,APP需要做的事情。
必须适配的新特性
通知的渠道ID(ChanneId)
Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道。用户界面将通知渠道称之为通知类别。targeSdk升级到26之后,所有的通知的实现都需要提供通知渠道,如果不提供通知渠道的话,所有通知在8.0系统上面都不能正常展示。
下面一张表格展示了是否适配通知渠道对APP的影响:
下图是8.0系统上,APP通知的展示样式:
APP适配渠道通知的实现
通知渠道的创建:
@RequiresApi(Build.VERSION_CODES.O)
public void createChannelId(String channelId){
String group_primary = "group_second";
NotificationChannelGroup ncp1 = new NotificationChannelGroup(group_primary, "通知渠道组2");
getmNotificationManager().createNotificationChannelGroup(ncp1);
NotificationChannel chan = new NotificationChannel(channelId,
"通知渠道2",
NotificationManager.IMPORTANCE_DEFAULT);
chan.setLightColor(Color.GREEN);
chan.setGroup(group_primary);
//锁屏的时候是否展示通知
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
getmNotificationManager().createNotificationChannel(chan);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
使用系统sdk里面的Notification对象创建通知:
public void sendSimpleNotification(Context context) {
int id = ;
String channelId = "channel_first";
//这里必须设置chanenelId,要不然该通知在手机上,不能正常显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannelId(channelId);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId);
builder.setContentTitle("简单的通知的标题")
.setContentText("这是通知内容")
.setLargeIcon(BitmapFactory.decodeResource(
context.getResources(),
R.drawable.ic_launcher))
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.setPriority(NotificationCompat.PRIORITY_HIGH);
mNotificationManager.notify(id, builder.build());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
使用v4-26兼容包里面的NotificationCompat类创建通知:
public void sendSimpleNotificationSecond(Context context) {
int id = ;
String channelId = "channel_second";
Notification.Builder builder = new Notification.Builder(context);
builder.setContentTitle("简单的通知的标题2")
.setContentText("这是通知内容2")
.setLargeIcon(BitmapFactory.decodeResource(
context.getResources(), R.drawable.ic_launcher))
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher);
//这里必须设置chanenelId,要不然该通知在手机上,不能正常显示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannelId(channelId);
builder.setChannelId(channelId);
}
//发送通知
mNotificationManager.notify(id, builder.build());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
通过以上两种方式,可以实现8.0系统通知渠道的适配。
悬浮窗
8.0 API 新增了一种悬浮窗的窗口类型,TYPE_APPLICATION_OVERLAY。
下表展示了是否适配该新窗口类型对不同手机系统的影响:
如果应用使用 SYSTEM_ALERT_WINDOW 权限并且尝试使用以下窗口类型之一来在其他应用和系统窗口上方显示提醒窗口:
TYPE_PHONE
TYPE_PRIORITY_PHONE
TYPE_SYSTEM_ALERT
TYPE_SYSTEM_OVERLAY
TYPE_SYSTEM_ERROR
TYPE_TOAST
这些窗口将始终显示在使用 TYPE_APPLICATION_OVERLAY 窗口类型的窗口下方。
如果该应用适配了8.0,则应用只能使用TYPE_APPLICATION_OVERLAY窗口类型来创建悬浮窗。(其它窗口类型在8.0已经被废弃掉)
提供兼容库支持的新特性
字体资源加载
把字体作为一种资源直接引入到工程里面。新建res/font/文件夹,直接把ttf格式的资源文件放进来,也可以通过xml文件来配置资源,如下图所示:
字体资源impact_font.xml里面的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font android:fontStyle="normal" android:fontWeight="400" android:font="@font/impact"/>
<font android:fontStyle="italic" android:fontWeight="400" android:font="@font/ads_digital"/>
</font-family>
- 1
- 2
- 3
- 4
- 5
在res/values/styles.xml里面,添加自定义字体style,具体内容如下:
<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
<item name="android:fontFamily">@font/impact</item>
</style>
- 1
- 2
- 3
- 4
也可以通过代码动态加载字体资源:
Typeface typeface = null;
//版本,新增api,实现字体资源加载
typeface = getResources().getFont(R.font.ads_digital);
- 1
- 2
- 3
通过V4兼容库实现字体资源的加载,只需要添加如下代码的支持就可以:
res/font/impact_font.xml实现:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<font android:fontStyle="normal" android:fontWeight="400" android:font="@font/impact"
app:fontStyle="normal" app:fontWeight="400" app:font="@font/impact"/>
<font android:fontStyle="italic" android:fontWeight="400" android:font="@font/ads_digital"
app:fontStyle="italic" app:fontWeight="400" app:font="@font/ads_digital" />
</font-family>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这里的app:命名空间,就是提供的低版本的兼容支持。
代码里面动态实现:
Typeface typeface = ResourcesCompat.getFont(this, R.font.ads_digital);
mTextView.setTypeface(typeface);
- 1
- 2
字体自动缩放
Android 8.0 允许根据TextView的内容和边界自动缩放文本内容。针对动态文本内容,这个设计使字体大小的优化在不同的屏幕分辨率上面变得更加容易。兼容库26提供了全部版本的支持。
你能通过framwork或者是支持库来在代码里面或者是xml文件里面配置TextView的autosize属性。
你可以通过如下三种方式配置TextView的autosize。
Default
默认设置:TextView在水平和垂直方向进行缩放。
在代码里面,可以通过setAutoSizeTextTypeWithDefaults(int autoSizeTextType) ,来定义默认的配置,
使用AUTO_SIZE_TEXT_TYPE_NONE来关掉autosize属性,或者使用AUTO_SIZE_TEXT_TYPE_UNIFORM来沿着水平和垂直轴进行缩放。
Granularity
粒度:定义一个textview尺寸的最大值和最小值,以及textview每一步的变化粒度。textview将在最大和最小值之间,按照每步变化的粒度进行缩放。
在代码里面,可以通过 setAutoSizeTextTypeUniformWithConfiguration(int autoSizeMinTextSize, int autoSizeMaxTextSize, int autoSizeStepGranularity, int unit)该方法来设置上面讨论的三个变量。
Preset Sizes
预置字体集:指定所有textview缩放过程中使用的字体大小。
动态代码实现字体自动缩放
使用系统API:
//default
mAutoSizeTV.setAutoSizeTextTypeWithDefaults(TextView.AUTO_SIZE_TEXT_TYPE_UNIFORM);
//Granularity mAutoSizeTV.setAutoSizeTextTypeUniformWithConfiguration(,,,TypedValue.COMPLEX_UNIT_SP);
//Preset sizes
mAutoSizeTV.setAutoSizeTextTypeUniformWithPresetSizes(mTextSizePresets, TypedValue.COMPLEX_UNIT_SP);
- 1
- 2
- 3
- 4
- 5
使用兼容库实现:
/** 兼容库实现 **/
//default
TextViewCompat.setAutoSizeTextTypeWithDefaults(mAutoSizeTV,
TextView.AUTO_SIZE_TEXT_TYPE_UNIFORM);
//Granularity
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(mAutoSizeTV,
,,,TypedValue.COMPLEX_UNIT_SP);
//Preset sizes
TextViewCompat.setAutoSizeTextTypeUniformWithPresetSizes(mAutoSizeTV, mTextSizePresets, TypedValue.COMPLEX_UNIT_SP);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
xml属性实现
使用系统属性实现:
<TextView
android:id="@+id/autosize_args_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:autoSizeTextType="uniform"
android:autoSizeMinTextSize="16sp"
android:autoSizeMaxTextSize="100sp"
android:autoSizeStepGranularity="2sp"
android:autoSizePresetSizes="@arrays/autosize_text_sizes"
/>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
兼容库xml属性实现:
<android.support.v7.widget.AppCompatTextView
android:id="@+id/autosize_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="end"
android:text="@string/auto_size_context"
android:background="@android:color/darker_gray"
app:autoSizeTextType="uniform"
android:layout_margin="20dp"
app:autoSizeMinTextSize="12sp"
app:autoSizeMaxTextSize="100sp"
app:autoSizeStepGranularity="2sp"
app:autoSizePresetSizes="@array/autosize_text_sizes"
/>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
建议适配的新特性
下面讨论的这些新特性只在8.0版本提供支持,低版本不提供支持,实现该新特性的时候需要按照版本提供控制。
自动填充
Android 8.0 通过引入自动填充框架,简化了登录和信用卡表单之类表单的填写工作。在用户选择接受自动填充之后,新老应用都可使用自动填充框架。自动填充框架管理着app和自动填充service的交互。
自动填充的具体实现:
自定义一个继承自AutofillService的service,实现两个方法:
public void onFillRequest(FillRequest rq, CancellationSignal cs, FillCallback callback)
public void onSaveRequest(SaveRequest request, SaveCallback callback)
在onSaveReques里面保存要存储的数据,在onFillRequest里面拿到要填充的数据,并在自动填充组件里面展示要填充的内容。
标准控件view默认支持自动填充功能,比如EditView等。
非标准控件和自定义view可以通过view structure实现。
View.autoFill(AutoFillValue) View.onProvideAutoFillStructure(ViewStructure structure, int flags)
View.getAutoFillType() ViewStructure.addChildCount(int)
View.getAutoFillValue(). ViewStructure.newChild(int, int, int)
备注:如果app要支持自动填充,需要在设置里面打开自动填充的service: Settings > System > Languages & input > Advanced > Input assistance > Autofill service。
画中画模式
7.0加入了画中画模式的支持,但是只是在TV和PAD上面提供支持,8.0开放到了手机上面。
两种进入画中画模式的方式:
属性配置
代码进入 enterPictureInPictureMode()方法
新增方法:
enterPictureInPictureMode(PictureInPictureParams params)
setPictureInPictureParams(PictureInPictureParams params)
onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig)
通过params参数,可以控制画中画窗口的显示大小,比例等。通过newConfig可以知道发生模式切换的时候,当前activity的状态。
注意事项:画中画模式针对的是Activity,同一个应用的不同Activity可以支持画中画,比如离线视频播 放和线上播放可以同时进行。
自适应图标
Android 8.0 引入自适应启动器图标。自适应图标支持视觉效果,可在不同设备型号上显示为各种不同的形状。例如一个启动图标在一个硬件设备上,能以圆形展示;而在另一个硬件设备上面,则以方形展示。
自适应图标的结构及规格如下图所示:
自适应图标的生成方式:
点击Image Asset之后,跳出如下对话框:
在该对话框里面,Asset Type,是启动图标的foreground,可以是本地任意图片,系统提供的默认图标,或者文字。background一般都是纯色,可以选择任何一种颜色作为背景图。
设置好这些内容之后,点击 Next,进入下一个页面,直接点击 Finish,就会在mipmap文件夹下面生成我们需要的自适应图标了。
自适应图标的使用:
<application
…
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
…>
</application>