天天看點

android 中widget元件

<span style="font-family: Arial, Helvetica, sans-serif;">Widget (微件、小元件)</span>
           
1)寫布局檔案對于widget的布局檔案有限制!不是所有的元件都能夠使用的。 容器類視圖目前隻支援四種:LinearLayout,RelativeLayout,FrameLayout,GridLayout容器類目前支援的視圖元件:AnalogClock 模拟時鐘ChronoMeter 電子時鐘、計時器ButtonImageButtonTextViewImageViewViewFlipper等(随着SDK版本的疊代,可支援的視圖數量在增加)不能用的:自定義視圖一概不能用(View) 上述可用視圖的子類一概不能用 (比如EditText)2)寫一個描述檔案,用來描述widget的一些屬性
寫在res/xml檔案下      
有四個屬性必須聲明:minWidht/minHeight:小元件拖動到螢幕上之後,系統會根據你指定的這兩個值估算會占用多少格。螢幕上會被系統劃分為4*4個格子,每個格子具體尺寸,根據螢幕尺寸和密度的不同會有所差異。Google早期給出了一個minWidth/minHeight的經驗計算公式:70*n-30 dp在高密度大尺寸螢幕下還有一個經驗公式:74*n-2
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="250dp"
    android:minHeight="110dp"
    android:updatePeriodMillis="1800000"
    android:initialLayout="@layout/widget_layout"
    >

</appwidget-provider>
           
updatePeriodMillis 系統會按照該時間間隔,通過發送系統廣播的方式,來更新Widget的顯示内容。發送的系統廣播的action是android.appwidget.action.APPWIDGET_UPDATE,widget一旦受到該廣播,會調用onUpdate方法。
updatePeriodMillis指定的時間間隔不得低于30分鐘所對應的毫秒值。低于該值,則設定無效,系統依然會每隔半小時發送一次廣播。


3)寫一個類,繼承自AppWidgetProvider類      
XML檔案 
<TextView 
        android:id="@+id/tv_widget_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:padding="8dp"
        android:text="XXX"
        />
    <TextView 
        android:id="@+id/tv_widget_number2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:padding="8dp"
        android:text="XXX"
        />

    <Button
        android:id="@+id/btn_widget_getnumber"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="擷取随機數字" />
           
5個方法:      
例:點選button擷取随機數和每隔一段時間自動生成随機數
onReceive:用來收廣播
	       
@Override
	public void onReceive(Context context, Intent intent) {
		super.onReceive(context, intent);
		String action=intent.getAction();
		if("com.tarena.UPDATE_WIDGET".equals(action)){
			int number=intent.getIntExtra("number", -1);
			
			RemoteViews views=new RemoteViews(context.getPackageName(), R.layout.widget_layout);
			views.setTextViewText(R.id.tv_widget_number2, number+"");
			AppWidgetManager manger=AppWidgetManager.getInstance(context);
			manger.updateAppWidget(new ComponentName(context, MyWidget.class), views);
		}
	}
           
onEnable:目前僅當,第一個Widget被拖到桌面上的時候,該方法會被調用。在第一個widget被拖到到桌面的時候,系統會發送系統廣播,onReceive方法收到該廣播後會調用onEnable方法。
      
onUpdate:當Widget被拖動桌面上,該方法都會被調用一次。widget被拖到到桌面的時候,
系統會發送系統廣播,onReceive方法收到該廣播後會調用onUpdate方法。然後,每隔updatePerioidMillis時間,系統還會發送一次系統廣播,該方法依然會被調用一次。
       
@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		
		//要先建立一個RemoteView的對象
		RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
		//為按鈕綁定監聽器
		//點選按鈕重新整理TextView中的内容
		Intent intent = new Intent(context,MyService.class);//用來啟動service的intent
		PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
		remoteViews.setOnClickPendingIntent(R.id.btn_widget_getnumber, pendingIntent);
		//利用AppWidgetManager把RemoteViews“送出”給安卓,安卓在Widget時
		//會按照你為RemoteViews指定的方式來進行
		ComponentName provider = new ComponentName(context, MyWidget.class);
		appWidgetManager.updateAppWidget(provider, remoteViews);
	}
           
onDeleted:當一個Widget從桌面上被删除的時候,該Widget的onDeleted方法會被調用。      
onDisable:當且僅當最後一個Widget從桌面上删除的時候,該Widget除了onDeleted方法會被調用之外,它的onDisable方法也會被調用



4)在AndroidManifest檔案中,“注冊”第3步寫好的類
       
<meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/mywidget" />
           
5)建立<span style="font-family: Arial, Helvetica, sans-serif;">Service</span>
           
public class MyService extends Service {


<span style="white-space:pre">	</span>Thread thread;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>public MyService() {
<span style="white-space:pre">	</span>}


<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void onCreate() {
<span style="white-space:pre">		</span>super.onCreate();
<span style="white-space:pre">		</span>thread=new Thread(){
<span style="white-space:pre">			</span>public void run() {
<span style="white-space:pre">				</span>try{
<span style="white-space:pre">					</span>while (!Thread.interrupted()) {
<span style="white-space:pre">						</span>Intent intent=new Intent("com.tarena.UPDATE_WIDGET");
<span style="white-space:pre">						</span>intent.putExtra("number", new Random().nextInt(100));
<span style="white-space:pre">						</span>sendBroadcast(intent);
<span style="white-space:pre">						</span>Thread.sleep(2000);
<span style="white-space:pre">					</span>}
<span style="white-space:pre">				</span>}catch (Exception e) {
<span style="white-space:pre">				</span>}
<span style="white-space:pre">			</span>};
<span style="white-space:pre">		</span>};
<span style="white-space:pre">		</span>thread.start();
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void onDestroy() {
<span style="white-space:pre">		</span>super.onDestroy();
<span style="white-space:pre">		</span>
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public int onStartCommand(Intent intent, int flags, int startId) {
<span style="white-space:pre">		</span>//重新整理Widget中TextView内容的代碼
<span style="white-space:pre">		</span>//要先建立一個RemoteView的對象
<span style="white-space:pre">		</span>RemoteViews views = new RemoteViews(getPackageName(), R.layout.widget_layout);
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>//為按鈕綁定監聽器
<span style="white-space:pre">		</span>//點選按鈕重新整理TextView中的内容
<span style="white-space:pre">		</span>views.setTextViewText(R.id.tv_widget_number, new Random().nextInt(1000)+"");
<span style="white-space:pre">		</span>views.setTextColor(R.id.tv_widget_number, Color.rgb(new Random().nextInt(256), new Random().nextInt(256),new Random().nextInt(256)));
<span style="white-space:pre">		</span>//利用AppWidgetManager把RemoteView "送出"給安卓,安卓早Widget的時候
<span style="white-space:pre">		</span>//會按照你為RemoteView指定的方式來進行
<span style="white-space:pre">		</span>AppWidgetManager manager = AppWidgetManager.getInstance(this);
<span style="white-space:pre">		</span>manager.updateAppWidget(new ComponentName(this, MyWidget.class), views);
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>return super.onStartCommand(intent, flags, startId);
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public IBinder onBind(Intent intent) {
<span style="white-space:pre">		</span>throw new UnsupportedOperationException("Not yet implemented");
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
}