横タブ?

結構簡単にできちゃいました。
タブのつまみ部分は TabWidget というクラスです。
TabWidget のソースをみてみればわかりますが、このクラスは LinearLayout を継承しています。
つまり、各つまみは LinearLayout の子要素ということになります。
まずコンストラクタをみると
- 75 public TabWidget(Context context, AttributeSet attrs, int defStyle) {
- 76 super(context, attrs);
- 77
- 78 TypedArray a =
- 79 context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.TabWidget,
- 80 defStyle, 0);
- 81
- 82 mDrawBottomStrips = a.getBoolean(R.styleable.TabWidget_tabStripEnabled, true);
- 83 mDividerDrawable = a.getDrawable(R.styleable.TabWidget_divider);
- 84 mLeftStrip = a.getDrawable(R.styleable.TabWidget_tabStripLeft);
- 85 mRightStrip = a.getDrawable(R.styleable.TabWidget_tabStripRight);
- 86
- 87 a.recycle();
- 88
- 89 initTabWidget();
- 90 }
initTabWdiget() があやしい。。。
- 111 private void initTabWidget() {
- 112 setOrientation(LinearLayout.HORIZONTAL);
- 113 mGroupFlags |= FLAG_USE_CHILD_DRAWING_ORDER;
- 114
- 115 final Context context = mContext;
- 116 final Resources resources = context.getResources();
- 117
- 118 if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
- 119 // Donut apps get old color scheme
- 120 if (mLeftStrip == null) {
- 121 mLeftStrip = resources.getDrawable(
- 122 com.android.internal.R.drawable.tab_bottom_left_v4);
- 123 }
- 124 if (mRightStrip == null) {
- 125 mRightStrip = resources.getDrawable(
- 126 com.android.internal.R.drawable.tab_bottom_right_v4);
- 127 }
- 128 } else {
- 129 // Use modern color scheme for Eclair and beyond
- 130 if (mLeftStrip == null) {
- 131 mLeftStrip = resources.getDrawable(
- 132 com.android.internal.R.drawable.tab_bottom_left);
- 133 }
- 134 if (mRightStrip == null) {
- 135 mRightStrip = resources.getDrawable(
- 136 com.android.internal.R.drawable.tab_bottom_right);
- 137 }
- 138 }
- 139
- 140 // Deal with focus, as we don't want the focus to go by default
- 141 // to a tab other than the current tab
- 142 setFocusable(true);
- 143 setOnFocusChangeListener(this);
- 144 }
- 112 setOrientation(LinearLayout.HORIZONTAL);
でがっつり horizontal 指定してますね。
なので、TabWdiget を継承した独自クラスを作って、そのコンストラクタで super() を読んだ後に
setOrientation(LinearLayout.VERTICAL);
を呼んであげます。
これだけではダメなんです。
この TabWidget (つまりレイアウト的には LinearLayout) に子要素を追加する部分もカスタマイズする必要があります。
- 385 @Override
- 386 public void addView(View child) {
- 387 if (child.getLayoutParams() == null) {
- 388 final LinearLayout.LayoutParams lp = new LayoutParams(
- 389 0,
- 390 ViewGroup.LayoutParams.MATCH_PARENT, 1.0f);
- 391 lp.setMargins(0, 0, 0, 0);
- 392 child.setLayoutParams(lp);
- 393 }
- 394
- 395 // Ensure you can navigate to the tab with the keyboard, and you can touch it
- 396 child.setFocusable(true);
- 397 child.setClickable(true);
- 398
- 399 // If we have dividers between the tabs and we already have at least one
- 400 // tab, then add a divider before adding the next tab.
- 401 if (mDividerDrawable != null && getTabCount() > 0) {
- 402 ImageView divider = new ImageView(mContext);
- 403 final LinearLayout.LayoutParams lp = new LayoutParams(
- 404 mDividerDrawable.getIntrinsicWidth(),
- 405 LayoutParams.MATCH_PARENT);
- 406 lp.setMargins(0, 0, 0, 0);
- 407 divider.setLayoutParams(lp);
- 408 divider.setBackgroundDrawable(mDividerDrawable);
- 409 super.addView(divider);
- 410 }
- 411 super.addView(child);
- 412
- 413 // TODO: detect this via geometry with a tabwidget listener rather
- 414 // than potentially interfere with the view's listener
- 415 child.setOnClickListener(new TabClickListener(getTabCount() - 1));
- 416 child.setOnFocusChangeListener(this);
- 417 }
LinearLayout に子要素を追加するメソッドの addView で
- 387 if (child.getLayoutParams() == null) {
- 388 final LinearLayout.LayoutParams lp = new LayoutParams(
- 389 0,
- 390 ViewGroup.LayoutParams.MATCH_PARENT, 1.0f);
- 391 lp.setMargins(0, 0, 0, 0);
- 392 child.setLayoutParams(lp);
- 393 }
と、width に 0, height に ViewGroup.LayoutParams.MATCH_PARENT が指定されています。
これを反対にします。
ということで完成コードはこんな感じ。
- public class SideTabWidget extends TabWidget {
- public SideTabWidget(Context context) {
- this(context, null);
- }
- public SideTabWidget(Context context, AttributeSet attrs) {
- super(context, attrs);
- setOrientation(LinearLayout.VERTICAL);
- }
- @Override
- public void addView(View child) {
- if (child.getLayoutParams() == null) {
- final LinearLayout.LayoutParams lp = new LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f);
- lp.setMargins(0, 0, 0, 0);
- child.setLayoutParams(lp);
- }
- super.addView(child);
- }
- }
- <?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"
- android:paddingBottom="10dip" >
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <FrameLayout
- android:id="@android:id/tabcontent"
- android:layout_width="0dip"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:background="@color/basic_white2"
- android:padding="10dip"
- />
- <layoutbook.example.sidetab.SideTabWidget
- android:orientation="vertical"
- android:id="@android:id/tabs"
- android:layout_width="60dip"
- android:layout_height="fill_parent" />
- </LinearLayout>
- </TabHost>
0 件のコメント:
コメントを投稿