国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

widget開發之helloworld(基礎篇)

2019-11-09 14:36:44
字體:
來源:轉載
供稿:網友

widget開發之helloworld

由于工作需求,上周剛開始接觸widget。經過一周的開發和了解,對widget的一些基礎點做一下整理。

什么是widget:

widget也叫小部件,在launcher中點擊menu鍵,會出現小部件選項,進入后會顯示所以手機上已經安裝的widget。長按或者單擊(launcher決定)后,可添加到手機桌面上。

從功能上,widget功能比較簡單,專注于某一件事情。比如時鐘、天氣、音樂等等。

widget也可以和響應的普通應用聯系起來,點擊之后進入應用界面。這時候widget更像是一個應用的快捷入口。

下面來具體介紹一下widget的開發步驟:

1、注冊widget處理器

在manifest中,注冊一個receiver,用來接收系統發來的widget的廣播。

<!-- receiver的 android:name指向的是widget的請求處理器或者說請求接收者 -->		<receiver			android:label="@string/app_name"			android:name="com.cooee.phenix.widget.WidgetPRovider">			<intent-filter>			    <!-- 點擊事件對應的廣播字符串 -->                <action android:name="com.cooee.phenix.widget.click.clock_layout"/>                <action android:name="com.cooee.phenix.widget.click.weather_layout"/>                <action android:name="com.cooee.phenix.widget.click.date_layout"/>				<!-- widget默認的事件action -->				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />			</intent-filter>			<!-- widget元數據,name是寫死的,resource指的是widget的配置文件 -->			<meta-data				android:name="android.appwidget.provider"				android:resource="@layout/widgetinfo" />		</receiver>

2、WidgetProvider處理器

WidgetProvider是我們自己創建的類,繼承AppWidgetProvider,AppWidgetProvider extends BroadcastReceiver,用來處理widget的各種請求。

widget中的事件都是通過廣播進行傳遞的:

