天天看点

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>
}