机器人:方向=&QUOT垂直的QUOT;对于TabWidget不起作用 [英] android:orientation="vertical" does not work for TabWidget

查看:237
本文介绍了机器人:方向=&QUOT垂直的QUOT;对于TabWidget不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序有四个选项卡的tabhost,现在我试图让漂亮的布局横向模式。为了利用附加的水平空间,我希望把TabWidget在屏幕右侧,而五言的所有标签必须是在另一个(就像一)。 但切换到横向模式下,所有的标签在连续获得一致的时候,它看起来很丑陋。如何解决这个问题?

 < XML版本=1.0编码=UTF-8&GT?;
< TabHost的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:ID =@机器人:ID / tabhost
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT>
    <的LinearLayout

        机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT
        >

        <的FrameLayout
            机器人:ID =@机器人:ID / tabcontent
            机器人:layout_width =WRAP_CONTENT
            机器人:layout_height =FILL_PARENT
            机器人:layout_weight =1>

            <包括布局=@布局/ filter_wizard/>
            <包括布局=@布局/ filter_wizard/>
            <包括布局=@布局/ filter_wizard/>
            <包括布局=@布局/ filter_wizard/>

            < /的FrameLayout>

             < TabWidget
            机器人:后台=#75ffffff
            机器人:ID =@机器人:ID /标签
            机器人:layout_width =WRAP_CONTENT机器人:方向=垂直
            机器人:layout_height =FILL_PARENT机器人:layout_weight =0/>



    < / LinearLayout中>
< / TabHost>
 

解决方案

这是我如何设置的 TabHost 的显示在屏幕左侧的选项卡,用卡垂直堆叠。

一个需要设置2个不同的布局活动,一个在纵向(正常)模式下,一个在横向模式。这意味着到的没有的使用TabActivity。

我复制使用的 TabActivity 的布局到自己的项目,并把它称为main_view.xml(存储在RES /布局)。在这里,它是:

 < TabHost的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
         机器人:ID =@ + ID / tabHost
         机器人:layout_width =match_parent
         机器人:layout_height =match_parent>
    <的LinearLayout机器人:方向=垂直
                  机器人:layout_width =match_parent
                  机器人:layout_height =match_parent>
        < TabWidget机器人:ID =@机器人:ID /标签
                   机器人:layout_height =WRAP_CONTENT
                   机器人:layout_width =match_parent
                   机器人:layout_weight =0/>
        <的FrameLayout机器人:ID =@机器人:ID / tabcontent
                     机器人:layout_width =match_parent
                     机器人:layout_height =0dip
                     机器人:layout_weight =1/>
    < / LinearLayout中>
< / TabHost>
 

我们必须重用的Andr​​oid IDS的标签 tabcontent 的。

在的风景,我通过反向布局的高度/宽度属性对所有控件和的LinearLayout 的方向设置为横向(改变这个的 TabWidget 的FrameLayout 的必须是彼此相邻,水平方向)。下面是结果,到res /布局的土地,也被称为main_view.xml:

 < TabHost的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
           机器人:ID =@ + ID / tabHost
           机器人:layout_width =match_parent
           机器人:layout_height =match_parent>
    <的LinearLayout机器人:方向=横向
                  机器人:layout_width =match_parent
                  机器人:layout_height =match_parent>
        < TabWidget机器人:ID =@机器人:ID /标签
                   机器人:layout_height =match_parent
                   机器人:layout_width =WRAP_CONTENT
                   机器人:layout_weight =0/>
        <的FrameLayout机器人:ID =@机器人:ID / tabcontent
                     机器人:layout_height =match_parent
                     机器人:layout_width =0dip
                     机器人:layout_weight =1/>
    < / LinearLayout中>
< / TabHost>
 

请注意,如果你想在右边的选项卡,你把的 TabWidget 的后的的FrameLayout 的在上面的XML。

TabWidget 的本身就是一个的的LinearLayout 的。请注意,我并​​没有设置XML的方向。这是因为 TabWidget 的做它自己的code(是的,这是硬codeD)。为了解决这个问题,就必须重新设置code的方向。这里是我在我的活动的OnCreate做了

 的setContentView(R.layout.main_view);

最后TabHost tabHost =(TabHost)findViewById(R.id.tabHost);
tabHost.setup();

资源RES = getResources();
配置CFG = res.getConfiguration();
布尔HOR = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE;

如果(横){
    TabWidget TW = tabHost.getTabWidget();
    tw.setOrientation(LinearLayout.VERTICAL);
}
 

由于TabHost通过创建的的setContentView 的,必须调用其设置明确的方法。

通常的方式来创建一个标签是调用:

  tabHost.addTab(tabHost.newTabSpec(标签名)setIndicator(标题,图标).setContent(...)。);
 