widget的添加、刪除、更新等操作,都會收到相應的廣播。在AppWidgetProvider的public void onReceive(方法中可以看到

AppWidgetProvider類中:

public void onUpdate:widget更新時回調

public void onDeleted:一個widget從桌面刪除時回調

public void onEnabled:第一個widget被放到桌面時回調

public void onDisabled:最后一個widget從桌面刪除時回調

public void onReceive:用來接收廣播,處理widget的消息。

如果我們需要在這些時刻做一下自己的邏輯處理,WidgetProvider可以重寫這幾個方法。

3、widgetinfo和widget布局

widget的界面和widget寬高等信息在哪里定義呢?

在上面代碼的注釋中可以看到,widgetinfo是關聯在receiver里的mete-data中。(把這部分代碼單獨貼出來方便大家看)

<!-- widget元數據,name是寫死的,resource指的是widget的配置文件 -->			<meta-data				android:name="android.appwidget.provider"				android:resource="@layout/widgetinfo" />那么,widgetinfo中究竟定義了什么東西,我們來具體看一下這個xml文件:

<?xml version="1.0" encoding="utf-8"?><!-- appwidget-provider Widget的配置文件 --><!-- android:minWidth 最小寬度 --><!-- android:minHeight 最小高度 --><!-- android:updatePeriodMillis 組件更新頻率(毫秒) --><!-- android:initialLayout 用來關聯widget的布局文件 --><!-- android:configure Widget設置用Activity ??? --><appwidget-provider	android:layout_width="wrap_content"	android:layout_height="wrap_content"	xmlns:android="http://schemas.android.com/apk/res/android"	android:initialLayout="@layout/widget_layout"	android:minWidth="@dimen/widget_width"	android:minHeight="@dimen/widget_height"	android:updatePeriodMillis="86400000" />關于android:configure屬性,這次并沒有用到,具體我也不懂這是干嘛用的。在這里,我最關心的是布局文件,畢竟,它是要顯示的東西。

由于布局文件比較長這里就不貼代碼了。(布局文件就像我們app里的一樣布局就ok啦)

4、widget點擊事件(action的意義)

說道點擊事件,我們得先來說一下widget中的view。

remoteview:

上面講到widget關聯布局的方式,和我們寫app有點不同。那么 我們想對顯示的布局做一些動態的改變(改變文字或者背景之類),該怎么辦呢?

按照寫app的思考方式,我們需要獲取到一個view,它里面填充的整個布局,然后最好有個findviewbyid獲取到布局里每一個控件,然后,嘎嘎嘎,我們就能為所欲為了。

設置點擊監聽、改變文字、設置圖片背景神馬的還不是灑灑水???!!!

想法,是很美好的。但是百度了一番之后我才發現并沒有想象中辣么簡單。。。。。。

下面來介紹widget如何獲取我們想要的view:

rv = new RemoteViews( mContext.getPackageName() , R.layout.widget_layout );得到view之后,悲劇的事情發生了,它居然沒有findviewbyid方法!!!!!也就是說我得不到布局里每一個具體的view

一番網上搜索之后,設置點擊事件監聽和改變文字之類的找到了對應的方法,不過,動畫好像就與我們絕緣了。。。

點擊事件:

//日期Intent intentDateClick = new Intent( WidgetProvider.CLICK_DATE_LAYOUT );//intent的action用來區分具體點擊的是哪一個viewPendingIntent pendingDateIntent = PendingIntent.getBroadcast( mContext , 0 , intentDateClick , 0 );rv.setOnClickPendingIntent( R.id.date_textview , pendingDateIntent );//設置點擊事件監聽//時鐘if( showClockVeiw ){	Intent intentClockClick = new Intent( WidgetProvider.CLICK_CLOCK_LAYOUT );	PendingIntent pendingClockIntent = PendingIntent.getBroadcast( mContext , 0 , intentClockClick , 0 );	rv.setOnClickPendingIntent( R.id.clock_layout , pendingClockIntent );}visibility = showClockVeiw ? View.VISIBLE : View.GONE;rv.setViewVisibility( R.id.clock_layout , visibility );//天氣if( showWeatherVeiw ){	Intent intentWeatherClick = new Intent( WidgetProvider.CLICK_WEATHER_LAYOUT );	PendingIntent pendingWeatherIntent = PendingIntent.getBroadcast( mContext , 0 , intentWeatherClick , 0 );	rv.setOnClickPendingIntent( R.id.city_textview , pendingWeatherIntent );	rv.setOnClickPendingIntent( R.id.weather_city , pendingWeatherIntent );	rv.setOnClickPendingIntent( R.id.temperature_current , pendingWeatherIntent );	rv.setOnClickPendingIntent( R.id.temperature_range , pendingWeatherIntent );}visibility = showWeatherVeiw ? View.VISIBLE : View.GONE;setWeatherVisibility( visibility );上面代碼可以看到。我們的關鍵點在于:

rv.setOnClickPendingIntent( R.id.date_textview , pendingDateIntent );就是這個方法設置了點擊事件的監聽。第一個參數是rv這個view中,布局里面的某一個view的id,第二個參數是PendingIntent是具體的廣播意圖。里面包含了如果點擊這個view,WidgetProvider將受到的廣播。

widget中,點擊事件是通過廣播傳遞的。intent的action就是我們在manifest里看到的三個action。所以我們用三個action來區分三種view的點擊事件。

下面貼出來三個action的變量值,方便大家邏輯跟蹤。這三個值都是WidgetProvider中的:

public static final String CLICK_CLOCK_LAYOUT = "com.cooee.phenix.widget.click.clock_layout";public static final String CLICK_WEATHER_LAYOUT = "com.cooee.phenix.widget.click.weather_layout";public static final String CLICK_DATE_LAYOUT = "com.cooee.phenix.widget.click.date_layout";	

通過點擊事件的啟發,我發現雖然我們不能具體拿到布局里的每一個view,但是我們可以通過remoteview來改變它。

比如這句:rv.setViewVisibility( R.id.clock_layout , visibility );//設置view是否可見,我似乎找到了某種規律。至此,我們已經設置好了widget中view的點擊事件。

當我們點擊view時,WidgetProvider就會收到廣播,我們通過區分intent的action來處理不同view的點擊:

public void onClick(		String action ){	//點擊時鐘布局	if( action.equals( WidgetProvider.CLICK_CLOCK_LAYOUT ) )	{		ClockCalendarManager.getInstance( mContext ).onClickClock();	}	//點擊日期	else if( action.equals( WidgetProvider.CLICK_DATE_LAYOUT ) )	{		ClockCalendarManager.getInstance( mContext ).onclickDate();	}	//點擊天氣	else if( action.equals( WidgetProvider.CLICK_WEATHER_LAYOUT ) )	{		WeatherManager.getInstance( mContext ).onClick();	}	else	{		Log.d( TAG , "其他" );	}}

5、widget修改后更新顯示

以上我們講了widget的manifest注冊、widgetinfo、widget布局、如何獲取view、如何設置點擊事件、如何響應點擊事件。

下面我們來看看如何更新一個view顯示的內容、如何更新我們的widget。

以我們的時鐘為例,當我們需要更新view時:

TwinkleClockwidgetManager instance = TwinkleClockwidgetManager.getInstance( mContext );RemoteViews rv = instance.getRv();if( instance.showClockVeiw ){	rv.setImageViewResource( R.id.clock_minute_tens , timeNumbers[mCurrentMinute / 10] );	rv.setImageViewResource( R.id.clock_minute_ones , timeNumbers[mCurrentMinute % 10] );}哈哈,果然跟想的一樣,都是通過remoteview來設置,第一個參數是要改變的view的id,第二個是要設置的值。

改變完view之后,我們需要更新一下widget,就能改變桌面上widget的顯示了:

//更新插件AppWidgetManager appWidgetManger = AppWidgetManager.getInstance( mContext );//第一步,通過context拿到appwidgetManagerint[] appIds = appWidgetManger.getAppWidgetIds( new ComponentName( mContext , WidgetProvider.class ) );//第二步,通過widgetManager和包類名拿到widgetIdappWidgetManger.updateAppWidget( appIds , rv );//第三步,更新widget的顯示

總結:

以上就是這一周多時間對widget的了解,貼一張widget的圖展示小成果:嘿嘿嘿

其中還有些坑無法解惑:

1、widget如何做動畫?(好像在哪看到過別的桌面的widget,日歷時鐘,過一天,日歷更新時是帶一個旋轉的動畫的)

2、widget如何可拉伸?(launcher上顯示widget時,有的widget長按松手之后可以改變widget在桌面上顯示的大小,目前還不確定這部分是桌面做?還是需要widget這邊協助。。。)

以上僅代表個人觀點,如有理解不到位的地方,還請指正。歡迎留言,歡迎私信。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 图们市| 长治市| 达尔| 临沧市| 鄂托克前旗| 白河县| 灵川县| 塘沽区| 黑河市| 清河县| 巴彦县| 鸡东县| 台东市| 容城县| 石泉县| 焦作市| 高邮市| 边坝县| 石楼县| 应城市| 西藏| 英山县| 留坝县| 文登市| 孝感市| 巴东县| 桃源县| 吴桥县| 天镇县| 景谷| 云林县| 道孚县| 沙洋县| 三江| 灌阳县| 会理县| 镇沅| 万山特区| 报价| 当雄县| 昂仁县|