使用 RemoteView 删除 Widget 中以编程方式生成的布局

Posted

技术标签:

【中文标题】使用 RemoteView 删除 Widget 中以编程方式生成的布局【英文标题】:Remove programmatically generated layout in Widget usin RemoteView 【发布时间】:2021-11-07 17:16:01 【问题描述】:

我正在为 android 创建一个小部件,但我遇到了问题。 我的主要小部件布局中有一个容器,我想在列表中动态添加新行。 为此,我在容器的 RemoteViews 上使用 addView 方法:

Widget.java

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
for (int i = 0; i < 10; i++) 
    RemoteViews rowView = new RemoteViews(context.getPackageName(), R.layout.row);
    views.addView(R.id.list_container, rowView);

行.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/row"
    android:layout_
    android:layout_
    android:orientation="horizontal"
    xmlns:android="http://schemas.android.com/apk/res/android">
</LinearLayout>

widget.xml

...
<LinearLayout
    android:id="@+id/list_container"
    android:layout_
    android:layout_
    android:orientation="vertical">
</LinearLayout>
...

所以现在,我有一个 10 行/行布局副本的布局。 但是每一行都有相同的 id,具体取决于我放在 layout/row.xml 中的那个。

我现在想删除一行,因为所有行都有相同的 id,我该怎么做?

我无法更改行的 id,因为 RemoteViews 似乎不接受 setId(id) 方法

删除所有未按预期工作的视图:

     views.removeAllViews(R.id.row);
它只删除第一行。

有人知道这是如何工作的吗?也许我这样做是错误的方式或小部件布局不是以编程方式定义的?

【问题讨论】:

如何为每一行动态设置不同的ID 我没有找到如何实现这一点,因为 setId() 不是 RemoteViews 的方法。我正在开发一个小部件,所以我必须使用 RemoteViews,而不是 Views! 所以,RemoveViews 不是 Views .. 你想怎么做 views.addView(R.id.list_container, rowView) .. Check here 您是否正在对该小部件进行部分更新?还是您每次都进行全面更新?如果是后者,那么您只需要以相同的方式重建RemoteViews,但不包含已删除的项目。 顺便说一句,removeAllViews() 正在正常工作。这并不意味着删除所有具有给定 ID 的 Views。它会删除您传递给它的Views inside;即,它相当于((ViewGroup) findViewById(R.id.row)).removeAllViews()。基本上,您的removeAllViews(R.id.row) 调用清空了第一行,但留下了LinearLayout,这就是其他行不会向上移动的原因。仅供参考。 【参考方案1】:

我添加这个答案是因为 Mike M 找到了解决方案。 Mike. M Comment

不知道这是否是更好的方法,但它的工作原理

我将我的行的 RemoteViews 保存在一个数组中。 每次更新小部件时,我都会用数组的 RemoteViews 填充视图。重新创建我列表的所有布局树。

在每次更新之前,我现在可以在我的 ArrayList 中删除或添加行,这将显示我想要的内容。

ArrayList<RemoteViews> rows = new ArrayList();

// Adding rows : rows.size() = 3
for (int i = 0; i < 3; i++) 
    RemoteViews rowView = new RemoteViews(context.getPackageName(), R.layout.row);
    rows.add(rowView);

// Removing a row : rows.size() = 2
rows.remove(2);

// Update the Layout
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.removeAllViews(R.id.list_container)
for (int i = 0; i < rows.size(); i++) 
    views.addView(R.id.list_container, rowView);

// Only 2 rows appear

另一个问题是访问我行中的特定元素,但这可以使用相同的方法完成。 RemoteViews.settextviewtext(id) 仅在其子项中搜索 id,因此我可以访问行中的元素,因为它们具有不同的 id。

【讨论】:

以上是关于使用 RemoteView 删除 Widget 中以编程方式生成的布局的主要内容,如果未能解决你的问题,请参考以下文章

Android-Widget:使用 RemoteView 更改 ListView 选择器颜色

如何在将在 RemoteView 中使用的可绘制对象上设置颜色过滤器?

如何在android通知中增加remoteview的高度

Remoteview showNext() 和 showPrevious() 中的 ViewFlipper 不起作用

简单理解RemoteView

将 RemoteView 转换为视图