开发者

Android Views - How to Configure a "Loose" Piece of View Element Through XML?

开发者 https://www.devze.com 2022-12-19 06:32 出处:网络
This is what i\'m trying to achieve: Use a TextView in a TabWidget (i.e. call TabHost.TabSpec.setIndicator(View) instead of TabHost.TabSpec.setIndicator(String)).

This is what i'm trying to achieve:

  1. Use a TextView in a TabWidget (i.e. call TabHost.TabSpec.setIndicator(View) instead of TabHost.TabSpec.setIndicator(String)).

  2. And i want to configure that TextView in XML instead of building it programatically.

So initially, in my layout XML, i had:

<TabHost
    android:id="@+id/mainTabHost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/ap开发者_如何学Pythonk/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>

Now i want to put in the TextView configuration somewhere. It does not actually "belong" nested anywhere within the layout hierarchy. But, since the layout XML have to be a valid XML of course, it can't have more than one root element. So i'm forced to nest the TextView somewhere. Hence i just put it one level below the root (TabHost):

<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"/>
    <TextView
        android:id="@+id/tvTabIndicatorPreferences"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:text="@string/tab_name_preferences"/>
    <FrameLayout
        android:id="@android:id/tabcontent"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingTop="30px">
    </FrameLayout>
</TabHost>

And in my code i do:

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);

but there's a problem here. When i try to run the application, i get an exception which says

Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

which is by all means logical and reasonable. The TextView is already a child of the TabHost. i can't just set it as the child of another element. (Note: Putting the TextView nested under the TabWidget yields the same thing.)

so i'm forced to call mainTabHost.removeView(tvTabIndicatorPreferences) before calling the setIndicator.

It works actually, but this way of doing feels very wrong to me. Firstly, i have to put the TextView in the XML where it didn't belong, then in the code remove it from where it didn't belong before using it.

In such a scenario, what's the Right Way to achieve this?


Step #1: Pull the TextView out into a separate layout file (e.g., res/layout/indicator.xml).

Step #2: Call tabSpecPreferences.setIndicator(getLayoutInflater().inflate(R.layout.indicator, null));

Step #3: There is no Step #3.

0

精彩评论

暂无评论...
验证码 换一张
取 消