android UI进阶之仿iphone的tab效果
  RhNPwA0V2ypD 2023年11月02日 38 0


 

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

上篇博客我们写了一个Itab类,介绍了背景的绘制和简单的一个图的贴图方法。我们继续来完成Itab这个类,同时把他放到MainAcitvity(继承Activity)这个类内部,这样,整个程序只需一个类就可以了。(上篇博客例子运行需要再建一个Activity的子类来作为lanucher)。废话不多说了,看看代码

 


1. public static class iTab extends
2.     {  
3. private Paint                   mPaint;//背景画笔 
4. private Paint                   mActiveTextPaint;//选中 
5. private Paint                   mInactiveTextPaint;//未选中 
6. private ArrayList<TabMember>  mTabMembers;//tab成员 
7. private int
8. private OnTabClickListener      mOnTabClickListener = null;   
9.           
10. public iTab( Context context, AttributeSet attrs ) //构造器,在里面初始化画笔 
11.         {  
12. super(context, attrs);   
13.               
14. new
15.               
16. new
17. new
18. new
19.               
20.             mPaint.setStyle( Paint.Style.FILL );  
21. 0xFFFFFF00
22. true);   
23.               
24.             mActiveTextPaint.setTextAlign( Align.CENTER );  
25. 12
26. 0xFFFFFFFF
27. true);   
28.               
29.               
30.             mInactiveTextPaint.setTextAlign( Align.CENTER );  
31. 12
32. 0xFF999999
33. true);   
34. 0;   
35.               
36.         }  
37.           
38. @Override
39. protected void
40.         {  
41. super.onDraw( canvas );   
42.               
43. new
44. this.getDrawingRect( r );   
45.               
46. // 计算每个标签能使用多少像素 
47. int singleTabWidth = r.right / ( mTabMembers.size( ) != 0 ? mTabMembers.size( ) : 1
48.               
49.               
50. // 绘制背景 
51. 0xFF000000
52. 0xFF434343
53. 1, r.right, r.top + 1, mPaint );   
54.               
55. int color = 46;   
56.               
57. for( int i = 0; i < 24; i++ )   
58.             {  
59. 255, color, color, color );   
60. 1, r.right, r.top + 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. new
71. new
72.                 iconCanvas.setBitmap( iconColored );  
73.    
74. if( mActiveTab == i )//为已选中的tab绘制一个白蓝的渐变色,未选中的绘制一个白灰的渐变色 
75.                 {  
76. new LinearGradient( 0, 0, icon.getWidth(), icon.getHeight(),   
77. 0xFFFFFFFF, 0xFF54C7E1, Shader.TileMode.CLAMP ) );   
78.                 }  
79. else
80. new LinearGradient( 0, 0, icon.getWidth(), icon.getHeight(),    
81. 0xFFA2A2A2, 0xFF5F5F5F, Shader.TileMode.CLAMP ) );   
82.                 }  
83.                   
84. 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. 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. 37, 255, 255, 255
104. new RectF( r.left + singleTabWidth * i + 3, r.top + 3,    
105. 1 ) - 3, r.bottom - 2 ), 5, 5, mPaint );   
106. 5, null
107.                     canvas.drawText( tabMember.getText( ),   
108. 2), r.bottom - 2, mActiveTextPaint );   
109. else
110.                 {  
111. 5, null
112.                     canvas.drawText( tabMember.getText( ),  
113. 2), r.bottom - 2, mInactiveTextPaint );   
114.                 }  
115.             }  
116.         }  
117. /*
118.          * 触摸事件
119.          */
120. @Override
121. public boolean
122.         {  
123. new
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
142.         {  
143.             mTabMembers.add( tabMember );  
144.         }  
145.           
146. void
147.         {  
148.             mOnTabClickListener = onTabClickListener;  
149.         }  
150.           
151. public static class TabMember//处理tab成员 
152.         {  
153. protected int
154. protected
155. protected int
156.               
157. int Id, String Text, int
158.             {  
159.                 mId = Id;  
160.                 mIconResourceId = iconResourceId;  
161.                 mText = Text;  
162.             }  
163.               
164. public int
165.             {  
166. return
167.             }  
168.               
169. public
170.             {  
171. return
172.             }  
173.               
174. public int
175.             {  
176. return
177.             }  
178.                   
179. public void
180.             {  
181.                 mText = Text;  
182.             }  
183.               
184. public void setIconResourceId( int
185.             {  
186.                 mIconResourceId = iconResourceId;  
187.             }  
188.         }  
189.           
190. public static interface
191.         {  
192. public abstract void onTabClick( int
193.         }  
194.     }


这是MainActivity这个类里面的两个static类,看我写的注释和上篇博客的内容应该都能理解。其中还定义了触摸事件,实现点击tab出现不同布局的效果。接下来我们只需要在我们的layout上添加就可以了,我们继续写一个内部类

 

 




1. public static class iRelativeLayout extends RelativeLayout//注意,还是声明为静态 
2.     {  
3. private
4. private
5.           
6. public
7.         {  
8. super(context, attrs);   
9.               
10. new
11. new
12.               
13.             mPaint.setStyle( Paint.Style.FILL_AND_STROKE );  
14. 0xFFCBD2D8
15.         }  
16.           
17. @Override
18. protected void
19.         {  
20. super.onDraw( canvas );   
21. 0xFFC5CCD4
22.               
23. this.getDrawingRect( mRect );   
24.               
25. for( int i = 0; i < mRect.right; i += 7 )//绘制屏幕背景的纹理效果 
26.             {  
27. 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
37. private
38. private
39. private
40. private
41. private
42.       
43. @Override
44. public void
45.     {  
46. super.onCreate(savedInstanceState);   
47.         setContentView(R.layout.main);   
48.           
49. this.findViewById( R.id.Tabs );   
50. this.findViewById( R.id.TabLayout_One );   
51. this.findViewById( R.id.TabLayout_Two );   
52. this.findViewById( R.id.TabLayout_Three );   
53. this.findViewById( R.id.TabLayout_Four );   
54. this.findViewById( R.id.TabLayout_Four );//偷个懒,不写第五个界面啦 
55.           
56. new TabMember( TAB_HIGHLIGHT, "精选", R.drawable.jingxuan ) );   
57. new TabMember( TAB_CHAT, "类别", R.drawable.cat ) );   
58. new TabMember( TAB_LOOPBACK, "25大排行榜", R.drawable.rank ) );   
59. new TabMember( TAB_REDO, "搜索", R.drawable.search ) );   
60. new TabMember( TAB_REDO, "更新", R.drawable.download ) );//添加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. new
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里面配置了

 


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>

 

来看看最终效果吧

 

 

android UI进阶之仿iphone的tab效果_ui



 


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  7omf4ZbFPORE   2023年11月02日   86   0   0 V8Textv9
  41QlEa797qE8   2023年11月02日   38   0   0 i++c++ci
  ssGPNGBVZK0u   2023年11月02日   71   0   0 nginxhtmlico
  jLXKB6vexBrB   2023年11月02日   59   0   0 Debuggingui高亮
  eHipUjOuzYYH   2023年11月13日   24   0   0 cssico字段
  vxoexqgjyiCS   2023年11月19日   17   0   0 i++linuxvim
  L83A5jZvvg3Q   2023年11月19日   35   0   0 源码包icoredis
  3n45YYmVLV9P   2023年11月13日   19   0   0 ico#includeLine
  9P2AJmN9ANLD   2023年11月13日   29   0   0 Dockericoci
  it2nV7RK7uw1   2023年11月28日   25   0   0 Dockerui
  it2nV7RK7uw1   2023年11月28日   23   0   0 Dockerawsui