快速上手Widget设计?这章帮你你搞定!
一、概念:
Widget是什么?
Widget就是可以放在桌面上的组件。
Widget特征
身材微 、 形式多 、 功能巨 、 姿容丽 、 个性化 、 易制作
Widget应用
Widget应用在Android手机上得到了广泛的应用。由于其方便小巧,所以得到了很多的应用,像天气,微博,信息,歌曲,时间等等。
Widget使用
绘制Widget的布局:和其他应用类的APP不同的是,Widget支持的控件比较少:除了基本的布局之外(相对、线性、帧、网格),ImageView、Image...
二、Widget设计步骤:
1.需要修改三个XML,一个class:
- 第一个xml是布局XML文件(如:main.xml),是这个widget的。一般来说如果用这个部件显示时间,那就只在这个布局XML中声明一个textview就OK了。
- 第二个xml是widget_provider.xml,主要是用于声明一个appwidget的。其中,Layout就是指定上面那个main.xml。
- 第三个xml是AndroidManifest.xml,注册broadcastReceiver信息。
- 最后那个class用于做一些业务逻辑操作。让其继承类AppWidgetProvider。AppWidgetProvider中有许多方法,一般情况下我们只是覆写onUpdate(Context,AppWidgetManager,int[])方法。
2.代码案例
****1.app\src\main\res\xml\下新建一个appwidget-provider文件,文件名:test_widget_info**
内容如下:**
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/test_widget" //widget 布局文件
android:minWidth="300dp" //widget最小宽度
android:minHeight="200dp" // widget最小高度
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000" // 最短刷新时间间隔
android:previewImage="@drawable/widget_preview" //widget选择列表里的预览图
android:widgetCategory="home_screen"></appwidget-provider> // 类型 主屏,还有种是基于锁屏的
2.androidmanifest文件里注册下widget,可以看出widget是继承自receiver的
public class AppWidgetProvider extends BroadcastReceiver
我们的widget继承AppWidgetProvider
AndroidManifest配置文件里加上
<receiver android:name=".widget.appwidget.TestWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> // 这个action类似于广播的action
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/test_widget_info" /> //指向我们刚配置的文件
</receiver>
3.写一个widget继承AppWidgetProvider
public class TestWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
//更新widget会调用这个方法
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
//删除widget时调用这个方法
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
//widget被第一次添加时会调用这个方法,这个方法应该只会有系统来调用
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
// 最后一个widget被删除时会调用这个方法
}
}
简单看下AppWidgetProvider里onReceive方法
public void onReceive(Context context, Intent intent) {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
} else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
this.onDeleted(context, new int[] { appWidgetId });
}
} else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
&& extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
appWidgetId, widgetExtras);
}
} else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
this.onDisabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] oldIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
int[] newIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (oldIds != null && oldIds.length > 0) {
this.onRestored(context, oldIds, newIds);
this.onUpdate(context, AppWidgetManager.getInstance(context), newIds);
}
}
}
}
4.具体UI相关的
widget的view还比较特殊,叫RemoteViews
跟我们常见的view集成viewgroup不同,它继承的是Parcelable, Filter
自然不能用findviewbyid之类的,代码里动态设置布局什么的都不太好搞了
但官方也给我们开放了一些接口用来设置控件。
基础的 设置textview,imageview
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.test_widget); //test_widget.xml 就是widgetview的布局文件
views.setTextViewText(R.id.tv, "helloworld");
views.setImageViewResource(R.id.iv,R.drawable/test_iv);
设置点击事件
Intent intent = new Intent(context, NewActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, UUID.randomUUID().hashCode(),
upload, PendingIntent.FLAG_UPDATE_CURRENT);//widget如果有多个点击事件需要这么写,否则点击事件只响应最先设置的那个
views.setOnClickPendingIntent(R.id.btn, pIntent);
结语:
上述就是一些关于Widget的概述与操作步骤;自己从事Android开发5年有余了;整理了一些Android开发技术进阶资料:想要进阶自己、拿高薪?
https://docs.qq.com/doc/DUkNRVFFzTG96VHNi领取《腾讯T12专家Android技术进阶手册丶面试题纲丶核心笔记资料》
想有收获必须努力,知识在于积累。不进则退。