android UI进阶之仿iphone的tab效果(二)

[来源] 达内    [编辑] 达内   [时间]2012-09-17

今天把这个仿iphone效果的tab写完,这个例子参考国外rolle3k共享的代码,感谢rolle3k。

今天把这个仿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>
 

资源下载