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

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

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( Paint.Style.FILL );
21 mPaint.setColor( 0xFFFFFF00 );
22 mPaint.setAntiAlias(true);
23
24 mActiveTextPaint.setTextAlign( Align.CENTER );
25 mActiveTextPaint.setTextSize( 12 );
26 mActiveTextPaint.setColor( 0xFFFFFFFF );
27 mActiveTextPaint.setAntiAlias(true);
28
29
30 mInactiveTextPaint.setTextAlign( Align.CENTER );
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, r.top + 1, r.right, r.top + 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, r.top + i + 1, r.right, r.top + i + 2, mPaint );
61 color--;
62 }
63
64 // 绘制每一个tab
65   for( int i = 0; i < mTabMembers.size( ); i++ )
66 {
67 TabMember tabMember = mTabMembers.get( i );
68
69 Bitmap icon = BitmapFactory.decodeResource( getResources( ), tabMember.getIconResourceId( ) );
70 Bitmap iconColored = Bitmap.createBitmap( icon.getWidth(), icon.getHeight(), Bitmap.Config.ARGB_8888 );
71 Paint p = new Paint( Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
72 Canvas iconCanvas = new Canvas( );
73 iconCanvas.setBitmap( iconColored );
74
75 if( mActiveTab == i )//为已选中的tab绘制一个白蓝的渐变色,未选中的绘制一个白灰的渐变色
76 {
77 p.setShader( new LinearGradient( 0, 0, icon.getWidth(), icon.getHeight(),
78 0xFFFFFFFF, 0xFF54C7E1, Shader.TileMode.CLAMP ) );
79 }
80 else {
81 p.setShader( new LinearGradient( 0, 0, icon.getWidth(), icon.getHeight(),
82 0xFFA2A2A2, 0xFF5F5F5F, Shader.TileMode.CLAMP ) );
83 }
84
85 iconCanvas.drawRect( 0, 0, icon.getWidth( ), icon.getHeight( ), p );
86
87 for( int x = 0; x < icon.getWidth(); x++ )
88 {
89 for( int y = 0; y < icon.getHeight(); y++ )
90 {
91 if( ( icon.getPixel(x, y) & 0xFF000000 ) == 0 )
92 {
93 iconColored.setPixel( x, y, 0x00000000 );
94 }
95 }
96 }
97
98 // 计算tab图片的位置
99 int tabImgX = singleTabWidth * i + ( singleTabWidth / 2 - icon.getWidth( ) / 2 );
100
101 // 绘制tab图片 选中的和未选中的
102 if( mActiveTab == i )
103 {
104 mPaint.setARGB( 37, 255, 255, 255 );
105 canvas.drawRoundRect( new RectF( r.left + singleTabWidth * i + 3, r.top + 3,
106 r.left + singleTabWidth * ( i + 1 ) - 3, r.bottom - 2 ), 5, 5, mPaint );
107 canvas.drawBitmap( iconColored, tabImgX , r.top + 5, null );
108 canvas.drawText( tabMember.getText( ),
109 singleTabWidth * i + ( singleTabWidth / 2), r.bottom - 2, mActiveTextPaint );
110 } else
111 {
112 canvas.drawBitmap( iconColored, tabImgX , r.top + 5, null );
113 canvas.drawText( tabMember.getText( ),
114 singleTabWidth * i + ( singleTabWidth / 2), r.bottom - 2, mInactiveTextPaint );
115 }
116 }
117
118 }
119 /*
120 * 触摸事件
121 */
122 @Override
123 public boolean onTouchEvent( MotionEvent motionEvent )
124 {
125 Rect r = new Rect( );
126 this.getDrawingRect( r );
127 float singleTabWidth = r.right / ( mTabMembers.size( ) != 0 ? mTabMembers.size( ) : 1 );
128
129 int pressedTab = (int) ( ( motionEvent.getX( ) / singleTabWidth ) - ( motionEvent.getX( ) / singleTabWidth ) % 1 );
130
131 mActiveTab = pressedTab;
132
133 if( this.mOnTabClickListener != null)
134 {
135 this.mOnTabClickListener.onTabClick( mTabMembers.get( pressedTab ).getId( ) );
136 }
137
138 this.invalidate();
139
140 return super.onTouchEvent( motionEvent );
141 }
142
143 void addTabMember( TabMember tabMember )
144 {
145 mTabMembers.add( tabMember );
146 }
147
148 void setOnTabClickListener( OnTabClickListener onTabClickListener )
149 {
150 mOnTabClickListener = onTabClickListener;
151 }
152
153 public static class TabMember//处理tab成员
154 {
155 protected int mId;
156 protected String mText;
157 protected int mIconResourceId;
158
159 TabMember( int Id, String Text, int iconResourceId )
160 {
161 mId = Id;
162 mIconResourceId = iconResourceId;
163 mText = Text;
164 }
165
166 public int getId( )
167 {
168 return mId;
169 }
170
171 public String getText( )
172 {
173 return mText;
174 }
175
176 public int getIconResourceId( )
177 {
178 return mIconResourceId;
179 }
180
181 public void setText( String Text )
182 {
183 mText = Text;
184 }
185
186 public void setIconResourceId( int iconResourceId )
187 {
188 mIconResourceId = iconResourceId;
189 }
190 }
191
192 public static interface OnTabClickListener
193 {
194 public abstract void onTabClick( int tabId );
195 }
196 }

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

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( Paint.Style.FILL_AND_STROKE );
14 mPaint.setColor( 0xFFCBD2D8 );
15 }
16
17 @Override
18 protected void onDraw( Canvas canvas )
19 {
20 super.onDraw( canvas );
21
22 canvas.drawColor( 0xFFC5CCD4 );
23
24 this.getDrawingRect( mRect );
25
26 for( int i = 0; i < mRect.right; i += 7 )//绘制屏幕背景的纹理效果
27 {
28 canvas.drawRect( mRect.left + i, mRect.top, mRect.left + i + 2, mRect.bottom, mPaint );
29 }
30
31 }
32 }
33
34
35 private static final int TAB_HIGHLIGHT = 1;
36 private static final int TAB_CHAT = 2;
37 private static final int TAB_LOOPBACK = 3;
38 private static final int TAB_REDO = 4;
39 private iTab mTabs;
40 private LinearLayout mTabLayout_One;
41 private LinearLayout mTabLayout_Two;
42 private LinearLayout mTabLayout_Three;
43 private LinearLayout mTabLayout_Four;
44 private LinearLayout mTabLayout_Five;
45
46 @Override
47 public void onCreate(Bundle savedInstanceState)
48 {
49 super.onCreate(savedInstanceState);
50 setContentView(R.layout.main);
51
52
53 mTabs = (iTab) this.findViewById( R.id.Tabs );
54 mTabLayout_One = (LinearLayout) this.findViewById( R.id.TabLayout_One );
55 mTabLayout_Two = (LinearLayout) this.findViewById( R.id.TabLayout_Two );
56 mTabLayout_Three = (LinearLayout) this.findViewById( R.id.TabLayout_Three );
57 mTabLayout_Four = (LinearLayout) this.findViewById( R.id.TabLayout_Four );
58 mTabLayout_Five = (LinearLayout) this.findViewById( R.id.TabLayout_Four );//偷个懒,不写第五个界面啦
59
60 mTabs.addTabMember( new TabMember( TAB_HIGHLIGHT, "精选", R.drawable.jingxuan ) );
61 mTabs.addTabMember( new TabMember( TAB_CHAT, "类别", R.drawable.cat ) );
62 mTabs.addTabMember( new TabMember( TAB_LOOPBACK, "25大排行榜", R.drawable.rank ) );
63 mTabs.addTabMember( new TabMember( TAB_REDO, "搜索", R.drawable.search ) );
64 mTabs.addTabMember( new TabMember( TAB_REDO, "更新", R.drawable.download ) );//添加tab
65
66 /*初始显示第一个界面*/
67 mTabLayout_One.setVisibility( View.VISIBLE );
68 mTabLayout_Two.setVisibility( View.GONE );
69 mTabLayout_Three.setVisibility( View.GONE );
70 mTabLayout_Four.setVisibility( View.GONE );
71
72 mTabs.setOnTabClickListener( new OnTabClickListener( ) {
73 @Override
74 public void onTabClick( int tabId )//实现点击事件
75 {
76 if( tabId == TAB_HIGHLIGHT )
77 {
78 mTabLayout_One.setVisibility( View.VISIBLE );
79 mTabLayout_Two.setVisibility( View.GONE );
80 mTabLayout_Three.setVisibility( View.GONE );
81 mTabLayout_Four.setVisibility( View.GONE );
82 } else if( tabId == TAB_CHAT )
83 {
84 mTabLayout_One.setVisibility( View.GONE );
85 mTabLayout_Two.setVisibility( View.VISIBLE );
86 mTabLayout_Three.setVisibility( View.GONE );
87 mTabLayout_Four.setVisibility( View.GONE );
88 } else if( tabId == TAB_LOOPBACK )
89 {
90 mTabLayout_One.setVisibility( View.GONE );
91 mTabLayout_Two.setVisibility( View.GONE );
92 mTabLayout_Three.setVisibility( View.VISIBLE );
93 mTabLayout_Four.setVisibility( View.GONE );
94 } else if( tabId == TAB_REDO )
95 {
96 mTabLayout_One.setVisibility( View.GONE );
97 mTabLayout_Two.setVisibility( View.GONE );
98 mTabLayout_Three.setVisibility( View.GONE );
99 mTabLayout_Four.setVisibility( View.VISIBLE );
100 }
101 }
102 });
103 }

