2010-11-10 29 views
12

Ứng dụng của tôi có tabhost với bốn tab và giờ tôi đang cố tạo bố cục đẹp cho chế độ ngang. Để sử dụng không gian ngang bổ sung, tôi muốn đặt TabWidget ở phía bên phải của màn hình và tất cả các tab đều phải nằm dưới một tab khác (như trong một cột). Nhưng khi chuyển sang chế độ ngang, tất cả các tab được căn chỉnh trong một hàng, nó trông khá xấu xí. Cách khắc phục điều đó?android: orientation = "vertical" không hoạt động đối với TabWidget

Screenshot

<?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> 
+0

Tôi đã thực sự cố gắng nhận được các tab dọc để làm việc bằng cách sử dụng tabhost/tabwidget. Tôi chưa bao giờ làm việc đó. có thể bạn sẽ phải cuộn chế độ xem tab của riêng mình để thực hiện. – Falmarri

+0

Tôi đồng ý với Falmarri. Điều này cần được thực hiện trong bố cục tùy chỉnh của riêng bạn. TabHost không phải là rất tốt đẹp khi cố gắng tùy chỉnh nó để nhìn tốt cho cả chân dung và phong cảnh. –

+0

Falmarri, Austyn Mahoney, cảm ơn lời giải thích. Có cách nào khả thi để thực hiện tabwidget riêng? – aiboman

Trả lời

4

TabHost không hỗ trợ các thuộc tính định hướng và các tab chỉ có thể được sử dụng theo chiều ngang.

+0

Cảm ơn rất nhiều, Romain Guy – aiboman

+0

Cảm ơn rất nhiều người, Thông tin hữu ích 1+ cho điều đó. – Harshad

21

Đây là cách tôi thiết lập Máy chủ tab để hiển thị các tab ở bên trái màn hình, với các tab được xếp chồng lên nhau theo chiều dọc.

Một trong những nhu cầu để thiết lập 2 bố trí khác nhau cho hoạt động, một trong chế độ chân dung ("bình thường"), một trong chế độ phong cảnh. Điều này ngụ ý rằng không phải là sử dụng TabActivity.

Tôi đã sao chép bố cục được sử dụng bởi TabActivity vào dự án của riêng tôi và gọi nó là main_view.xml (được lưu trữ trong res/layout). Ở đây là:

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

Người ta phải tái sử dụng id Android tabtabcontent.

Trong phong cảnh, tôi đã thay đổi điều này bằng cách đảo ngược chiều cao bố trí/thuộc tính chiều rộng cho tất cả các điều khiển và thiết lập các định hướng của LinearLayout để ngang (các TabWidgetFrameLayout phải bên cạnh nhau, theo chiều ngang). Dưới đây là kết quả, trong res/layout-đất, hay còn gọi là 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> 

Lưu ý rằng nếu bạn muốn các tab ở bên phải, bạn đặt TabWidget sau FrameLayout trong XML ở trên.

TabWidget chính nó là LinearLayout. Lưu ý rằng tôi đã không đặt định hướng trong XML. Điều này bởi vì TabWidget thực hiện theo mã riêng của mình (có, mã được mã hóa cứng). Để chống lại điều này, người ta phải thiết lập lại định hướng trong mã. Đây là cách tôi đã làm nó trong 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); 
} 

Như TabHost được tạo ra thông qua setContentView, người ta phải gọi phương thức thiết lập của nó hoạt động của tôi một cách rõ ràng.

Cách thông thường để tạo ra một tab là gọi:

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

Các setIndicator phương pháp, tham gia một chuỗi tiêu đề và đối tượng vẽ được như các thông số, tạo ra một bố cục mà chỉ có hiệu lực trong chế độ chân dung. Người ta phải tạo chế độ xem của riêng mình và đưa nó đến setIndicator.Nó là đủ để sao chép TabSpec.LabelAndIconIndicatorStrategy.createIndicatorView mã:

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

Sự khác biệt với mã Google ban đầu là cách bố trí điểm riêng của mình, TextViewImageView id là từ ứng dụng riêng của chúng tôi , không phải là id nội bộ của Android.

Đối với chế độ chân dung, chúng ta có thể tái sử dụng các tab_indicator.xml từ Android, mà chúng tôi lưu trữ trong 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> 

Một lần nữa, đây là giống với XML Android gốc, ngoại trừ cho các id. Đối với một phiên bản thân thiện với cảnh quan, chúng tôi cần đảo ngược lại các thuộc tính chiều rộng và chiều cao bố cục. Mang đến cho chúng ta trong res/layout-đất:

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

(Tôi đã thay đổi marginLeft và marginRight để marginTop và marginBottom nhưng tôi không phải là chắc chắn rằng nó là hữu ích)

Những tập tin XML cuối cùng tham khảo @ drawable/tab_indicator , vì vậy chúng tôi cần phải sao chép nó từ mã nguồn Android, cũng như drawable/tab_selected.9.png, drawable/tab_unselected.9.png, drawable/tab_focus.9.png.

Bây giờ tạo một tab trở thành:

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

EDIT: một dự án trình diễn đã có sẵn tại địa chỉ: VerticalTabHost on SkyDrive

+0

tôi làm như bạn nói, nhưng khi màn hình nằm ngang, tôi nhận được kết quả là màn hình không thể hiển thị tabWidget, chỉ hiển thị tabContent – pengwang

+0

Bạn có cách nào để xuất bản dự án của mình không? Tôi có thể có một cái nhìn và so sánh với tôi. – Timores

+0

bạn có thể có email không, tôi có thể gửi email cho bạn, cảm ơn bạn – pengwang

3

Vì vậy, chỉ quan trọng nghĩ rằng bạn phải làm là thế này:

getTabWidget().setOrientation(LinearLayout.VERTICAL); 

TabWidget đã mã cứng setOrientation(LinearLayout.HORIZONTAL); trong phương thức initTabWidget(). Tôi không biết tại sao.

+1

Khi tôi làm điều đó, TabWidget của tôi biến mất. – Davor

Các vấn đề liên quan