Android进阶之路

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

2022-05-10  本文已影响0人  码农的地中海

一、概念:

Widget是什么?

Widget就是可以放在桌面上的组件。

Widget特征

身材微 、 形式多 、 功能巨 、 姿容丽 、 个性化 、 易制作

Widget应用

Widget应用在Android手机上得到了广泛的应用。由于其方便小巧,所以得到了很多的应用,像天气,微博,信息,歌曲,时间等等。

Widget使用

绘制Widget的布局:和其他应用类的APP不同的是,Widget支持的控件比较少:除了基本的布局之外(相对、线性、帧、网格),ImageView、Image...

二、Widget设计步骤:

1.需要修改三个XML,一个class:

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

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

上一篇下一篇

猜你喜欢

热点阅读