视图替换后,重复的布局ID返回为-1

时间:2012-10-17 13:10:19

标签: android android-fragments android-view

短篇小说: 我有一个布局“layout.xml”,在成功的Web请求后,它将被另一个布局“success.xml”替换。两种布局都有ImageView,可为布局提供背景。这两个背景都需要相同,并且都取决于用户偏好。

更长的故事:这一切都发生在Fragmnet AsyncTask,并在网络请求后用onPostExecute中的“success.xml”替换了contentView。这发生如下:

View view = getView();
view = null;
view = View.inflate(context, R.layout.success, null);

我尝试做的是为ImageView提供以下android:id="@+id/background_image",然后致电

ImageView background = (ImageView)view.findViewById(R.id.background_image);
background.setImageResource(R.drawable.bg1);

此背景设置适用于初始视图(layout.xml),但在尝试更改为“success.xml”时,我得到NullPointException,因为background为空。

我已经检查过,并且View的ID设置为-1,而原始视图的background_image ID设置为合理且有效的。

我也尝试设置第二个视图的背景ID,如:android:id="@id/background_image",即没有'+',但仍然没有运气。

增加的复杂性是它不仅仅是2个布局,而是我需要执行此操作的大约5个布局,因此回收视图ID非常方便。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

用于替换片段视图的代码将无法执行您想要的操作,原始视图将保持不变,因为您只更改对该视图的引用而不是实际对象。

要使用新布局替换片段的视图,您可以在基本布局(ViewGroup)中包含另一个FrameLayout(例如layout.xml)包装您当前的内容(不要“{忘记给它一个id”)layouts.xml(据我所知这是基本布局)。然后,当需要更换布局时,您可以这样做:

// remove the current content
((ViewGroup) getView().findViewById(R.id.yourWrapperLayout)).removeAllViews();
// add the new content
View.inflate(context, R.layout.success, ((ViewGroup) getView().findViewById(R.id.yourWrapperLayout)));

如果您的所有五个布局都具有相同的根视图类型(如LinearLayout等),您可以避免添加额外的布局。在这种情况下,您将使用与上面相同的代码,但您将修改其他布局文件以使用merge标记。此外,您将在layout.xml布局中查找根目录的ID,您将在其中添加其他文件的内容。

然后你可以拥有相同的id,但你必须重新初始化对视图的任何引用(这意味着如果存储对视图的引用,你将不得不再次搜索视图(如{{1}片段类中的字段))。