RemoteView

常駐通知欄

Notification

//使用Notification欺抗,需要注意在android8.0以上的系統(tǒng)中尸折,需要定義channel,否則無法顯示通知
mBuilder = new NotificationCompat.Builder(this, CHANNEL_TOOLS);
mBuilder.setSmallIcon(R.drawable.ic_notification); // 設(shè)置頂部圖標(biāo)(狀態(tài)欄)

//需要實(shí)現(xiàn)自定義的布局狐援,需要實(shí)現(xiàn)RemoteView俱恶,通過setContent()方法設(shè)置
mBuilder.setContent(remoteViews);

注意點(diǎn):
1. 布局盡量不要限制死高度,在不同的Room下高度過大可能導(dǎo)致View超出通知框范圍
2. 布局背景顏色需要考慮庸毫,盡量使用透明背景色仔拟,同時(shí)布局內(nèi)其他組件也盡量保證在父布局透明時(shí)能夠保持正常視圖
3. 不能保證透明時(shí)較好的效果,則需要統(tǒng)一定死背景顏色飒赃,犧牲一定的room兼容(某些room獲取通知欄顏色不準(zhǔn)利花,會(huì)影響動(dòng)態(tài)設(shè)置背景色)

RemoteView

自定義通知欄中,需要自定義通知欄的視圖時(shí)载佳,需要使用RemoteView定義視圖晋被,代碼示例

//定義RemoteView視圖
RemoteView remoteViews = new RemoteViews(getPackageName(), R.layout.layout_tools_unit_normal_white);

//需要注意,在RemoteView中使用的空間有比較嚴(yán)格的限制刚盈,僅支持有限的幾種控件
//支持控件:

//布局
FrameLayout羡洛,LinearLayout,RelativeLayout,GridLayout

//控件
AnalogClock欲侮,Button崭闲,Chronometer,ImageButton威蕉,ImageView刁俭,ProgressBar,TextView韧涨,ViewFlipper牍戚,ListView,GridView虑粥,StackView如孝,AdapterViewFlipper,ViewStub

注意點(diǎn)
1. 在RemoteView中自定義控件是莫得用的
2. 在RemoteView中沒法直接拿到子View對(duì)象(可以通過方法操控)

RemoteView內(nèi)的控件無法直接通過findViewById來獲取娩贷,所以控制RemoteView中的組件需要通過提供的方法:

例如:
setTextViewText(int viewId, CharSequence text)
setImageViewResourse(int viewId, int resId)
setTextColor(int viewId, int color)

//實(shí)際上這一些方法的實(shí)現(xiàn)機(jī)制是通過反射完成的第晰,所有RemoteView的子組件都通過RemoteView調(diào)用提供的方法來操作

常駐效果

//常駐效果可以通過這行代碼實(shí)現(xiàn)
mBuilder.setOngoing(true);


小部件

小部件是可以單獨(dú)在桌面顯示的內(nèi)容,本質(zhì)上AppWidget實(shí)現(xiàn)的是一個(gè)廣播(BroadCastReceiver)彬祖,生成一個(gè)小部件會(huì)通知我們對(duì)AppWidget的定義茁瘦,然后生成相應(yīng)的布局以及內(nèi)容

定義小部件主體

實(shí)現(xiàn)小部件:繼承AppWidgetProvider

public class MyAgentWidget extends AppWidgetProvider {
    
    /*
     * 核心方法,在更新的時(shí)候調(diào)用
     */
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
        //appWidgetManager:主要用來調(diào)用updataAppWidget(int appwidgetId, RemoteView view)
        //這一方法用來替換刷新appwidgetId對(duì)應(yīng)的小部件的布局顯示储笑,通過RemoteView控制布局內(nèi)容
        //AppWidget裝載內(nèi)容同樣使用的是RemoteView甜熔,所以RemoteView相關(guān)的限制在小部件上也一樣存在

        //appWidgetIds:小部件定義完成以后,用戶可以在桌面生成多個(gè)相同的小部件突倍,所以一個(gè)小部件update()中對(duì)應(yīng)的id會(huì)是數(shù)組類型的數(shù)據(jù)

    }
    
    
    public void onEnable(Context context) {
        //小部件首次添加到桌面時(shí)調(diào)用
    }
    
    public void onDisable(Context context) {
        //小部件移除桌面時(shí)調(diào)用
    }
}

AppWidgetManager的實(shí)例可以通過getInstance()來獲取纺非,在非Widget定義部分的代碼也可以對(duì)小部件的內(nèi)容進(jìn)行修改

//將RemoteView設(shè)置給指定的小部件替換為新的布局樣式
AppWidgetManager.getInstance().updateAppWidget(new ComponentName(Context, 小部件.class), RemoteView)

小部件注冊

小部件本體是一個(gè)BroadCastReceiver,那么對(duì)應(yīng)的在AndroidMainfest里要進(jìn)行注冊

<receiver android:name=".appwidget.MyAppWidget">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        <!-- resource指向的xml文件是對(duì)Widget的一些基本定義 -->
        android:resource="@xml/msg_widget_mine" />
</receiver>

小部件定義