其中onDraw()方法里面实现了背景的纹理效果,配合xml里面背景色的配置,实现了如下图所示的效果:

是不是非常漂亮呢。下面就是xml里面的配置了

代码

1 <?xml version="1.0" encoding="utf-8"?>
2
3 <view xmlns:android="http://schemas.android.com/apk/res/android"
4 class="com.notice520.MainActivity$iRelativeLayout"
5 android:orientation="vertical"
6 android:layout_width="fill_parent"
7 android:layout_height="fill_parent"
8 android:background = "#C5CCD4FF"
9 >
10 <LinearLayout
11 android:id = "@+id/TabLayout_One"
12 android:layout_width = "fill_parent"
13 android:layout_height = "fill_parent"
14 android:layout_above = "@+id/Tabs"
15 >
16 <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content">
17 <RelativeLayout
18 android:layout_width = "fill_parent"
19 android:layout_height = "fill_parent"
20 android:visibility = "visible"
21 >
22 <TextView
23 android:textColor="@android:color/black"
24 android:textSize="30sp"
25 android:layout_width = "wrap_content"
26 android:layout_height = "wrap_content"
27 android:text = "春节快乐!!"
28 />
29 </RelativeLayout>
30 </ScrollView>
31 </LinearLayout>
32
33 <LinearLayout
34 android:id = "@+id/TabLayout_Two"
35 android:layout_width = "fill_parent"
36 android:layout_height = "fill_parent"
37 android:layout_above = "@+id/Tabs"
38 >
39 <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content">
40 <RelativeLayout
41 android:layout_width = "fill_parent"
42 android:layout_height = "fill_parent"
43 android:visibility = "visible"
44 android:layout_above = "@+id/Tabs"
45 >
46 <Button
47 android:layout_width = "wrap_content"
48 android:layout_height = "wrap_content"
49 android:text = "祝大家事业有成!"
50 android:textSize = "30sp"
51 />
52 </RelativeLayout>
53 </ScrollView>
54 </LinearLayout>
55 <LinearLayout
56 android:id = "@+id/TabLayout_Three"
57 android:layout_width = "fill_parent"
58 android:layout_height = "fill_parent"
59 android:layout_above = "@+id/Tabs"
60 >
61 <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content">
62 <RelativeLayout
63 android:layout_width = "fill_parent"
64 android:layout_height = "fill_parent"
65 android:visibility = "visible"
66 android:layout_above = "@+id/Tabs"
67 >
68 <ImageView
69
70 android:layout_width = "fill_parent"
71 android:layout_height = "fill_parent"
72 android:src="@drawable/newq"
73 />
74 </RelativeLayout>
75 </ScrollView>
76 </LinearLayout>
77 <LinearLayout
78 android:id = "@+id/TabLayout_Four"
79 android:layout_width = "fill_parent"
80 android:layout_height = "fill_parent"
81 android:layout_above = "@+id/Tabs"
82 >
83 <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content">
84 <RelativeLayout
85 android:id = "@+id/TabLayout_Four"
86 android:layout_width = "fill_parent"
87 android:layout_height = "fill_parent"
88 android:visibility = "visible"
89 android:layout_above = "@+id/Tabs"
90 >
91 <TextView
92 android:textColor="@android:color/black"
93 android:layout_width = "wrap_content"
94 android:layout_height = "wrap_content"
95 android:text = "很简单,是么"
96 />
97 </RelativeLayout>
98 </ScrollView>
99 </LinearLayout>
100 <view
101 class="com.notice520.MainActivity$iTab"
102 android:id="@+id/Tabs"
103 android:layout_width = "fill_parent"
104 android:layout_height = "49px"
105 android:layout_alignParentBottom = "true"
106 />
107 </view>
108

