Android视图-如何通过XML配置“松散”的视图元素?
这就是我想要实现的目标: 在TabWidget中使用文本视图,即调用TabHost.TabSpec.setIndicatorView而不是TabHost.TabSpec.setIndicatorString 我想用XML来配置TextView,而不是通过编程来构建它 因此,最初,在我的布局XML中,我有:Android视图-如何通过XML配置“松散”的视图元素?,android,layout,view,Android,Layout,View,这就是我想要实现的目标: 在TabWidget中使用文本视图,即调用TabHost.TabSpec.setIndicatorView而不是TabHost.TabSpec.setIndicatorString 我想用XML来配置TextView,而不是通过编程来构建它 因此,最初,在我的布局XML中,我有: <TabHost android:id="@+id/mainTabHost" android:layout_width="fill_parent" android
<TabHost
android:id="@+id/mainTabHost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="30px"/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="30px">
</FrameLayout>
</TabHost>
但这里有个问题。当我尝试运行应用程序时,我得到一个异常,它说
Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
这绝对是合乎逻辑和合理的。TextView已经是TabHost的子级。我不能将它设置为另一个元素的子元素。注意:将TextView嵌套在TabWidget下会产生相同的结果
因此,在调用setIndicator之前,我必须调用mainTabHost.removeViewTvTabIndicator引用
它实际上是有效的,但这种做法让我觉得很不对。首先,我必须将TextView放在XML中它不属于的地方,然后在使用它之前在代码中从它不属于的地方删除它
在这种情况下,实现这一点的正确方法是什么?步骤1:将文本视图拉到单独的布局文件中,例如res/layout/indicator.xml
步骤2:调用tabSpecPreferences.setIndicatorTargetLayoutFlater.inflateR.layout.indicator,null
步骤3:没有步骤3。谢谢!之前,我确实按照您在步骤1中所说的做了,但在步骤2中,我所做的是尝试直接调用findViewById。。。这给了我一个NPE。因此,我认为所有相关的视图元素必须在同一个布局文件中。哦,我还发现,通过这种方式,我实际上可以在两个选项卡的布局XML中重用TextView。怎么会这样?我是说,TextView会有两个父母吗?或者inflate是否从同一配置创建视图的不同实例?每次调用inflate都会创建一个新的Java对象树。谢谢!我正要发布另一个问题,关于如何动态创建N个通过XML配置的视图元素。但现在我知道了!
final TabHost mainTabHost = (TabHost) this.findViewById(R.id.mainTabHost);
mainTabHost.setup();
final TextView tvTabIndicatorPreferences = (TextView) this.findViewById(R.id.tvTabIndicatorPreferences);
final TabHost.TabSpec tabSpecPreferences = mainTabHost.newTabSpec("tabPreferences");
tabSpecPreferences.setIndicator(tvTabIndicatorPreferences);
tabSpecPreferences.setContent(R.id.scrlTblPreferences);
mainTabHost.addTab(tabSpecPreferences);
Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.