Android之widget
ONE Goal,ONE Passion !
widget---桌面小控件.大多使用与天气应用等控件(墨迹天气).一般用来实时更新service中的获取的最新数据.
widget使用步骤:
- 1, 写一个广播接收者继承AppWidgetProvider(AppWidgetProvider继承自BroadcastReceiver).
- 2,在清单文件中配置这个广播接收者
- 3,重写onEnabled等方法.
- 4,[一般开启服务,在服务中去处理widget的点击事件]
第一步: 创建widget控件
public class MyWidgetReceiver extends AppWidgetProvider {
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
/**
* 当创建时调用
*/
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
@Override
/**
* 当销毁时调用
*/
public void onEnabled(Context context) {
super.onEnabled(context);
Intent service = new Intent(context, WidgetService.class);
context.startService(service);
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
Intent service = new Intent(context, WidgetService.class);
context.stopService(service);
}
}
第二步: 在清单文件中配置
a.清单中配置
// name : 我们创建的广播接收者的名称
<receiver android:name="com.example.widgetdemo.MyWidgetReceiver" >
// intent-filter : 要接收的广播的频道(固定写法)
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
// resource: widget显示的布局资源
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_provider" />
</receiver>
当我们配置后系统会帮助我们创建widget.
b.在res下创建xml文件夹,在xml文件中创建一个widget_provider.xml文件
initialLayout: widget显示布局
minHeight : 显示的最小高度
minWidth : 显示的最小宽度
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/process_widget"
android:minHeight="72.0dip"
android:minWidth="294.0dip"
android:updatePeriodMillis="0" />
现在widget已经可以显示了.只是这个widget仅仅能显示布局.
第三步: 在服务中为widget添加可点击的操作:
public class WidgetService extends Service {
AppWidgetManager am;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
updateWidget();
return super.onStartCommand(intent, flags, startId);
}
public void updateWidget() {
// 获取AppWidgetManager
am = AppWidgetManager.getInstance(this);
/**
* 更新widget调用方法 ComponentName---四大组件的封装类
* am.updateAppWidget(ComponentName provider, RemoteViews views)
*/
/**
* RemoteViews --- 远程view A class that describes a view hierarchy that
* can be displayed in another process. The hierarchy is inflated from a
* layout resource file, and this class provides some basic operations
* for modifying the content of the inflated hierarchy.
*/
// 将四大组件封装成了ComponentName
ComponentName provider = new ComponentName(getApplicationContext(),
MyWidgetReceiver.class);
// 获得远程view
RemoteViews views = new RemoteViews(getPackageName(),
R.layout.process_widget);
// 为远程view设置内容
views.setTextViewText(R.id.process_count, "5 个应用");
views.setTextViewText(R.id.process_memory, "200M");
// 延迟意图--发送广播
Intent intent = new Intent();
intent.setAction("widget.clear.notify");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), 88, intent,
PendingIntent.FLAG_ONE_SHOT);
/*
* 延迟意图开启activity
* Intent intent = new Intent(getApplicationContext(),
* MainActivity.class); PendingIntent pendingIntent =
* PendingIntent.getActivity( getApplicationContext(), 80, intent,
* PendingIntent.FLAG_ONE_SHOT);
* PendingIntent.FLAG_ONE_SHOT----这个值能能开启一次
*/
// 为远程view设置点击后的意图
/**
* setOnClickPendingIntent(int viewId, PendingIntent pendingIntent)
* viewId---响应点击事件的控件id pendingIntent--- 要执行的PendingIntent
*/
views.setOnClickPendingIntent(R.id.btn_clear, pendingIntent);
am.updateAppWidget(provider, views);
}
}
好了.widget已经可以操作了.
注: 如果是开启activity.注意将要启动的activity的启动方式更改为
android:launchMode="singleTask"
以防点击widget后进入activity后需要点击2此返回键才能退出.