在xml文件夾下赘方,

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialKeyguardLayout="@layout/agent_tool_widget"   <!-- 初始定義鎖屏頁面中布局 -->
    android:initialLayout="@layout/agent_tool_widget"           <!-- 初始定義桌面中布局 -->
    
    android:minHeight="40dp"                                    <!-- 布局最小高度 -->   
    android:minWidth="250dp"                                    <!-- 布局最小寬度 -->
    
    android:previewImage="@mipmap/ic_tools"                     <!-- 在選擇小部件時(shí)展示的圖片 -->
    android:updatePeriodMillis="86400000"                       <!-- 更新時(shí)間毫秒值 -->
    android:widgetCategory="home_screen"></appwidget-provider>  <!-- 相當(dāng)于一個(gè)類別小部件的標(biāo)識(shí) --> 

需要注意的是:通常定義下,桌面中的一格弱左,寬高都是40dp窄陡,但在不同的room下表現(xiàn)都會(huì)有差別(部分系統(tǒng)會(huì)在邊界添加padding),所以整體父布局盡量避免使用padding拆火,保持和桌面應(yīng)用的入口相似跳夭。
只占單格的小部件樣式為了更好的適配,最好只用一張圖片展示



快捷方式

快捷方式的實(shí)現(xiàn)和小部件原理相似们镜,同樣是發(fā)送廣播生成币叹;廣播發(fā)送后由系統(tǒng)接收,之后根據(jù)廣播中包含的內(nèi)容生成快捷方式模狭;

權(quán)限申請

<!-- 快捷方式生成 -->
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<!-- 快捷方式移除 -->
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<!-- 快捷方式讀取信息 -->
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher2.permission.READ_SETTINGS" />
<uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" />

生成快捷方式

ShortcutInfoCompat info = new ShortcutInfoCompat(Context context, String title)
    .setIcon(快捷方式圖標(biāo)(Bitmap,IconCompat,Drawable))
    .setShortLabel(String title)
    .setIntent(點(diǎn)擊快捷方式發(fā)出的Intent)
    .build();
    
//生成制定快捷方式   
PendingIntent shortcutCallbackIntent = PendingIntent.getBroadCast(Context context, int type:快捷方式的唯一標(biāo)識(shí), Intent intent, PendingIntent.FLAG_UPDATE_CURRENT)
ShortcutManagerCompat.requestPinShortcut(Context context, ShortcutInfoCompat info, IntentSender intentSender)    

快捷方式點(diǎn)擊

Intnet intent = new Intent(Context context, Class clazz);
intent.setAction(Intent.ACTION_VIEW);   //必須設(shè)置項(xiàng)颈抚,缺失會(huì)導(dǎo)致崩潰

在首頁點(diǎn)擊快捷方式后將會(huì)直接根據(jù)Intent的內(nèi)容進(jìn)行相應(yīng)的跳轉(zhuǎn),此處的Intent可以設(shè)置FLAG來控制Activity的啟動(dòng)模式


關(guān)于PendingIntent的點(diǎn)擊效果

在RemoteView中要申明點(diǎn)擊事件需要借助PendingIntent來完成嚼鹉,但是有非常重要的一點(diǎn)在于贩汉,PendingIntent中申明的Flag是沒有效果的驱富,也就是說需要跳轉(zhuǎn)到首頁之類的頁面時(shí),在Intent中指定的啟動(dòng)模式是不會(huì)起到作用的匹舞;
如果原先的首頁是standard模式(一般都設(shè)置為這個(gè)模式)褐鸥,那么就會(huì)在跳轉(zhuǎn)是創(chuàng)建一個(gè)新的首頁(emm....),而修改首頁的launchMode也并不可取赐稽,會(huì)影響到切置后臺(tái)再從圖標(biāo)進(jìn)入時(shí)的邏輯叫榕;

對(duì)于RemoteView的點(diǎn)擊目標(biāo)最好不要直接跳轉(zhuǎn)到首頁,如果有必須跳轉(zhuǎn)的情況姊舵,這時(shí)就需要一個(gè)中轉(zhuǎn)頁面來輔助跳轉(zhuǎn)晰绎,因?yàn)镻endingIntent無法傳遞launchMode,所以需要先跳轉(zhuǎn)至中轉(zhuǎn)頁蠢莺,再由中轉(zhuǎn)頁通過Intent來定義launchMode寒匙,通過這種方式可以做到正確的跳轉(zhuǎn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市躏将,隨后出現(xiàn)的幾起案子锄弱,更是在濱河造成了極大的恐慌,老刑警劉巖祸憋,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件会宪,死亡現(xiàn)場離奇詭異,居然都是意外死亡蚯窥,警方通過查閱死者的電腦和手機(jī)掸鹅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拦赠,“玉大人巍沙,你說我怎么就攤上這事『墒螅” “怎么了句携?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長允乐。 經(jīng)常有香客問我矮嫉,道長,這世上最難降的妖魔是什么牍疏? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任蠢笋,我火速辦了婚禮,結(jié)果婚禮上鳞陨,老公的妹妹穿的比我還像新娘昨寞。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布编矾。 她就那樣靜靜地躺著熟史,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窄俏。 梳的紋絲不亂的頭發(fā)上蹂匹,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音凹蜈,去河邊找鬼限寞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛仰坦,可吹牛的內(nèi)容都是我干的履植。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼悄晃,長吁一口氣:“原來是場噩夢啊……” “哼玫霎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起妈橄,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤庶近,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后眷蚓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鼻种,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年沙热,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叉钥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡篙贸,死狀恐怖投队,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情爵川,我是刑警寧澤敷鸦,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站雁芙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏钞螟。R本人自食惡果不足惜兔甘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鳞滨。 院中可真熱鬧洞焙,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至唁情,卻和暖如春疑苔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背甸鸟。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來泰國打工惦费, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抢韭。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓薪贫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親刻恭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瞧省,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容