来看看最终的效果吧

是不是还不错呢  希望大家喜欢,有问题可以留言交流。

转载于:https://www.cnblogs.com/noTice520/archive/2011/01/30/1947820.html

android UI进阶之仿iphone的tab效果(二)相关推荐

  1. android UI进阶之仿iphone的tab效果

    相信很多人都喜欢iphone 酷炫的界面,虽然android的原生控件已经足够漂亮,但是往往不能满足用户越来越挑剔的眼光.其实,我们完全可以自己来绘制界面.今天我就来分享下做一个和iphone一样的t ...

  2. 做出仿iphone的圆角效果,以及shpe的各个属性

    2019独角兽企业重金招聘Python工程师标准>>> 想要做出仿iphone的圆角效果其实很简单,定义一个shap就可以了 贴上代码 下面这个例子就是在ListViw的backGr ...

  3. (转) android UI进阶之用gallery实现可滑动的Tab

    首先我们需要写Gallery的适配器.这里我们要注意的是Gallery有一个特点,就是起始一个元素的左边会留下一块空位,如下图所示: 这样我们的Tab显然不是很完美,如何解决?开始想的就是去看gall ...

  4. 精仿苹果x开机android,800元高仿iPhone X以假乱真!更可怕的是奸商套路

    原标题:800元高仿iPhone X以假乱真!更可怕的是奸商套路 每一代iPhone产品都不乏仿冒者,而iPhone X这样的高(zhuang)贵(bi)巅峰之作,同样少不了被模仿.抄袭,而从目前的情 ...

  5. android 自定义取色器,【Android自定义View】仿Photoshop取色器ColorPicker(二)

    ColorPicker 一款仿Photoshop取色器的Android版取色器. 前言 上一篇已经简单介绍了ColorPicker的项目结构以及两种颜色空间,接下来我们详细解析一下ColorPicke ...

  6. android bilibili搜索框,仿bilibili搜索框效果(三句代码实现)

    SearchDialog 仿bilibili搜索框效果(只需要三句话即可实现) 先看预览图(转换后有一点点失真): 前言 1,支持搜索历史(已经做了数据库存储了) 2,基本与bilibili的搜索效果 ...

  7. android UI进阶之布局的优化(二)

    上一篇博客中介绍了布局优化的工具,层级观察器Hierarchy Viewer和布局优化分析工具layoutopt.如果看过上篇博客的会注意到,layoutopt工具提示可以将<FrameLayo ...

  8. android UI进阶之布局的优化

    好久没更新博客了,趁着清明来写点什么. 今天来讲下如何使用android中提供的工具优化我们的布局.首先我们写一个最简单的框架布局. <?xml version="1.0"  ...

  9. android触摸效果,Android开发进阶:仿MIUI12控件触摸反馈效果(下沉+倾斜)附源码...

    简单模仿了下MIUI12里控件的触摸反馈效果,转载请标明出处 效果简述 按压控件内圈区域,控件整体缩小,高度降低(阴影消失) 按压内圈 按压控件外圈区域,依据触摸点控件以中心为支点,向触摸点倾斜 按压 ...

