博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
给你的app添加桌面widget
阅读量:7119 次
发布时间:2019-06-28

本文共 5128 字,大约阅读时间需要 17 分钟。

首先,什么是桌面widget,桌面widget是一种桌面插件,如下图: 

 

这种类型的控件叫做widget,一般长按桌面会弹出一个界面让你选择控件,选择完了拖到桌面就能使用了。

下面我们为这个app来添加一个widget,先看一下效果吧。 

 

 

然后点击这个桌面widget,让他跳转到我们的app里面

 

怎么样,效果还不错吧?

下面重点讲一下实现widget的主要步骤: 1. 在AndroidManifest.xml里面定义声明 AppWidgetProvider 2. 初始化AppWidget的xml文件(信息) 3. 实现AppWidget的布局 4. 继承 AppWidgetProvider 类,实现具体的 Widget 业务逻辑。

 

1、在AndroidManifest.xml里面定义声明 AppWidgetProvider

<intent-filter>中必须要包含 APPWIDGET_UPDATE 这个 <action>,所有 Widget 的 broadcast 都是通过这个 filter 来接收的。<meta-data> 声明了 Widget的xml 信息,用的是 xml 目录下的 widget_info.xml。

 

2、widget_info.xml

记住,这个文件不是widget的布局,而是widget的信息,描述了widget的宽高、刷新时间等等信息。 

minWidth & minHeight:定义了 Widget 的最小宽高,当 minWidth 和 minHeight 不是桌面 cell 的整数倍时,Widget 的宽高会被阔至与其最接近的 cells 大小。Google 官方给出了一个大致估算 minWidth & minHeight 的公式,根据 Widget 所占的 cell 数量来计算宽高:70 × n − 30,n 是所占的 cell 数量。

updatePeriodMillis: 定义了 Widget 的刷新频率,也就是 App Widget Framework 多久请求一次 AppWidgetProvider 的 onUpdate() 回调函数。但是,系统默认最小更新时间是30分钟,如果这里定义的时间小于30分钟,那么刷新时间还是30分钟。

previewImage:widget的预览图,就是我们widget列表里面那些预览图

initialLayout: 这里定义的才是widget的布局

resizeMode:Widget 在水平和垂直方向是否可以调整大小,值可以为:horizontal(水平方向可以调整大小),vertical(垂直方向可以调整大小),none(不可以调整大小),也可以 horizontal|vertical 组合表示水平和垂直方向均可以调整大小。

widgetCategory:表示 Widget 可以显示的位置,包括 home_screen(桌面),keyboard(锁屏),keyboard 属性需要 5.0 或以上 Android 版本才可以。

 

3、AppWidget的布局 

这里布局可以随便写,我简单的写了个ImageView

 

4、继承 AppWidgetProvider 

public class RecyclerWidgetProvider extends AppWidgetProvider {    public RecyclerWidgetProvider() {        super();    }    @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);        Log.i("shenlong", "onUpdate");        for (int i = 0; i < appWidgetIds.length; i++) {            int appWidgetId = appWidgetIds[i];            Log.i("shenlong", "onUpdate appWidgetId=" + appWidgetId);            Intent intent = new Intent();            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |                    Intent.FLAG_ACTIVITY_TASK_ON_HOME);            intent.setClass(context, MainActivity.class);            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);            // Get the layout for the App Widget and attach an on-click listener            // to the button            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);            views.setOnClickPendingIntent(R.id.iv_widget, pendingIntent);            // Tell the AppWidgetManager to perform an update on the current app widget            appWidgetManager.updateAppWidget(appWidgetId, views);        }    }    /**     * 当 Widget 被删除时调用该方法。     *     * @param context     * @param appWidgetIds     */    @Override    public void onDeleted(Context context, int[] appWidgetIds) {        super.onDeleted(context, appWidgetIds);        Toast.makeText(context, "onDeleted", Toast.LENGTH_SHORT).show();    }    /**     * 当 Widget 第一次被添加时调用,例如用户添加了两个你的 Widget,那么只有在添加第一个 Widget 时该方法会被调用。     * 所以该方法比较适合执行你所有 Widgets 只需进行一次的操作     *     * @param context     */    @Override    public void onEnabled(Context context) {        super.onEnabled(context);    }    /**     * 与 onEnabled 恰好相反,当你的最后一个 Widget 被删除时调用该方法,所以这里用来清理之前在 onEnabled() 中进行的操作。     *     * @param context     */    @Override    public void onDisabled(Context context) {        super.onDisabled(context);    }    /**     * 当 Widget 第一次被添加或者大小发生变化时调用该方法,可以在此控制 Widget 元素的显示和隐藏。     *     * @param context     * @param appWidgetManager     * @param appWidgetId     * @param newOptions     */    @Override    public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {        super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);    }    @Override    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {        super.onRestored(context, oldWidgetIds, newWidgetIds);    }}

注释写的应该还蛮详细的, 

onUpdateonDeletedonDisabledonAppWidgetOptionsChanged等函数的调用时机都写在注释里了。另外,AppWidgetProvider 继承自 BroadcastReceiver,所以要实现onReceive()方法, onReceive() 中处理的是 Widget 相关的广播事件,然后分发到各个回调函数中onUpdate()onDeleted()onEnabled()onDisabledonAppWidgetOptionsChanged()

 

5、为widget添加点击事件

a、首先先定义个开启Activity的intent

Intent intent = new Intent();

 

b、用intent实例化一个PendingIntent,调用pendingIntent的getActicity方法来启动另一个Activity

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

 

c、实例化RemoteView,其对应相应的Widget布局

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

 

d、给RemoteView上的控件设置按钮事件

views.setOnClickPendingIntent(R.id.iv_widget, pendingIntent);

 

e、更新AppWidget界面

appWidgetManager.updateAppWidget(appWidgetId, views);

 

这样,就实现了点击事件,效果图可以见上图

源码:https://github.com/AdleyLong/RecyclerViewDemo

 

转: https://blog.csdn.net/Picasso_L/article/details/70597609

你可能感兴趣的文章
详细介绍Linux shell脚本基础学习(一)
查看>>
存储引擎和Mysql服务层出现索引信息不一致错误提示
查看>>
LInux下如何挂载光盘找rpm包?
查看>>
java 异常处理
查看>>
MySQL异常
查看>>
写给工程师的十条精进原则
查看>>
前嗅ForeSpider教程:采集图片/视频/资源文件的链接地址
查看>>
远程部署SEP 11.RU5 安装包到 Windows 7 客户端提示“访问被拒”
查看>>
zabbix自定义用户key
查看>>
PHP5.3安装
查看>>
Python怎么使用beautifulsoup来从HTML片段中删除标签
查看>>
java并发编程-volatile内存实现和原理
查看>>
我的友情链接
查看>>
前端知识 | 简析ES6
查看>>
zip压缩工具与tar打包并压缩工具
查看>>
我的友情链接
查看>>
(8)Xwork容器概览
查看>>
gem包 用途说明
查看>>
C# textBox框实现输入像百度搜索出现下拉列表的格式
查看>>
混日子不是你的错,根源在这里
查看>>