- 首页 »
- 资源下载
- »
- Android培训中心
- »
- 技术文章
android UI进阶之仿iphone的tab效果(二)
[来源] 达内 [编辑] 达内 [时间]2012-09-17
今天把这个仿iphone效果的tab写完,这个例子参考国外rolle3k共享的代码,感谢rolle3k。
上篇博客我们写了一个Itab类,介绍了背景的绘制和简单的一个图的贴图方法。我们继续来完成Itab这个类,同时把他放到MainAcitvity(继承Activity)这个类内部,这样,整个程序只需一个类就可以了。(上篇博客例子运行需要再建一个Activity的子类来作为lanucher)。废话不多说了,看看代码
[java] view plaincopy
1. public static class iTab extends View 
2. { 
3. private Paint mPaint;//背景画笔 
4. private Paint mActiveTextPaint;//选中 
5. private Paint mInactiveTextPaint;//未选中 
6. private ArrayList<TabMember> mTabMembers;//tab成员 
7. private int mActiveTab; 
8. private OnTabClickListener mOnTabClickListener = null; 
9. 
10. public iTab( Context context, AttributeSet attrs ) //构造器,在里面初始化画笔 
11. { 
12. super(context, attrs); 
13. 
14. mTabMembers = new ArrayList<MainActivity.iTab.TabMember>( ); 
15. 
16. mPaint = new Paint( ); 
17. mActiveTextPaint = new Paint( ); 
18. mInactiveTextPaint = new Paint( ); 
19. 
20. mPaint.setStyle( .FILL ); 
21. mPaint.setColor( 0xFFFFFF00 ); 
22. mPaint.setAntiAlias(true); 
23. 
24. mActiveTextPaint.setTextAlign( ); 
25. mActiveTextPaint.setTextSize( 12 ); 
26. mActiveTextPaint.setColor( 0xFFFFFFFF ); 
27. mActiveTextPaint.setAntiAlias(true); 
28. 
29. 
30. mInactiveTextPaint.setTextAlign( ); 
31. mInactiveTextPaint.setTextSize( 12 ); 
32. mInactiveTextPaint.setColor( 0xFF999999 ); 
33. mInactiveTextPaint.setAntiAlias(true); 
34. mActiveTab = 0; 
35. 
36. } 
37. 
38. @Override 
39. protected void onDraw( Canvas canvas ) 
40. { 
41. super.onDraw( canvas ); 
42. 
43. Rect r = new Rect( ); 
44. this.getDrawingRect( r ); 
45. 
46. // 计算每个标签能使用多少像素 
47. int singleTabWidth = r.right / ( mTabMembers.size( ) != 0 ? mTabMembers.size( ) : 1 ); 
48. 
49. 
50. // 绘制背景 
51. canvas.drawColor( 0xFF000000 ); 
52. mPaint.setColor( 0xFF434343 ); 
53. canvas.drawLine( r.left, + 1, r.right, + 1, mPaint ); 
54. 
55. int color = 46; 
56. 
57. for( int i = 0; i < 24; i++ ) 
58. { 
59. mPaint.setARGB( 255, color, color, color ); 
60. canvas.drawRect( r.left, + i + 1, r.right, + i + 2, mPaint ); 
61. color--; 
62. } 
63. // 绘制每一个tab 
64. for( int i = 0; i < mTabMembers.size( ); i++ ) 
65. { 
66. TabMember tabMember = mTabMembers.get( i ); 
67. 
68. Bitmap icon = BitmapFactory.decodeResource( getResources( ), tabMember.getIconResourceId( ) ); 
69. Bitmap iconColored = Bitmap.createBitmap( icon.getWidth(), icon.getHeight(), Bitmap.Config.ARGB_8888 ); 
70. Paint p = new Paint( Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 
71. Canvas iconCanvas = new Canvas( ); 
72. iconCanvas.setBitmap( iconColored ); 
73. 
74. if( mActiveTab == i )//为已选中的tab绘制一个白蓝的渐变色,未选中的绘制一个白灰的渐变色 
75. { 
76. p.setShader( new LinearGradient( 0, 0, icon.getWidth(), icon.getHeight(), 
77. 0xFFFFFFFF, 0xFF54C7E1, Shader.TileMode.CLAMP ) ); 
78. } 
79. else { 
80. p.setShader( new LinearGradient( 0, 0, icon.getWidth(), icon.getHeight(), 
81. 0xFFA2A2A2, 0xFF5F5F5F, Shader.TileMode.CLAMP ) ); 
82. } 
83. 
84. iconCanvas.drawRect( 0, 0, icon.getWidth( ), icon.getHeight( ), p ); 
85. 
86. for( int x = 0; x < icon.getWidth(); x++ ) 
87. { 
88. for( int y = 0; y < icon.getHeight(); y++ ) 
89. { 
90. if( ( icon.getPixel(x, y) & 0xFF000000 ) == 0 ) 
91. { 
92. iconColored.setPixel( x, y, 0x00000000 ); 
93. } 
94. } 
95. } 
96. 
97. // 计算tab图片的位置 
98. int tabImgX = singleTabWidth * i + ( singleTabWidth / 2 - icon.getWidth( ) / 2 ); 
99. 
100. // 绘制tab图片 选中的和未选中的 
101. if( mActiveTab == i ) 
102. { 
103. mPaint.setARGB( 37, 255, 255, 255 ); 
104. canvas.drawRoundRect( new RectF( r.left + singleTabWidth * i + 3, + 3, 
105. r.left + singleTabWidth * ( i + 1 ) - 3, r.bottom - 2 ), 5, 5, mPaint ); 
106. canvas.drawBitmap( iconColored, tabImgX , + 5, null ); 
107. canvas.drawText( tabMember.getText( ), 
108. singleTabWidth * i + ( singleTabWidth / 2), r.bottom - 2, mActiveTextPaint ); 
109. } else 
110. { 
111. canvas.drawBitmap( iconColored, tabImgX , + 5, null ); 
112. canvas.drawText( tabMember.getText( ), 
113. singleTabWidth * i + ( singleTabWidth / 2), r.bottom - 2, mInactiveTextPaint ); 
114. } 
115. } 
116. } 
117. /* 
118. * 触摸事件 
119. */ 
120. @Override 
121. public boolean onTouchEvent( MotionEvent motionEvent ) 
122. { 
123. Rect r = new Rect( ); 
124. this.getDrawingRect( r ); 
125. float singleTabWidth = r.right / ( mTabMembers.size( ) != 0 ? mTabMembers.size( ) : 1 ); 
126. 
127. int pressedTab = (int) ( ( motionEvent.getX( ) / singleTabWidth ) - ( motionEvent.getX( ) / singleTabWidth ) % 1 ); 
128. 
129. mActiveTab = pressedTab; 
130. 
131. if( this.mOnTabClickListener != null) 
132. { 
133. this.mOnTabClickListener.onTabClick( mTabMembers.get( pressedTab ).getId( ) ); 
134. } 
135. 
136. this.invalidate(); 
137. 
138. return super.onTouchEvent( motionEvent ); 
139. } 
140. 
141. void addTabMember( TabMember tabMember ) 
142. { 
143. mTabMembers.add( tabMember ); 
144. } 
145. 
146. void setOnTabClickListener( OnTabClickListener onTabClickListener ) 
147. { 
148. mOnTabClickListener = onTabClickListener; 
149. } 
150. 
151. public static class TabMember//处理tab成员 
152. { 
153. protected int mId; 
154. protected String mText; 
155. protected int mIconResourceId; 
156. 
157. TabMember( int Id, String Text, int iconResourceId ) 
158. { 
159. mId = Id; 
160. mIconResourceId = iconResourceId; 
161. mText = Text; 
162. } 
163. 
164. public int getId( ) 
165. { 
166. return mId; 
167. } 
168. 
169. public String getText( ) 
170. { 
171. return mText; 
172. } 
173. 
174. public int getIconResourceId( ) 
175. { 
176. return mIconResourceId; 
177. } 
178. 
179. public void setText( String Text ) 
180. { 
181. mText = Text; 
182. } 
183. 
184. public void setIconResourceId( int iconResourceId ) 
185. { 
186. mIconResourceId = iconResourceId; 
187. } 
188. } 
189. 
190. public static interface OnTabClickListener 
191. { 
192. public abstract void onTabClick( int tabId ); 
193. } 
194. } 
这是MainActivity这个类里面的两个static类,看我写的注释和上篇博客的内容应该都能理解。其中还定义了触摸事件,实现点击tab出现不同布局的效果。接下来我们只需要在我们的layout上添加就可以了,我们继续写一个内部类
[java] view plaincopy
1. public static class iRelativeLayout extends RelativeLayout//注意,还是声明为静态 
2. { 
3. private Paint mPaint; 
4. private Rect mRect; 
5. 
6. public iRelativeLayout( Context context, AttributeSet attrs ) 
7. { 
8. super(context, attrs); 
9. 
10. mRect = new Rect( ); 
11. mPaint = new Paint( ); 
12. 
13. mPaint.setStyle( .FILL_AND_STROKE ); 
14. mPaint.setColor( 0xFFCBD2D8 ); 
15. } 
16. 
17. @Override 
18. protected void onDraw( Canvas canvas ) 
19. { 
20. super.onDraw( canvas ); 
21. canvas.drawColor( 0xFFC5CCD4 ); 
22. 
23. this.getDrawingRect( mRect ); 
24. 
25. for( int i = 0; i < mRect.right; i += 7 )//绘制屏幕背景的纹理效果 
26. { 
27. canvas.drawRect( mRect.left + i, , mRect.left + i + 2, mRect.bottom, mPaint ); 
28. } 
29. } 
30. } 
31. 
32. private static final int TAB_HIGHLIGHT = 1; 
33. private static final int TAB_CHAT = 2; 
34. private static final int TAB_LOOPBACK = 3; 
35. private static final int TAB_REDO = 4; 
36. private iTab mTabs; 
37. private LinearLayout mTabLayout_One; 
38. private LinearLayout mTabLayout_Two; 
39. private LinearLayout mTabLayout_Three; 
40. private LinearLayout mTabLayout_Four; 
41. private LinearLayout mTabLayout_Five; 
42. 
43. @Override 
44. public void onCreate(Bundle savedInstanceState) 
45. { 
46. super.onCreate(savedInstanceState); 
47. setContentView(R.layout.main); 
48. 
49. mTabs = (iTab) this.findViewById( .Tabs ); 
50. mTabLayout_One = (LinearLayout) this.findViewById( .TabLayout_One ); 
51. mTabLayout_Two = (LinearLayout) this.findViewById( .TabLayout_Two ); 
52. mTabLayout_Three = (LinearLayout) this.findViewById( .TabLayout_Three ); 
53. mTabLayout_Four = (LinearLayout) this.findViewById( .TabLayout_Four ); 
54. mTabLayout_Five = (LinearLayout) this.findViewById( .TabLayout_Four );//偷个懒,不写第五个界面啦 
55. 
56. mTabs.addTabMember( new TabMember( TAB_HIGHLIGHT, "精选", R.drawable.jingxuan ) ); 
57. mTabs.addTabMember( new TabMember( TAB_CHAT, "类别", ) ); 
58. mTabs.addTabMember( new TabMember( TAB_LOOPBACK, "25大排行榜", R.drawable.rank ) ); 
59. mTabs.addTabMember( new TabMember( TAB_REDO, "搜索", ) ); 
60. mTabs.addTabMember( new TabMember( TAB_REDO, "更新", ) );//添加tab 
61. 
62. /*初始显示第一个界面*/ 
63. mTabLayout_One.setVisibility( View.VISIBLE ); 
64. mTabLayout_Two.setVisibility( View.GONE ); 
65. mTabLayout_Three.setVisibility( View.GONE ); 
66. mTabLayout_Four.setVisibility( View.GONE ); 
67. 
68. mTabs.setOnTabClickListener( new OnTabClickListener( ) { 
69. @Override 
70. public void onTabClick( int tabId )//实现点击事件 
71. { 
72. if( tabId == TAB_HIGHLIGHT ) 
73. { 
74. mTabLayout_One.setVisibility( View.VISIBLE ); 
75. mTabLayout_Two.setVisibility( View.GONE ); 
76. mTabLayout_Three.setVisibility( View.GONE ); 
77. mTabLayout_Four.setVisibility( View.GONE ); 
78. } else if( tabId == TAB_CHAT ) 
79. { 
80. mTabLayout_One.setVisibility( View.GONE ); 
81. mTabLayout_Two.setVisibility( View.VISIBLE ); 
82. mTabLayout_Three.setVisibility( View.GONE ); 
83. mTabLayout_Four.setVisibility( View.GONE ); 
84. } else if( tabId == TAB_LOOPBACK ) 
85. { 
86. mTabLayout_One.setVisibility( View.GONE ); 
87. mTabLayout_Two.setVisibility( View.GONE ); 
88. mTabLayout_Three.setVisibility( View.VISIBLE ); 
89. mTabLayout_Four.setVisibility( View.GONE ); 
90. } else if( tabId == TAB_REDO ) 
91. { 
92. mTabLayout_One.setVisibility( View.GONE ); 
93. mTabLayout_Two.setVisibility( View.GONE ); 
94. mTabLayout_Three.setVisibility( View.GONE ); 
95. mTabLayout_Four.setVisibility( View.VISIBLE ); 
96. } 
97. } 
98. }); 
99. } 
其中onDraw()方法里面实现了背景的纹理效果,配合xml里面背景色的配置,实现了如下图所示的效果:
是不是非常漂亮呢,剩下的就是在xml里面配置了
[xhtml] view plaincopy
1. <?xml version="1.0" encoding="utf-8"?> 
2. <view xmlns:android="http://schemas.android.com/apk/res/android" 
3. class="com.notice520.MainActivity$iRelativeLayout" 
4. android:orientation="vertical" 
5. android:layout_width="fill_parent" 
6. android:layout_height="fill_parent" 
7. android:background = "#C5CCD4FF" 
8. > 
9. <LinearLayout 
10. android:id = "@+id/TabLayout_One" 
11. android:layout_width = "fill_parent" 
12. android:layout_height = "fill_parent" 
13. android:layout_above = "@+id/Tabs" 
14. > 
15. <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> 
16. <RelativeLayout 
17. android:layout_width = "fill_parent" 
18. android:layout_height = "fill_parent" 
19. android:visibility = "visible" 
20. > 
21. <TextView 
22. android:textColor="@android:color/black" 
23. android:textSize="30sp" 
24. android:layout_width = "wrap_content" 
25. android:layout_height = "wrap_content" 
26. android:text = "春节快乐!!" 
27. /> 
28. </RelativeLayout> 
29. </ScrollView> 
30. </LinearLayout> 
31. 
32. <LinearLayout 
33. android:id = "@+id/TabLayout_Two" 
34. android:layout_width = "fill_parent" 
35. android:layout_height = "fill_parent" 
36. android:layout_above = "@+id/Tabs" 
37. > 
38. <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> 
39. <RelativeLayout 
40. android:layout_width = "fill_parent" 
41. android:layout_height = "fill_parent" 
42. android:visibility = "visible" 
43. android:layout_above = "@+id/Tabs" 
44. > 
45. <Button 
46. android:layout_width = "wrap_content" 
47. android:layout_height = "wrap_content" 
48. android:text = "祝大家事业有成!" 
49. android:textSize = "30sp" 
50. /> 
51. </RelativeLayout> 
52. </ScrollView> 
53. </LinearLayout> 
54. <LinearLayout 
55. android:id = "@+id/TabLayout_Three" 
56. android:layout_width = "fill_parent" 
57. android:layout_height = "fill_parent" 
58. android:layout_above = "@+id/Tabs" 
59. > 
60. <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> 
61. <RelativeLayout 
62. android:layout_width = "fill_parent" 
63. android:layout_height = "fill_parent" 
64. android:visibility = "visible" 
65. android:layout_above = "@+id/Tabs" 
66. > 
67. <ImageView 
68. 
69. android:layout_width = "fill_parent" 
70. android:layout_height = "fill_parent" 
71. android:src="@drawable/newq" 
72. /> 
73. </RelativeLayout> 
74. </ScrollView> 
75. </LinearLayout> 
76. <LinearLayout 
77. android:id = "@+id/TabLayout_Four" 
78. android:layout_width = "fill_parent" 
79. android:layout_height = "fill_parent" 
80. android:layout_above = "@+id/Tabs" 
81. > 
82. <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> 
83. <RelativeLayout 
84. android:id = "@+id/TabLayout_Four" 
85. android:layout_width = "fill_parent" 
86. android:layout_height = "fill_parent" 
87. android:visibility = "visible" 
88. android:layout_above = "@+id/Tabs" 
89. > 
90. <TextView 
91. android:textColor="@android:color/black" 
92. android:layout_width = "wrap_content" 
93. android:layout_height = "wrap_content" 
94. android:text = "很简单,是么" 
95. /> 
96. </RelativeLayout> 
97. </ScrollView> 
98. </LinearLayout> 
99. <view 
100. class="com.notice520.MainActivity$iTab" 
101. android:id="@+id/Tabs" 
102. android:layout_width = "fill_parent" 
103. android:layout_height = "49px" 
104. android:layout_alignParentBottom = "true" 
105. /> 
106. </view> 
 