最新文章

  1. go语言中fmt包中Print、Printf、Println输出相关函数的区别
  2. jQuery 事件对象的属性
  3. python条件替换_python-根据其他列中的条件替换pandas列中的某些特定值
  4. 【Qt】Qt6调用Visual Studio2019生成的动态库详解
  5. 判断一个点是否在矩形内部_高速公路专用矩形泄水管特点及安装注意事项
  6. ORACLE性能优化救生指南_21章 重做和归档的优化
  7. HALCON示例程序crystal.hdev通过局部阈值处理和区域处理提取六角形晶体
  8. 【转】magento性能优化的教程(非常详细)
  9. python3.7如何使用enum_python3 enum模块
  10. acs880变频器静态辨识_ACS880变频器PID控制参数设置 -
  11. python判断是否包含英文字符
  12. OTA三种差分算法安装使用。bsdiff,hdiffpatch,xdelta3
  13. gif图怎么压缩大小?在线压缩gif技巧
  14. 上海电气“星云智汇”工业互联网平台
  15. 【iptables】bluetooth自组网
  16. HSL和HSLA颜色
  17. “十三五”地表水水质国控断面坐标位置数据(共1854个点位,含断面名称、断面编码、所在省份、所在地区、断面类型、所在河流经度、纬度)
  18. 融云「超级群」即将发布,邀你见证
  19. 检测和处理异常值的极简指南
  20. 【码住】关于系统日志中的错误COM服务器应用程序本地激活权限

热门文章

  1. 深度学习(五十八)caffe移植至mxnet
  2. matlab的一些关于块分类的函数~~~
  3. 非线性回归的数学理论与方法(非线性最小二乘法)
  4. linux gfs原理,Linux GFS 配置方法及注意事项
  5. java 事件分发机制_用两段代码带你看懂事件分发机制
  6. html如何设置三列列宽相等,CSS分割宽度100%到3列
  7. 主板没有rgb接口怎么接灯_性价比稳定的RGB水冷散热器:乔思伯天使眼TW2-240测评...
  8. python pprint_python读写文件(七)
  9. zabbix4.2学习笔记系列
  10. Oracle EBS SLA取值