精华内容
下载资源
问答
  • 一般来说如果用这个部件显示时间,那就只在这个布局XML中声明一个textview就OK了。2.第二个xml是widget_provider.xml,主要是用于声明一个appwidget的。其中,Layout就是指定上面那个main.xml。3.第三个xml...

    一、Widget设计步骤  需要修改三个XML,一个class:

    1.第一个xml是布局XML文件(如:main.xml),是这个widget的。一般来说如果用这个部件显示时间,那就只在这个布局XML中声明一个textview就OK了。

    2.第二个xml是widget_provider.xml,主要是用于声明一个appwidget的。其中,Layout就是指定上面那个main.xml。

    3.第三个xml是AndroidManifest.xml,注册broadcastReceiver信息。

    4.最后那个class用于做一些业务逻辑操作。让其继承类AppWidgetProvider。AppWidgetProvider中有许多方法,一般情况下我们只是覆写onUpdate(Context,AppWidgetManager,int[])方法。

    二、代码案例

    1.定义一个WidgetProvider, 用来处理Widget的一些CallBack

    (1)OnEnable,创建第一个Widget时调用。

    (2)OnDisable, 和OnEnable相反,创建最后一个Widget调用。

    (3)OnDelete,Widget的一个实例被删除时调用。

    (4)OnUpdate,当Widget需要更新它的View时调用。

    (5)onReceive():此方法默认情况下处理BroadcastReceiver行为,并调用上面的方法。

    public class WidgetDemoAppWidgetProvider extends AppWidgetProvider{

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    final int N = appWidgetIds.length; // Perform this loop procedure for each App Widget that belongs to this provider

    for (int i=0; i

    int appWidgetId = appWidgetIds[i];

    Intent intent = new Intent();

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

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

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

    appWidgetManager.updateAppWidget(appWidgetId, views);

    }

    }

    }

    2.在AndroidManifast.xml 注册Provide

    android:resource="@xml/widget_demo_appwidget_info" />

    3.创建Widget配置XML在xml文件夹下:

    android:minWidth="60px"

    android:minHeight="60px"

    android:initialLayout="@layout/widget_demo_layout"

    >

    (4)创建Widget 的Layout

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

    android:id="@+id/wap_app"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:src="@drawable/icon"/>

    展开全文
  • 我正在尝试为设备开发android应用程序(设备不是平板电脑或手机,它是运行Android 4.1.1的预先配置的android板),并且其中一项活动需要显示自定义的仪表板,其中包含多种信息,如下所示此处显示的信息类型是预先配置的....

    我正在尝试为设备开发android应用程序(设备不是平板电脑或手机,它是运行Android 4.1.1的预先配置的android板),并且其中一项活动需要显示自定义的仪表板,其中包含多种信息,如下所示

    此处显示的信息类型是预先配置的.我打算从头开始开发所有具有小部件(例如天气和日历)并在版式中包含小部件的应用,而不是从头开始开发所有这些.

    我参考了以下链接

    我完成了大部分代码.

    public class MainActivity extends Activity {

    private AppWidgetManager mAppWidgetManager;

    private AppWidgetHost mAppWidgetHost;

    static final int APPWIDGET_HOST_ID = 2037;

    private AppWidgetHostView widgets[] = new AppWidgetHostView[16];

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    mAppWidgetManager = AppWidgetManager.getInstance(this);

    mAppWidgetHost = new AppWidgetHost(this, APPWIDGET_HOST_ID);

    setContentView(r.id.layout_main);

    ****here is where I am stuck??****

    int [] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(name);

    mAppWidgetHost.startListening();

    }

    但是卡住的地方是,如何指定窗口小部件管理器以获取所需的特定窗口小部件.假设我对小部件感兴趣

    “ com.android.deskclock / com.android.alarmclock.AnalogAppWidgetProvider”

    请指教.

    更新:

    我添加了以下代码

    mAppWidgetManager = AppWidgetManager.getInstance(this);

    mAppWidgetHost = new AppWidgetHost(this, APPWIDGET_HOST_ID);

    int appWidgetId = mAppWidgetHost.allocateAppWidgetId();

    ComponentName name = new ComponentName("com.android.deskclock","com.android.alarmclock.AnalogAppWidgetProvider");

    int [] ids = mAppWidgetManager.getAppWidgetIds(name);

    if(ids != null && ids.length>0){

    System.err.println("Number of widget ids :"+ids.length);

    AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(ids[0]);

    appWidgetId = ids[0];

    LinearLayout parent= (LinearLayout) findViewById(R.id.generalDashboardLayout);

    parent.addView(mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo));

    }else{

    System.err.println("Ids is null");

    }

    它总是打印“ Ids为null”.找不到要添加到我的视图的小部件

    请帮忙

    展开全文
  • 小组件Android平台上命名为AppWidget,有的时候还被翻译成小部件插件和微件。说的都是一个东西:显示在Launcher上,能在Logo以外提供更多信息的特别设计。它方便用户免于打开App即可直接查看信息和进行简单的...

    e3511957eb1c5834f7e6d03accdb0b18.png

    /   今日科技快讯   /

    近日,电动汽车制造商特斯拉公布了2021年第三季度财报。财报显示,特斯拉第三季度营收137.6亿美元,同比增长57%;净利润16.2亿美元,同比增长389%;每股收益1.86美元,与去年同期相比增长145%。

    /   作者简介   /

    明天就是开心的周末了,祝大家周五愉快,我们下周再见。

    本篇文章转载自TechMerger的博客,文章主要分享了Android 12上AppWidget的变化,相信会对大家有所帮助!

    原文地址:

    https://juejin.cn/post/6968851189190377480

    /   前言   /

    Google IO 2021上重磅介绍的Android 12,号称历代设计变化最大的版本。其全新的Material You设计语言、流畅的动画特效再到焕然一新的小组件,都令人印象深刻。本文将聚焦小组件环节,谈谈它在重新设计之后的各种新特性和适配方法。

    小组件在Android平台上命名为AppWidget,有的时候还被翻译成小部件、小插件和微件。说的都是一个东西:显示在Launcher上,能在Logo以外提供更多信息的特别设计。它方便用户免于打开App即可直接查看信息和进行简单的交互,在PC上、早前的Symbian上都有类似的设计。

    简要回顾下移动平台在小组件设计上的持续探索:

    • 早期的Android版本缺乏美观,小组件更是常年未改。似乎除了天气、时钟等常用小组件以外鲜少使用,逐渐被人遗忘

    • Windows Phone的动态磁贴在自由尺寸的Logo上灵活展示信息的设计非常超前,奈何生态构建困难,早已退场

    • Apple向来稳重(保守),直到iOS 10才引入小组件,但负一屏限制着它的发展。直到iOS 14的全面支持才大获成功,大有后来居上的态势

    • VIVO紧随其后重磅推出的OriginOS则将Logo和小组件完美融合,试图一统磁贴和小组件的概念,非常值得称赞

    也许是受到了友商们的持续刺激,Google终于开始重新审视小组件这个元老级功能,并在Android 12里进行了重新设计、重新出发。

    0644a3cccb90a1cfa03c9753d6b519f7.png

    下面将结合代码实战,带领大家逐步感受Android 12里小组件的各项新特性和对应的适配方法。

    /   选择和展示   /

    事实上即使未做任何适配,在12上直接运行的小组件与11就有明显不同,主要表现在选择器和展示的效果。

    以Chrome和Youtube Music的小组件为例:

    ece4115def8021209621d37662acc4a3.png

    可以看到12上的一些变化:

    • 选择器

    • 顶部悬浮搜索框,可以更加快速地找到目标小组件

    • 小组件按照App自动折叠,避免无关的小组件占用屏幕空间

    • App标题还对包含的小组件数目进行了提示

    • 拖拽到桌面上之后小组件默认拥有圆角设计

    11上的小组件选择器不支持搜索而且无法折叠,拖拽到桌面上也是初始的直角效果。

    3895d27c9f52e526a71d6624a09433ae.png

    /   圆角设计   /

    健康信息越发重要,手撸一个展示今日步数的小组件,搭配androidplot框架展示详细的步数图表。

    override fun onUpdate(...) {
        for (appWidgetId in appWidgetIds) {
            showBarChartToWidget(context, appWidgetManager, appWidgetId)
        }
    }
    
    private fun showBarChartToWidget(...) {
        // Create plot view.
        val plot = XYPlot(context, "Pedometers chart")
        ...
        // Set graph shape
        plot.setBorderStyle(Plot.BorderStyle.ROUNDED, 12f, 12f)
        plot.isDrawingCacheEnabled = true
    
        // Reflect chart's bitmap to widget.
        val bmp = plot.drawingCache
        val remoteViews = RemoteViews(context.packageName, R.layout.widget_pedometer)
        remoteViews.setBitmap(R.id.bar_chart, "setImageBitmap", bmp)
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
    }

    不用特别适配,直接运行到12上,就能有圆角效果。

    62942f620e8cda8d5321e101a6508a1f.png

    但布局需要遵从如下两点建议:

    • 四周的边角不要放置内容,防止被切掉

    • 背景不要采用透明的、空的视图或布局,避免系统无法探测边界去进行裁切

    事实上,系统预设了如下dimension以设置默认的圆角表现。

    • system_app_widget_background_radius: 小组件背景的圆角尺寸,默认16dp,上限28dp

    • system_app_widget_inner_radius: 小组件内部视图的圆角尺寸 ,默认8dp,上限20dp

    • system_app_widget_internal_padding:内部视图的padding值,默认16dp

    看下官方的对于内外圆角尺寸的示意图。

    3437f46e7841349c9c3589b1e77365aa.png

    注意:

    1. 这些dimension可以被ROM厂商或3rd Launcher修改,不一定能保证一致性的尺寸

    2. 官方没有说明小组件的内部视图如何才能应用上内部圆角尺寸,DEMO确实也没有适配上,不知道是ROM的问题还是App的问题,有待后续的进一步研究

    当然12以前的系统想要支持圆角设计也很简单:自定义radius的attribute,应用在shape drawable上,手动将drawable应用到background。具体可参考官方Sample:

    https://github.com/android/user-interface-samples/tree/main/AppWidget

    /   动态色彩效果   /

    给小组件添加暗黑主题支持即可自动适配动态色彩。

    <!-- values/themes.xml -->
    <resources xmlns:tools="http://schemas.android.com/tools">
        <style name="Theme.AppWidget" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
            <item name="colorPrimary">@color/purple_500</item>
            <item name="colorPrimaryVariant">@color/purple_700</item>
            <item name="colorOnPrimary">@color/white</item>
            ...
        </style>
    </resources>
    
    <!-- values-night/themes.xml -->
    <resources xmlns:tools="http://schemas.android.com/tools">
        <style name="Theme.AppWidget" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
            <item name="colorPrimary">@color/purple_200</item>
            <item name="colorPrimaryVariant">@color/purple_700</item>
            <item name="colorOnPrimary">@color/black</item>
            ...
        </style>
    </resources>

    da98833933dff79697265d5a6cddfb92.png

    /   预览改进   /

    12针对小组件选择时的预览界面进行了改进,方便展示更加精准的预览效果。

    动态预览

    之前只能使用previewImage属性展示一张预览图,功能迭代的过程中忘记更新它的话,可能导致预览和实际效果发生偏差。

    12新引入了previewLayout属性用以配置小组件的实际布局,使得用户能够在小组件的选择器里看到更加接近实际效果的视图,而不再是一层不变的静态图片。

    这样一来在保证效果一致的同时免去了额外维护预览图的麻烦。

    <appwidget-provider
        <!-- 既存的图片属性指定UI提供的设计图 -->
        android:previewImage="@drawable/app_widget_pedometer_preview_2"
    
        <!-- 新的预览API里指定实际的布局 -->
        android:previewLayout="@layout/widget_pedometer"
    </appwidget-provider>

    左边是步数小组件一开始的设计图,右边是最后的实际效果。

    12f1c201dcdfe99ffa93cef840776c4c.png

    如果忘记说服UI重新作图的话,在11上的预览图会和实际效果有较大偏差。而12上不用在乎设计图是否更新,借助新的API即可直接预览实际效果,所见即所得。

    d0152e92dbd9718441825ce1fb8b0d3c.png

    一般来说previewLayout属性最好指定小组件的实际布局。但如果预览的测试数据和实际的默认值有冲突的话,可以指定专用的预览布局,只需要确保布局的一致。

    添加预览说明

    description属性则可以在小组件预览的下方展示额外的说明,便于用户更好地了解其功能定位。

    <appwidget-provider
        android:description="@string/app_widget_pedometer_description">
    </appwidget-provider>

    daaeeade074d4a4e4ca6d4f907243819.png

    需要提醒的是description属性并非12新增,但12之前的选择器不支持展示这个说明。

    /   新的交互控件   /

    之前的小组件不支持CheckBox等控件,从12开始全面支持CheckBox、Switch和RadioButton三种状态控件。

    下面是采用这三种控件的简单效果。

    1d887b9cd5ba5f1c158dd9a7381bb4c2.png

    再做个简单的待办事项以更好地说明状态小组件的使用。

    // 小组件件布局里指定CheckBox控件即可
    <LinearLayout ...
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:theme="@style/Theme.AppWidget.AppWidgetContainer">
    
        <include layout="@layout/widget_todo_list_title_region" />
    
        <CheckBox
            android:id="@+id/checkbox_first"
            style="@style/Widget.AppWidget.Checkbox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/todo_list_sample_1"
            Tools:text="@string/todo_list_tool" />
        ...
    </LinearLayout>

    3f825e738e1c4ccd8037e2593c26209d.png

    如果将同样的代码运行到11上,则会显示加载失败。日志:

    AppWidgetHostView: Error inflating AppWidget AppWidgetProviderInfo(UserHandle{0}/ComponentInfo{com.example.splash/com.example.splash.widget.TodoListAppWidget}): android.view.InflateException: Binary XML file line #13 in com.example.splash:layout/widget_todo_list: Binary XML file line #13 in com.example.splash:layout/widget_todo_list: Error inflating class android.widget.CheckBox

    096b270be1e0c02dd95509e29b270aa9.png

    文本内容不确定的话,可以通过代码动态地控制文本,同时还可以监听用户的选择事件。

    比如我们要展示Android开发者如今要学习的三座大山,选中的时候弹出Toast。

    private fun updateAppWidget(...) {
        val viewId1 = R.id.checkbox_first
        val pendingIntent = PendingIntent.getBroadcast(...)
    
        val rv = RemoteViews(context.packageName, R.layout.widget_todo_list)
        rv.apply {
            // 设置文本
            setTextViewText(viewId1, context.resources.getString(R.string.todo_list_android))
            ...
    
            // 设置CheckBox的默认选中状态
            setCompoundButtonChecked(viewId1, true)
    
            // 监听相应的CheckBox的选中事件
            setOnCheckedChangeResponse(
                viewId1,
                RemoteViews.RemoteResponse.fromPendingIntent(pendingIntent)
            )
        }
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
    }
    
    override fun onReceive(context: Context?, intent: Intent?) {
        ...
        val checked = intent.extras?.getBoolean(RemoteViews.EXTRA_CHECKED, false) ?: false
        val viewId = intent.extras?.getInt(EXTRA_VIEW_ID) ?: -1
    
        Toast.makeText(
            context,
            "ViewId : $viewId's checked status is now : $checked",
            Toast.LENGTH_SHORT
        ).show()
    }

    b62b3d995d9d40ecab1c75384f3a908b.png

    /   便捷配置尺寸   /

    12针对小组件的尺寸配置环节也进行了改进,更加便捷。

    精确的尺寸

    在已有的minWidth、minResizeWidth等属性以外,新增了几个属性以更便捷地配置小组件的尺寸。

    • targetCellWidth和targetCellHeight:占据Launcher上Cell的宽高格数,用以替代minWidth和minHeight。事实上Launcher是以Cell的单位来展示小组件的,所以直接指定Cell数显然更合理

    • maxResizeWidth和maxResizeHeight: 配置Launcher上允许配置的最大尺寸,弥补minResizeWidth和minResizeHeight的不足

    <appwidget-provider
        ...
        android:targetCellWidth="3"
        android:targetCellHeight="2"
        android:maxResizeWidth="250dp"
        android:maxResizeHeight="110dp">
    </appwidget-provider>

    4f5a1bf95482ede5e27c9de393ce4e11.png

    灵活调节尺寸

    iOS上添加小组件后尺寸就固定了,不支持调节。而Android 12上小组件在长按后即可灵活调节。

    9dc903b8c92f8b01ed24c4d74faf5238.png

    想要支持这个特性只需要给widgetFeatures属性指定reconfigurable值即可。

    <appwidget-provider
        android:widgetFeatures="reconfigurable">
    </appwidget-provider>

    The reconfigurable flag was introduced in Android 9 (API level 28), but it was not widely supported in launchers until Android 12.

    事实上这个属性早在Android 9的时候就引入了,但官方说从S开始才全面支持。我在11版本的Pixel Launcher上发现已经可以直接调节尺寸了,不知道官方的意思是不是别的Launcher并不支持。

    采用默认配置

    configure属性可以在小组件展示之前启动一个配置画面,供用户选择小组件所需的内容、主题和风格等。

    如果想让用户快速看到效果,即不想展示这个画面的话,只要在widgetFeatures里指定新的configuration_optional值即可。

    <appwidget-provider
      ...
      android:configure="com.example.appwidget.activity.WidgetConfigureActivity"
      android:widgetFeatures="reconfigurable|configuration_optional">
    </appwidget-provider>

    后面改主意了又想替换配置的话,可以长按小组件找到配置的入口。

    一是小组件右下方的编辑按钮,二是上方出现的Setup菜单,这在以前的版本上是没有的。

    7913651f3165e563fa23061464515285.gif

    /   高效控制布局   /

    小组件内容较多的时候,为了展示的完整往往会给它限定Size,这意味着只有Launcher空间足够大小组件才能成功放置。当Launcher空间捉急的时候就尴尬了,用户只能在移除别的小组件和放弃你的小组件之间做个抉择。

    免除这种困扰的最佳做法是在不同的Size下采用不同的布局,对展示的内容做出取舍。即Size充足的情况下提供更多丰富的内容,反之只呈现最基本、最常用的信息。

    响应式布局

    之前是如何做到这一需求呢?除了预设各种尺寸的小组件的一般思路以外,通过onAppWidgetOptionsChanged回调也可以控制布局的变化,但往往非常繁琐。

    而12上借助新增的RemoteViews(Map<SizeF, RemoteViews> map)API可以大大简化实现过程。在小组件放置的时候就将Size和布局的映射关系告知系统,当Size变化了AppWidgetManager将自动响应更新对应的布局。

    比如待办事项小组件在Size为3x2的时候额外展示添加按钮,2x2的时候只展示事项列表的相应式布局。

    6723179467a699aa35a136a77a8b5b24.png

    代码的实现也简单清晰:

    private fun updateAppWidgetWithResponsiveLayouts(...) {
        ...
        // 尺寸够宽的情况下Button才显示
        val wideView = RemoteViews(rv)
        wideView.setViewVisibility(button, View.VISIBLE)
    
        val viewMapping: Map<SizeF, RemoteViews> = mapOf(
            SizeF(100f, 100f) to rv,
            SizeF(200f, 100f) to wideView
        )
    
        // 将Size和RemoteViews布局的映射关系告知AppWidgetManager
        val remoteViews = RemoteViews(viewMapping)
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
    }

    好处:

    • 免于同一功能提供一堆尺寸小组件的繁琐,减轻选择器的负担

    • 实现简单,自动响应

    精确布局

    如今移动设备的尺寸、形态丰富多样,尤其是折叠屏愈加成熟。如果响应式布局仍不能满足更精细的需求,可以在Size变化的回调里,获取目标Size对布局进一步的精确把控。

    利用AppWidgetManager新增的OPTION_APPWIDGET_SIZES KEY可以从AppWidgetManager里拿到目标Size。

    // 监听目标尺寸
    override fun onAppWidgetOptionsChanged(...) {
        ...
        // Get the new sizes.
        val sizes = newOptions?.getParcelableArrayList<SizeF>(
            AppWidgetManager.OPTION_APPWIDGET_SIZES
        )
    
        // Do nothing if sizes is not provided by the launcher.
        if (sizes.isNullOrEmpty()) {
            return
        }
        Log.d("Widget", "PedometerAppWidget#onAppWidgetOptionsChanged() size:${sizes}")
    
        // Get exact layout
        if (BuildCompat.isAtLeastS()) {
            val remoteViews = RemoteViews(sizes.associateWith(::createRemoteViews))
            appWidgetManager?.updateAppWidget(appWidgetId, remoteViews)
        }
    }

    如下的日志显示Size变化的时候会将目标Size回传。

    Widget  : PedometerAppWidget#onAppWidgetOptionsChanged() size:[377.42856x132.0, 214.57143x216.57143]

    之后从预设的精细布局里匹配相应的视图。

    private fun createRemoteViews(size: SizeF): RemoteViews {
        val smallView: RemoteViews = ...
        val tallView: RemoteViews = ...
        val wideView: RemoteViews = ...
        ...
    
        return when (size) {
            SizeF(100f, 100f) -> smallView
            SizeF(100f, 200f) -> tallView
            SizeF(200f, 100f) -> wideView
            ...
        }
    }

    注意:实际上Size列表由Launcher提供,如果3rd Launcher没有适配这一特性的话,回传的Size可能为空

    /   自由更新视图   /

    RemoteViews作为小组件视图的重要管理类,本次OSV也添加了诸多API,以便更加自由地控制视图的展示。

    • 更改颜色的setColorStateList()

    更改边距的setViewLayoutMargin()

    更改宽高的setViewLayoutWidth()等

    这些新API可以助力我们实很多方便的功能,比如CheckBox选中之后更新文本颜色,思路很简单:

    1. 监听小组件的点击事件并传递目标视图

    2. 根据CheckBox的状态获得预设的文本颜色

    3. 使用setColorStateList()更新

    override fun onReceive(context: Context?, intent: Intent?) {
        ...
        // Get target widget.
        val appWidgetManager = AppWidgetManager.getInstance(context)
        val thisAppWidget = ComponentName(context!!.packageName, TodoListAppWidget::class.java.name)
        val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget)
    
        // Update widget color parameters dynamically.
        for (appWidgetId in appWidgetIds) {
            val remoteViews = RemoteViews(context.packageName, R.layout.widget_todo_list)
            remoteViews.setColorStateList(
                viewId,
                "setTextColor",
                getColorStateList(context, checked)
            )
            appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
        }
    }
    
    private fun getColorStateList(context: Context, checkStatus: Boolean): ColorStateList =
        if (checkStatus) 
            ColorStateList.valueOf(context.getColor(R.color.widget_checked_text_color))
        else 
            ColorStateList.valueOf(context.getColor(R.color.widget_unchecked_text_color))

    399357689c4613d74eef962117449248.png

    再比如Chart线图太小,看不清楚。可以让它在点击之后放大,再点击之后恢复原样。

    // 根据记录的缩放状态获得预设的宽高
    // 通过setViewLayoutWidth和setViewLayoutHeight更新宽高
    override fun onReceive(context: Context?, intent: Intent?) {
        ...
        val widthScaleSize = if (scaleOutStatus) 200f else 260f
        val heightScaleSize = if (scaleOutStatus) 130f else 160f
    
        // Update widget layout parameters dynamically.
        for (appWidgetId in appWidgetIds) {
            val remoteViews = RemoteViews(context.packageName, R.layout.widget_pedometer)
            remoteViews.setViewLayoutWidth(viewId, widthScaleSize, TypedValue.COMPLEX_UNIT_DIP)
            remoteViews.setViewLayoutHeight(viewId, heightScaleSize, TypedValue.COMPLEX_UNIT_DIP)
            appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
        }
    }

    c9686799f8e6861940c7113171775e42.png

    /   流畅启动效果   /

    12版本上点击Widget启动App的时候可以呈现更流畅的过渡效果,适配也很简单。官方指示只需给小组件的根布局指定android的 backgoround id即可。

    <LinearLayout
        ...
        android:id="@android:id/background">
    </LinearLayout>

    实际的动作显示添加这个ID后App启动没有什么变化,个中原因需要继续研究。

    12开始对从Broadcast Receiver或Serivce启动Activity做了更严格的限制,但不包括Widget发起的场合。但为了避免视觉上的突兀,这种后台启动的情况下不展示迁移动画。

    /   简化数据绑定   /

    小组件里展示ListView的需求也很常见,提供数据的话需要声明一个 RemoteViewsService 以返回RemoteViewsFactory,比较绕。

    而12里新增的 setRemoteAdapter(int , RemoteCollectionItems) API则可以大大简化这个绑定过程。

    比如制作一个即将到来的事件列表小组件,通过这个API便可以高效注入数据。

    private fun updateCountDownList(...) {
        ...
        // 创建用于构建Remote集合数据的Builder
        val builder = RemoteViews.RemoteCollectionItems.Builder()
        val menuResources = context.resources.obtainTypedArray(R.array.count_down_list_titles)
    
        // 往Builder里添加各Item对应的RemoteViews
        for (index in 0 until menuResources.length()) {
            ...
            builder.addItem(index.toLong(), constructRemoteViews(context, resId))
        }
    
        // 构建Remote集合数据
        // 并通过setRemoteAdapter直接放入到ListView里
        val collectionItems = builder.setHasStableIds(true).build()
        remoteViews.setRemoteAdapter(R.id.count_down_list, collectionItems)
        ...
    }
    
    // 创建ListView各Item对应的RemoteViews
    private fun constructRemoteViews(...): RemoteViews {
        val remoteViews = RemoteViews(context.packageName, R.layout.item_count_down)
        val itemData = context.resources.getStringArray(stringArrayId)
    
        // 遍历Item数据行设置对应的文本
        itemData.forEachIndexed { index, value ->
            val viewId = when (index) {
                0 -> R.id.item_title
                1 -> R.id.item_time
                ...
            }
            remoteViews.setTextViewText(viewId, value)
        }
        return remoteViews
    }

    e5826a402a8905c5391cf4a4c49803ab.png

    如果Item的布局不固定不止一种,可以使用setViewTypeCount指定布局类型的数目,告知ListView需要提供的ViewHolder种类。如果不指定也可以,系统将自动识别布局的种类,需要系统额外处理而已。

    但要注意:如果指定的数目和实际的不一致会引发异常。

    IllegalArgumentException: View type count is set to 2, but the collection contains 3 different layout ids

    另外,需要补充一下,支持该API的View必须是AdapterView的子类,比如常见的ListView、GridView等。RecyclerView是不支持的,毕竟小组件里数据量不多,不能使用也没关系。

    /   新增API总结   /

    简要罗列一下12针对小组件新增的API,方便大家查阅。

    de3607824f8ae9c416cd240377012012.png

    157e1e4d676e8de1f7acfabc460f7394.png

    /   结语   /

    通过上面的解读,大家可以感受到Google在小组件的重新设计上耗费了诸多努力,它给这个老旧的功能注入很多新玩法和新花样。

    简要回顾一下Android 12里小组件的新特性:

    • 更便捷的小组件选择器

    • 更美观的圆角边框设计

    • 更灵活的小组件预览

    • 更完整的控件支持

    • 更方便的尺寸调节

    • 更精准的布局控制

    • 更自由的视图更新

    • 更简便的列表数据绑定

    如此之多的新特性,在助力小组件高效开发的同时,还能给用户呈现更加优秀的使用体验。

    跟随Android 12的脚步,快快尝试起来,让现有的小组件重新绽放光彩。

    未决事项

    1. 小组件内部视图的圆角尺寸如何适配?

    2. 小组件启动App的流畅过渡效果如何实现,是什么效果?

    Demo地址:

    https://github.com/ellisonchan/NewAppWidget

    推荐阅读:

    Button的“进化之旅”

    PermissionX 1.6发布,支持Android12

    Android 12 正式发布 | 开发者们的全新舞台

    欢迎关注我的公众号

    学习技术或投稿

    4c0d02edab66151529c08477ee5a9e37.png

    6d2497914cc1ee93ce54d756deb9176a.png

    长按上图,识别图中二维码即可关注

    展开全文
  • 安卓仿ios14桌面小部件

    千次阅读 2021-05-26 07:53:13
    安卓仿ios14桌面小部件,是一个可以让安卓手机的界面看起来像苹果界面的软件,功能非常强大,它可以提供多种不同主题的壁纸桌面,随心选择,设置后的效果还是非常不错的,很有高级感,操作简单,上手也很快。安卓仿...

    安卓仿ios14桌面小部件,是一个可以让安卓手机的界面看起来像苹果界面的软件,功能非常强大,它可以提供多种不同主题的壁纸桌面,随心选择,设置后的效果还是非常不错的,很有高级感,操作简单,上手也很快。

    安卓仿ios14桌面小部件功能:

    1.这是一款非常好用的桌面主题,可以让你的安卓界面和苹果界面一样。

    2.包括了各种桌面小工具,将自己的安卓手机变为iOS系统的仿生桌面。

    3.是能体现iphone桌面风格的应用,提供锁屏,控制中心以及壁纸商店三大核心功能。

    4.丰富的主题、壁纸、特效和桌面设置,让你的手机好用又好玩!如果您已经厌倦了Android千篇一律的解锁方式。

    安卓仿ios14桌面小部件亮点:

    1.多种不同的主题可以去进行搭配选择,我们给你提供了最真实的IOS主题。

    2.你可以去进行对铃声的替换,内置的所有IOS自带的系统铃声可以随意的选择。

    3.操作非常的简单,上手也是十分快的,大家可以轻松线上进行制定操作,上手很快。

    小编点评:

    1.即使使用的不是苹果手机,也是可以直接使用仿ios14的桌面。

    2.效果看起来还是非常不错的,喜欢的用户都是可以去尝试的。

    3.这样的部件添加上去不会显得手机界面很单调,值得一用。

    展开全文
  • 万能小组件透明背景设置全新为广大用户带来的精美小组件模板应用服务平台,有海量的小组件,快捷方式小组件以及照片小组件,让你的桌面更加简单美观,感兴趣的朋友快来下载体验吧!万能小组件透明小组件软件介绍:...
  • 桌面小组件

    2021-05-28 04:26:02
    桌面小组件安卓版上线啦,非常实用的手机主题桌面美化神器,可以帮助用户进行桌面的美好,还可以在这里添加各种小组件在桌面上,根据自己喜欢的方式进行排列,非常的有意思,操作非常简单,需要就赶快点击下载吧!...
  • 首先看下效果demo.gif背景在Android手机中,我们经常会看到各种桌面小部件,天气、音乐播放器、时间表盘等,虽然常见,但是我们着手开发的还是较少,其实桌面小部件开发起来很简单,但是还是可能会走一些弯路,下面...
  • 写过桌面小部件的同学都知道,由于小部件是在在部件加载的,所以支持的view比较有限,用官方的原话说就是Creating the App Widget layout is simple if you're familiar withLayouts.However, you must be aware ...
  • ios14小组件怎么添加1、在手机升级到iOS14系统之后,就可以拥有小组件功能2、长按手机空白处位置,就可以进入到编辑界面3、点击左上方的加号图标,选择需要添加小组件4、滑动选择需要使用的样式,选择下方的添...
  • 有些时候,我们需要为自己的应用添加一个桌面小部件来显示一些简单但是关键的信息方便用户使用。应用小部件的视图是靠RemoteViews来展现的,而RemoteViews内只能放置一些简单的ViewGroup和Widget。文章内容基本上是...
  • 如何更改Android标签小部件的背景?我的课扩展了TabActivityTabHost mTabHost = getTabHost();TabHost.TabSpec tab1 =mTabHost.newTabSpec("tab1");TabHost.TabSpec tab2 =mTabHost.newTabSpec("tab2");tab1 ....
  • 时钟天气小部件

    2021-06-08 07:10:44
    Clock Weather Mobile Edition是一款个性化的手机锁屏时钟和天气日历插件,非常实用且易于使用,软件非常,反正它并不会占用太多内存,而且使用非常方便. 您还可以根据自己的喜好调整字体,颜色和其他DIY.功能...
  • 我有一个Android小部件,它使用Web服务来检索和显示小部件上的数据.小部件具有扩展PreferenceActivity的配置活动.安装小部件后,即可启动配置活动,这是此小部件所需的行为.问题是,无论何时将主窗口添加到主屏幕,窗口...
  • Android 12 小部件详解

    2021-12-03 10:52:31
    2020年九月苹果的 iOS 14 正式版本发布,其中的一项重大更新就是苹果也支持小部件了!不容易啊,安卓好多年前拥有的功能现如今苹果终于用上了,虽然苹果的小部件挺好看的,但是安卓也不差,快来看看吧!
  • 本文实例讲述了android自定义组件实现方法。分享给大家供大家参考。具体如下:atts.xml:TopBar.java:package com.cd.administrator.mytopbar;import android.annotation.TargetApi;import android.content.Context...
  • 软件中有丰富多元的主题,各种风格类型的都有,满足大家不同的喜好,小组件的选择性也非常多,大家常用的时钟、日历、天气等等都有,还可以挑选不同的尺寸组合,轻松打造好玩有趣的手机桌面。软件特色1.在软件里可以...
  • 编写配置文件 在清单中声明小部件 如果想要在 Android添加一个小部件的话首先应该在 AndroidManifest.xml 中进行声明,因为小部件实际上也是一个 BroadcastReceiver,大家都知道四大组件想要使用的话都需要在 ...
  • 而系统自带的程序,典型的App Widget是music,这个Android内置的音乐播放程序。这个是典型的App Widget+app应用。就是一个程序既可以通过App Widget启动,也可以通过App启动。App Widget就是一个AppWidgetPr...
  • 本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下–主页面——–//布局中就一个Buttonpublic class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle ...
  • 安卓组件之通知栏

    2021-05-26 10:39:45
    通知是安卓中比较常见的一种展示后台发生的消息的方式,使用 NotificationManager 发送一个 Notification 类型的消息,使用方法大多是先获取一个通知的系统服务类然后创建一个通知并添加通知布局样式和点击跳转方式...
  • 原标题:这款 Android 应用,帮你优雅地管理桌面小部件在很长一段时间内,桌面小部件一直是 Android 桌面上一个非常不错的独占功能。它可以让你把各式各样的小组件放到你喜欢的地方,从而方便地实现一些快捷功能,还...
  • 智能型手机的音量控制工具,通常都埋在设置菜单的「...之前曾介绍过的「VolumeControl Free」就是个蛮不错的桌面音量调整工具,不过似乎不太支持高端的 Android 版本,放置在桌面的工具,虽仍可做音量调整,但...
  • 如果你现在想换一款手机,在预算充足的情况下,选择是非常多的。多到什么程度?系统(iOS、Android、Windows Phone和其他)、...但是,在真正可随意改变形态的柔性屏幕及组件出现前,你都需要忍受越来越大的手机体...
  • 万能小组件小部件

    2021-05-28 08:55:12
    万能小组件小部件,优质的手机桌面美化工具,您可以自由编辑组件内容,例如时钟、日历、相册、背景、天气等等,还可以快速设置锁屏壁纸,打造专属于自己的个性桌面,简单又好用!非常炫酷哦!万能小组件小部件介绍...
  • 在项目开发中,我们经常需要进行动态添加组件,其中可添加的部分有两项:布局和组件其中,添加的布局主要有RelativeLayout型(相对布局)的和LinearLayout(线性布局)添加组件主要有文本显示框,编辑框,按钮等组件。...
  • 工具/原料Android手机方法/步骤添加的方法很简单,首先可在应用市场上下载并且安装你喜欢的软件或游戏,随后该图标或者插件就会出现在你的手机桌面上。下面重点讲解下如何删除。首先解锁进入手机桌面:...
  • 如果你需要一款好用的手机修复软件,不妨试试编带来的这款牛学长安卓手机修复工具,功能强大全面,使用后可以帮助用户更轻松便捷的修复安卓手机。软件能够轻松的将修复Android系统正常,软件能够修复50多个Android...
  • 安卓手机一直以来以其可玩性高而受到欢迎,即使是简单的桌面小部件,也有人能玩出花来。强大如 Zooper Widget 和 KWGT 等复杂且定制性极强的美化类桌面插件应用,抑或是朴实无华但又必不可少的时间和天气小部件,...
  • 1、Widgetwidget可以直译为小部件,它在Android中代表视图的概念,如TextView、Button、EditText等widget视图控件,及LinearLayout等视图布局。2、AppWidgetAppWidget是放置在手机屏幕的桌面小组件应用,如时钟、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 63,044
精华内容 25,217
关键字:

安卓手机添加小组件