【问题标题】:Why is android trying to read an xml layout file from the /res/layout when I have created the layout in code?当我在代码中创建布局时,为什么 android 试图从 /res/layout 读取 xml 布局文件?
【发布时间】:2012-04-05 22:59:50
【问题描述】:

这个问题是关于 RemoteViews 的。它在正常活动中可以正常工作,但在小部件中却不行:

我的 ids.xml 中有这个:

    <item type="layout" name="linear_layout_for_widget"></item>

我的 WidgetProvider 类中有这个:

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget4x1_layout);
    LinearLayout linearLayoutForWidget = layout4x1Provider.createLinearLayoutForWidget(backgroundColor, 
            textColor, borderColor, borderWidth, false);
    RemoteViews nestedView = new RemoteViews(context.getPackageName(), R.layout.linear_layout_for_widget);
    remoteViews.removeAllViews(R.id.frame_layout_root);
    remoteViews.addView(R.id.frame_layout_root, nestedView);
    appWidgetManager.updateAppWidget(widgetId, remoteViews);

Layout4x1Provider 是一个辅助类,它在代码中构建我的布局树。 如果我在我的配置活动中执行此操作(以显示预览),它将正确显示:

    Layout4x1Provider layout4x1Provider = new Layout4x1Provider(this);
FrameLayout frameLayoutRoot = (FrameLayout) findViewById(R.id.frame_layout_root);
    LinearLayout linearLayoutWidget = layout4x1Provider.createLinearLayoutForWidget(backgroundColor, 
            textColor, borderColor, borderWidth, true);
frameLayoutRoot.removeAllViews();
frameLayoutRoot.addView(linearLayoutWidget);

作为 RemoteView,尽管文档声明 RemoteView 类的 addView() 方法等效于 ViewGroup 类的 addView() 方法,但它不起作用。

代码编译,Logcat中只抛出异常:

04-06 00:42:12.843: W/AppWidgetHostView(4671): updateAppWidget couldn't find any view, using error view
04-06 00:42:12.843: W/AppWidgetHostView(4671): android.content.res.Resources$NotFoundException: File  from xml type layout resource ID #0x7f060003
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.content.res.Resources.loadXmlResourceParser(Resources.java:1916)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.content.res.Resources.loadXmlResourceParser(Resources.java:1871)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.content.res.Resources.getLayout(Resources.java:731)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.view.LayoutInflater.inflate(LayoutInflater.java:318)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.widget.RemoteViews.apply(RemoteViews.java:1303)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.widget.RemoteViews$ViewGroupAction.apply(RemoteViews.java:844)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.widget.RemoteViews.performApply(RemoteViews.java:1328)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.widget.RemoteViews.apply(RemoteViews.java:1305)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.appwidget.AppWidgetHostView.updateAppWidget(AppWidgetHostView.java:218)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.appwidget.AppWidgetHost.createView(AppWidgetHost.java:218)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at org.adw.launcher.Launcher.realAddWidget(Launcher.java:4005)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at org.adw.launcher.Launcher.access$25(Launcher.java:3984)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at org.adw.launcher.Launcher$3.onClick(Launcher.java:1069)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:159)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.os.Looper.loop(Looper.java:130)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.app.ActivityThread.main(ActivityThread.java:3687)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at java.lang.reflect.Method.invokeNative(Native Method)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at java.lang.reflect.Method.invoke(Method.java:507)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at dalvik.system.NativeStart.main(Native Method)
04-06 00:42:12.843: W/AppWidgetHostView(4671): Caused by: java.io.FileNotFoundException: 
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.content.res.AssetManager.openXmlAssetNative(Native Method)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.content.res.AssetManager.openXmlBlockAsset(AssetManager.java:486)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  at android.content.res.Resources.loadXmlResourceParser(Resources.java:1898)
04-06 00:42:12.843: W/AppWidgetHostView(4671):  ... 21 more

那么,显然android 正在寻找相应的xml 文件...那么,我如何告诉android 不要寻找xml 文件。我假设 ids.xml 中布局资源的声明应该阻止 android 查找物理文件。在创建布局的代码中,我有:

    linearLayoutForWidget.setId(R.layout.linear_layout_for_widget);

为什么这可以作为 Activity 而不是在小部件/RemoteView 中工作? 不显示小部件,而是显示“加载小部件时出现问题”。 附带说明:我已经将资源项的类型从“布局”更改为“id”,然后再更改。在代码中,无济于事。

这真的让我很烦,因为我见过很多可以即时配置的小部件,以至于我怀疑它们是基于大量资源文件的集合。例如,允许用户使用颜色选择器选择任何背景颜色的小部件。

【问题讨论】:

    标签: android android-layout android-widget


    【解决方案1】:

    因为你告诉它:

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget4x1_layout);
    

    也就是说,我认为它几乎总是如此。

    从代码中修改/添加Views 与使用 XML 布局并不相互排斥。只需在您的 XML 布局中添加最少的数量,也许只是一个 LinearLayout。然后您可以根据需要使用addView 添加。

    【讨论】:

    • 我已经在考虑这种方法了。但问题始终是背景可绘制。 View 类中有一些方法可以将可绘制对象应用为背景:setBackgroundDrawable(Drawable d) 和 setBackGroundResource(int resid)。第一个在 RemoteVieww 类中不可用,第二个转换为 setInt(int vieId, String methodName, int value)。这将再次要求可绘制对象作为 xml 文件存在,并由 R.drawable.my_drawable 作为上述方法的 int 值引用。我正在寻找的是一种传递可绘制对象的方法,它是在代码中创建的?
    • 你不能直接。您通常必须最终使用setBitmap 并处理随之而来的问题(通常是位图大小限制)。不管怎样,你几乎都必须处理这个问题。
    • 或者你建议只在可绘制文件夹中放置一个可绘制的“存根”。通过RemoteViews remoteDrawable = new RemoteViews(context.PackageName(), R.drawable.my_drawable) 检索它,使用setInt(R.drawable.my_drawable, "some_method_name", intValue) 操作其属性,然后使用setInt(R.id,some_view, "setBackgroundResource", R.drawable.my_drawable) 将其设置为视图的背景?改变会进行吗?还是Android会加载原始xml?
    • 我从未使用过位图。我假设位图是图像?还是它的行为像一个形状?缩放以填充背景,具有边框,以编程方式设置其颜色?我可以用代码构造它吗?
    • 您的资源仍然不可用。作为 RemoteView,您的小部件可能托管在另一个应用程序中。它无权访问您的资源。是的,位图就是图像。见BitmapFactory`Bitmap'
    猜你喜欢
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    相关资源
    最近更新 更多