前言
爲了更好的開發Android應用程序,除了熟練掌握基本的UI組件和API外,還需要掌握一些技巧,而這些技巧可以通過閱讀一些代碼來提高,本系列將與大家分享一些新浪微博佈局方面的收穫,歡迎交流!
版本
新浪微博 weibo_10235010.apk
正文
一、效果圖
紅色部分是本文要實現的目標。
二、實現maintabs.xml
1. <?xml version="1.0" encoding="UTF-8"?>
2. <TabHost android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent"
3. xmlns:android="http://schemas.android.com/apk/res/android">
4. <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
5. <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="0.0dip" android:layout_weight="1.0" />
6. <TabWidget android:id="@android:id/tabs" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.0" />
7. <RadioGroup android:gravity="center_vertical" android:layout_gravity="bottom" android:orientation="horizontal" android:id="@id/main_radio" android:background="@drawable/maintab_toolbar_bg" android:layout_width="fill_parent" android:layout_height="wrap_content">
8. <RadioButton android:text="@string/main_home" android:checked="true" android:id="@+id/radio_button0" android:layout_marginTop="2.0dip" android:drawableTop="@drawable/icon_1_n" style="@style/main_tab_bottom" />
9. <RadioButton android:id="@+id/radio_button1" android:layout_marginTop="2.0dip" android:text="@string/main_news" android:drawableTop="@drawable/icon_2_n" style="@style/main_tab_bottom" />
10. <RadioButton android:id="@+id/radio_button2" android:layout_marginTop="2.0dip" android:text="@string/main_my_info" android:drawableTop="@drawable/icon_3_n" style="@style/main_tab_bottom" />
11. <RadioButton android:id="@+id/radio_button3" android:layout_marginTop="2.0dip" android:text="@string/menu_search" android:drawableTop="@drawable/icon_4_n" style="@style/main_tab_bottom" />
12. <RadioButton android:id="@+id/radio_button4" android:layout_marginTop="2.0dip" android:text="@string/more" android:drawableTop="@drawable/icon_5_n" style="@style/main_tab_bottom" />
13. </RadioGroup>
14. </LinearLayout>
15. </TabHost>
styles.xml
1. <style name="main_tab_bottom">
2. <item name="android:textSize">@dimen/bottom_tab_font_size</item>
3. <item name="android:textColor">#ffffffff</item>
4. <item name="android:ellipsize">marquee</item>
5. <item name="android:gravity">center_horizontal</item>
6. <item name="android:background">@drawable/home_btn_bg</item>
7. <item name="android:paddingTop">@dimen/bottom_tab_padding_up</item>
8. <item name="android:layout_width">fill_parent</item>
9. <item name="android:layout_height">wrap_content</item>
10. <item name="android:button">@null</item>
11. <item name="android:singleLine">true</item>
12. <item name="android:drawablePadding">@dimen/bottom_tab_padding_drawable</item>
13. <item name="android:layout_weight">1.0</item>
14. </style>
home_btn_bg.xml
1. <selector
2. xmlns:android="http://schemas.android.com/apk/res/android">
3. <item android:state_focused="true" android:state_enabled="true" android:state_pressed="false" android:drawable="@drawable/home_btn_bg_s" />
4. <item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/home_btn_bg_s" />
5. <item android:state_enabled="true" android:state_checked="true" android:drawable="@drawable/home_btn_bg_d" />
6. <item android:drawable="@drawable/transparent" />
7. </selector>
代碼說明:
1. 需要注意的是他這裏把TabWidget的Visibility設置成了gone!也就是默認難看的風格不見了: ,取而代之的是5個帶風格的單選按鈕.
2. 注意爲單選按鈕設置的style,其中最重要的是爲其background設置了home_btn_bg.xml,也就是自定義了選中效果。
Java文件
1. public class MainTabActivity extends TabActivity implements
2. OnCheckedChangeListener {
3.
4. private TabHost mHost;
5. private Intent mMBlogIntent;
6. private Intent mMoreIntent;
7. private Intent mInfoIntent;
8. private Intent mSearchIntent;
9. private Intent mUserInfoIntent;
10.
11. @Override
12. protected void onCreate(Bundle savedInstanceState) {
13. super.onCreate(savedInstanceState);
14. requestWindowFeature(Window.FEATURE_NO_TITLE);
15. setContentView(R.layout.maintabs);
16.
17. // ~~~~~~~~~~~~ 初始化
18. this.mMBlogIntent = new Intent(this, HomeListActivity.class);
19. this.mSearchIntent = new Intent(this, SearchSquareActivity.class);
20. this.mInfoIntent = new Intent(this, MessageGroup.class);
21. this.mUserInfoIntent = new Intent(this, MyInfoActivity.class);
22. this.mMoreIntent = new Intent(this, MoreItemsActivity.class);
23.
24. initRadios();
25.
26. setupIntent();
27. }
28.
29. /**
30. * 初始化底部按鈕
31. */
32. private void initRadios() {
33. ((RadioButton) findViewById(R.id.radio_button0)).setOnCheckedChangeListener(this);
34. ((RadioButton) findViewById(R.id.radio_button1)).setOnCheckedChangeListener(this);
35. ((RadioButton) findViewById(R.id.radio_button2)).setOnCheckedChangeListener(this);
36. ((RadioButton) findViewById(R.id.radio_button3)).setOnCheckedChangeListener(this);
37. ((RadioButton) findViewById(R.id.radio_button4)).setOnCheckedChangeListener(this);
38. }
39.
40. /**
41. * 切換模塊
42. */
43. @Override
44. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
45. if (isChecked) {
46. switch (buttonView.getId()) {
47. case R.id.radio_button0:
48. this.mHost.setCurrentTabByTag("mblog_tab");
49. break;
50. case R.id.radio_button1:
51. this.mHost.setCurrentTabByTag("message_tab");
52. break;
53. case R.id.radio_button2:
54. this.mHost.setCurrentTabByTag("userinfo_tab");
55. break;
56. case R.id.radio_button3:
57. this.mHost.setCurrentTabByTag("search_tab");
58. break;
59. case R.id.radio_button4:
60. this.mHost.setCurrentTabByTag("more_tab");
61. break;
62. }
63. }
64. }
65.
66. private void setupIntent() {
67. this.mHost = getTabHost();
68. TabHost localTabHost = this.mHost;
69.
70. localTabHost.addTab(buildTabSpec("mblog_tab", R.string.main_home,
71. R.drawable.icon_1_n, this.mMBlogIntent));
72.
73. localTabHost.addTab(buildTabSpec("message_tab", R.string.main_news,
74. R.drawable.icon_2_n, this.mInfoIntent));
75.
76. localTabHost.addTab(buildTabSpec("userinfo_tab", R.string.main_my_info,
77. R.drawable.icon_3_n, this.mUserInfoIntent));
78.
79. localTabHost.addTab(buildTabSpec("search_tab", R.string.menu_search,
80. R.drawable.icon_4_n, this.mSearchIntent));
81.
82. localTabHost.addTab(buildTabSpec("more_tab", R.string.more,
83. R.drawable.icon_5_n, this.mMoreIntent));
84.
85. }
86.
87. private TabHost.TabSpec buildTabSpec(String tag, int resLabel, int resIcon,
88. final Intent content) {
89. return this.mHost
90. .newTabSpec(tag)
91. .setIndicator(getString(resLabel),
92. getResources().getDrawable(resIcon))
93. .setContent(content);
94. }
代碼說明
1. 由於TabWidget被隱藏,所以相關的事件也會無效,這裏取巧用RadioGroup與RadioButton的特性來處理切換,然後監聽事件調用setCurrentTabByTag來切換Activity。
2. 注意即使TabWidget被隱藏,也要爲其設置indicator,否則會保持。
三、總結
在這之前如果要做這種效果我恐怕第一時間就會想到用ActivityGroup來做,主要是因爲TabHost的TabWidget非常難看,用起 來也不方便。其實從源碼可以看出,TabActivity也是繼承自ActivityGroup,這裏結合了單選按鈕和TabHost,各取其長,有時間 可以專門寫一個這樣的自定義控件:)