目前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 = 1000;
String channelId = "channel_first";
//這裏必須設置chanenelId,要不然該通知在8.0手機上,不能正常顯示
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 = 1002;
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,要不然該通知在8.0手機上,不能正常顯示
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;
//26版本,新增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(10,100,2,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,
10,100,2,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>