setIndicator 的方法,取一个标题字符串和绘制作为参数,创建一个布局只适用于肖像模式。一个人创造了自己的看法,并给它的 setIndicator 的。这足以复制的 TabSpec.LabelAndIconIndicatorStrategy.createIndicatorView 的code:

 私人查看createIndicatorView(TabHost tabHost,CharSequence的标签,可绘制图标){

       LayoutInflater充气=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

       查看tabIndicator = inflater.inflate(R.layout.tab_indicator,
               tabHost.getTabWidget(),//选项卡插件是父
               假); //没有充气PARAMS

       最后的TextView电视=(TextView中)tabIndicator.findViewById(R.id.title);
       tv.setText(标签);

       最后ImageView的ICONVIEW =(ImageView的)tabIndicator.findViewById(R.id.icon);
       iconView.setImageDrawable(图标);

       返回tabIndicator;
   }
 

与原来的谷歌code不同的是,视图布局本身, TextView的的和的 ImageView的的ID是从我们自己的应用程序,而不是机器人内部标识。

有关肖像模式下,我们可以重复使用的Andr​​oid的tab_indicator.xml,我们存储在RES /布局:

 < RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =0dip
    机器人:layout_height =64dip
    机器人:layout_weight =1
    机器人:layout_marginLeft = -  3dip
    机器人:layout_marginRight = -  3dip
    机器人:方向=垂直
    机器人:背景=@可绘制/ tab_indicator>

    < ImageView的机器人:ID =@ + ID /图标
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_centerHorizo​​ntal =真
    />

    < TextView的机器人:ID =@ + ID /标题
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_alignParentBottom =真
        机器人:layout_centerHorizo​​ntal =真
        风格=机器人:ATTR / tabWidgetStyle
    />

< / RelativeLayout的>
 

再次,这是与原始的XML机器人,除了标识。对于景观的版本,我们需要再次反转布局width和height属性。这让我们在RES /布局土地:

 < RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =64dip
    机器人:layout_height =0dip
    机器人:layout_weight =1
    机器人:layout_marginTop = -  3dip
    机器人:layout_marginBottom = -  3dip
    机器人:方向=垂直
    机器人:背景=@可绘制/ tab_indicator>

    < ImageView的机器人:ID =@ + ID /图标
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_centerHorizo​​ntal =真
    />

    < TextView的机器人:ID =@ + ID /标题
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_alignParentBottom =真
        机器人:layout_centerHorizo​​ntal =真
        风格=机器人:ATTR / tabWidgetStyle
    />
< / RelativeLayout的>
 

(我改变了marginLeft和marginRight到marginTop和marginBottom,但我并不确定它是有益的)

这些最后一个XML文件引用@可绘制/ tab_indicator,所以我们需要从Android源$ C ​​$ C,以及绘制/ tab_selected.9.png,绘制/ tab_unselected.9.png,绘制/ tab_focus复制。 9.png。

现在创建一个标签就变成​​了:

  tabHost.addTab(tabHost.newTabSpec(AllTabName)
                .setIndicator(createIndicatorView(tabHost,分页标题图标)))
                .setContent(本));
 

编辑:一个示范项目,请访问:<一href="https://skydrive.live.com/?cid=1e771dcd1c382f9c&sc=documents&id=1E771DCD1C382F9C!284#">VerticalTabHost在SkyDrive上

My app has a tabhost with four tabs, and now I'm trying to make nice layouts for landscape mode. In order to make use of additional horizontal space I want to put TabWidget at the right side of the screen, and of cource all tabs must be one under another (like in a column). But when switching to landscape mode all tabs get aligned in a row, it looks quite ugly. How to fix that?

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <LinearLayout

        android:layout_width="fill_parent"
        android:layout_height="fill_parent" 
        >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_weight="1">

            <include layout="@layout/filter_wizard"/>
            <include layout="@layout/filter_wizard"/>
            <include layout="@layout/filter_wizard"/>
            <include layout="@layout/filter_wizard"/>

            </FrameLayout>

             <TabWidget
            android:background="#75ffffff"
            android:id="@android:id/tabs"
            android:layout_width="wrap_content" android:orientation="vertical" 
            android:layout_height="fill_parent" android:layout_weight="0" />



    </LinearLayout>
</TabHost>

解决方案

This is how I set up the TabHost to display the tabs on the left of the screen, with tabs vertically stacked.

One needs to set up 2 different layouts for the activity, one in portrait ("normal") mode, one in landscape mode. This implies to not use TabActivity.

I copied the layout used by TabActivity into my own project and called it main_view.xml (stored in res/layout). Here it is:

