美文网首页Android进阶之路
快速上手Widget设计?这章帮你你搞定!

快速上手Widget设计?这章帮你你搞定!

作者: 码农的地中海 | 来源:发表于2022-05-10 13:51 被阅读0次

    一、概念:

    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技术进阶手册丶面试题纲丶核心笔记资料》

    想有收获必须努力,知识在于积累。不进则退。

    相关文章

      网友评论

        本文标题:快速上手Widget设计?这章帮你你搞定!

        本文链接:https://www.haomeiwen.com/subject/xkulurtx.html