App Widgets 详解三 Activity中添加App Widgets

导读

  • 从官方文档可知,App widgets 是微型应用视图,能够嵌入到其他的应用程序(如系统桌面/其他应用的Activity)

  • 由于现在App Widget在实际开发中已经不常见了,本篇简单介绍如何将widget添加到当前Activity

有兴趣深入研究的同学可以看下Launch实现widget的原理

关键API AppWidgetHost 官方文档

  • App Widget 小部件系列其他文章链接:

App Widgets 详解一 简单使用

App Widgets 详解二 Configuration Activity

App Widgets 详解三 Activity中添加App Widgets

App Widgets 详解四 RemoteViews、RemoteViewsService和RemoteViewsFactory

实现步骤

  1. 设置要长按监听的布局
  2. 使用AppWidgetHost.startListening() 监听widget的状态变化
  3. 请求添加一个新的widget:用于选取系统中的widget
  4. 接收添加appwidget和appwidget的配置activity的返回值.分类处理添加widget的逻辑业务

public class ExampleActivity extends AppCompatActivity {
    private AppWidgetHost    mAppWidgetHost;
    private AppWidgetManager mAppWidgetManager;
    private FrameLayout      frameLayout;
    private static final int    REQUEST_PICK_APPWIDGET   = 1;
    private static final int    REQUEST_CREATE_APPWIDGET = 2;
    private static final int    APPWIDGET_HOST_ID        = 0x100;     //用于标识
    private static final String EXTRA_CUSTOM_WIDGET      = "custom_widget";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //1.设置要长按监听的布局
        //这里不一定学我直接监听根布局,写一个ViewGroup重写那三个方法(扩展性更高)
        frameLayout = new FrameLayout(this);

        setContentView(frameLayout);

        frameLayout.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                showWidgetChooser();
                return true;
            }
        });


        mAppWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
        mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID);

        //2.使用AppWidgetHost.startListening() 监听widget的状态变化
        mAppWidgetHost.startListening();


    }

    /**
     * 4.接收添加appwidget和appwidget的配置activity的返回值.分类处理添加widget的逻辑业务
     * <p>
     * 选中了某个widget之后,根据是否有配置来决定直接添加还是弹出配置activity
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case REQUEST_PICK_APPWIDGET:
                    addAppWidget(data);
                    break;
                case REQUEST_CREATE_APPWIDGET:
                    completeAddAppWidget(data);
                    break;
            }
        } else if (requestCode == REQUEST_PICK_APPWIDGET &&
                resultCode == RESULT_CANCELED && data != null) {
            //如果configure Actvity finish掉,已经添加过Widget,就不添加widget
            int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
            if (appWidgetId != -1) {
                mAppWidgetHost.deleteAppWidgetId(appWidgetId);
            }
        }
    }

    /**
     * 选中了某个widget之后,根据是否有配置来决定直接添加还是弹出配置activity
     *
     * @param data
     */
    private void addAppWidget(Intent data) {
        int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);

        String customWidget = data.getStringExtra(EXTRA_CUSTOM_WIDGET);
        d("addAppWidget", "data:" + customWidget);

        AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);

        d("addAppWidget", "configure:" + appWidget.configure);
        if (appWidget.configure != null) {
            //有配置,弹出配置
            Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
            intent.setComponent(appWidget.configure);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

            startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
        } else {
            //没有配置,直接添加
            completeAddAppWidget(data);
        }
    }


    /**
     * 3.请求添加一个新的widget:用于选取系统中的widget
     * <p>
     * 实际上系统 Launch ,选择widget之后弹出的widget列表是一个Activity,
     * <p>
     * 需要用带上Extra的,AppWidgetManager.ACTION_APPWIDGET_PICK这个Intent来启动
     * <p>
     * 这里我们用startActivityForResult()传参分类处理
     */
    private void showWidgetChooser() {
        int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
        Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
        pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);
    }

    /**
     * 添加widget
     *
     * @param data
     */
    private void completeAddAppWidget(Intent data) {
        Bundle extras = data.getExtras();
        int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);

        d("completeAddAppWidget", "dumping extras content=" + extras.toString());
        d("completeAddAppWidget", "appWidgetId:" + appWidgetId);
        AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);

        View hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
        frameLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, appWidgetInfo.minHeight));
        frameLayout.addView(hostView);
    }

}

效果图

这里写图片描述

==注意==

  1. 必须调用AppWidgetHost的startListening方法来监听appwidget的状态变化,否则添加上去的appwidget不会更新的.
  2. 需要override一个onActivityResult方法,来接收添加appwidget和appwidget的配置activity的返回值.
  3. 启动AppWidgetManager.ACTION_APPWIDGET_PICK这个Intent,必须要给列表中加上自己定义的一个选项,否则出错.

总结:

本系列Demo源码

本篇文章到此结束,欢迎关注,后续有补充的会即使更新,有问题也欢迎评论,共同成长

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值