<TabHost xmlns:android="http://schemas.android.com/apk/res/android" 
         android:id="@+id/tabHost"
         android:layout_width="match_parent" 
         android:layout_height="match_parent">
    <LinearLayout android:orientation="vertical"
                  android:layout_width="match_parent" 
                  android:layout_height="match_parent">
        <TabWidget android:id="@android:id/tabs"
                   android:layout_height="wrap_content" 
                   android:layout_width="match_parent"
                   android:layout_weight="0" />
        <FrameLayout android:id="@android:id/tabcontent"
                     android:layout_width="match_parent" 
                     android:layout_height="0dip"
                     android:layout_weight="1"/>
    </LinearLayout>
</TabHost>

One must reuse the Android ids tabs and tabcontent.

In landscape, I changed this by inverting the layout height/width attributes for all controls and setting the orientation of LinearLayout to horizontal (the TabWidget and FrameLayout must be next to each other, horizontally). Here is the result, in res/layout-land, also called main_view.xml:

<TabHost   xmlns:android="http://schemas.android.com/apk/res/android" 
           android:id="@+id/tabHost"
           android:layout_width="match_parent" 
           android:layout_height="match_parent">
    <LinearLayout android:orientation="horizontal"
                  android:layout_width="match_parent" 
                  android:layout_height="match_parent">
        <TabWidget android:id="@android:id/tabs" 
                   android:layout_height="match_parent" 
                   android:layout_width="wrap_content"
                   android:layout_weight="0" />
        <FrameLayout android:id="@android:id/tabcontent"
                     android:layout_height="match_parent" 
                     android:layout_width="0dip"
                     android:layout_weight="1"/>
    </LinearLayout>
</TabHost>

Note that if you want the tabs on the right, you put the TabWidget after the FrameLayout in the XML above.

TabWidget is itself a LinearLayout. Notice that I did not set the orientation in XML. This because TabWidget does it in its own code (yes, it is hard-coded). To counter this, one has to re-set the orientation in code. Here is how I did it in my activity's oncreate

setContentView(R.layout.main_view);

final TabHost tabHost = (TabHost) findViewById(R.id.tabHost);
tabHost.setup();

Resources res = getResources();
Configuration cfg = res.getConfiguration();
boolean hor = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE;

if (hor) {
    TabWidget tw = tabHost.getTabWidget();
    tw.setOrientation(LinearLayout.VERTICAL);
}

As TabHost is created through setContentView, one must call its setup method explicitly.

The usual way to create a tab is to call:

tabHost.addTab(tabHost.newTabSpec("tab name").setIndicator("title", icon).setContent(...));

The setIndicator method, taking a title string and a drawable as parameters, creates a layout that is valid only in portrait mode. One has to create one's own view and give it to setIndicator. It is enough to copy the TabSpec.LabelAndIconIndicatorStrategy.createIndicatorView code:

   private View createIndicatorView(TabHost tabHost, CharSequence label, Drawable icon) {

       LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

       View tabIndicator = inflater.inflate(R.layout.tab_indicator,
               tabHost.getTabWidget(), // tab widget is the parent
               false); // no inflate params

       final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
       tv.setText(label);

       final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
       iconView.setImageDrawable(icon);

       return tabIndicator;
   }

The difference with the original Google code is that the view layout itself, the TextView and ImageView ids are from our own application, not Android internal ids.

For portrait mode, we can reuse the tab_indicator.xml from Android, that we store in res/layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dip"
    android:layout_height="64dip"
    android:layout_weight="1"
    android:layout_marginLeft="-3dip"
    android:layout_marginRight="-3dip"
    android:orientation="vertical"
    android:background="@drawable/tab_indicator">

    <ImageView android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
    />

    <TextView android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        style="?android:attr/tabWidgetStyle"
    />

</RelativeLayout>

Again, this is identical to the original Android XML, except for the ids. For a landscape-friendly version, we need to invert again the layout width and height attributes. Which gives us in res/layout-land:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="64dip"
    android:layout_height="0dip"
    android:layout_weight="1"
    android:layout_marginTop="-3dip"
    android:layout_marginBottom="-3dip"
    android:orientation="vertical"
    android:background="@drawable/tab_indicator">

    <ImageView android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
    />

    <TextView android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        style="?android:attr/tabWidgetStyle"
    />
</RelativeLayout>

(I changed marginLeft and marginRight to marginTop and marginBottom but am not that sure that it is helpful)

These last XML files reference @drawable/tab_indicator, so we need to copy it from Android source code, as well as drawable/tab_selected.9.png, drawable/tab_unselected.9.png, drawable/tab_focus.9.png.

Now creating a tab becomes:

tabHost.addTab(tabHost.newTabSpec(AllTabName)
                .setIndicator(createIndicatorView(tabHost, "tab title", icon)))
                .setContent(this));

EDIT: a demo project is available at: VerticalTabHost on SkyDrive

这篇关于机器人:方向=&QUOT垂直的QUOT;对于TabWidget不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