今天把这个仿iphone效果的tab写完,这个例子参考国外rolle3k共享的代码,感谢rolle3k。
上篇博客我们写了一个Itab类,介绍了背景的绘制和简单的一个图的贴图方法。我们继续来完成Itab这个类,同时把他放到MainAcitvity(继承Activity)这个类内部,这样,整个程序只需一个类就可以了。(上篇博客例子运行需要再建一个Activity的子类来作为lanucher)。废话不多说了,看看代码
public static class iTab extends View { private Paint mPaint;//背景画笔 private Paint mActiveTextPaint;//选中 private Paint mInactiveTextPaint;//未选中 private ArrayList<TabMember> mTabMembers;//tab成员 private int mActiveTab; private OnTabClickListener mOnTabClickListener = null; public iTab( Context context, AttributeSet attrs ) //构造器,在里面初始化画笔 { super(context, attrs); mTabMembers = new ArrayList<MainActivity.iTab.TabMember>( ); mPaint = new Paint( ); mActiveTextPaint = new Paint( ); mInactiveTextPaint = new Paint( ); mPaint.setStyle( Paint.Style.FILL ); mPaint.setColor( 0xFFFFFF00 ); mPaint.setAntiAlias(true); mActiveTextPaint.setTextAlign( Align.CENTER ); mActiveTextPaint.setTextSize( 12 ); mActiveTextPaint.setColor( 0xFFFFFFFF ); mActiveTextPaint.setAntiAlias(true); mInactiveTextPaint.setTextAlign( Align.CENTER ); mInactiveTextPaint.setTextSize( 12 ); mInactiveTextPaint.setColor( 0xFF999999 ); mInactiveTextPaint.setAntiAlias(true); mActiveTab = 0; } @Override protected void onDraw( Canvas canvas ) { super.onDraw( canvas ); Rect r = new Rect( ); this.getDrawingRect( r ); // 计算每个标签能使用多少像素 int singleTabWidth = r.right / ( mTabMembers.size( ) != 0 ? mTabMembers.size( ) : 1 ); // 绘制背景 canvas.drawColor( 0xFF000000 ); mPaint.setColor( 0xFF434343 ); canvas.drawLine( r.left, r.top + 1, r.right, r.top + 1, mPaint ); int color = 46; for( int i = 0; i < 24; i++ ) { mPaint.setARGB( 255, color, color, color ); canvas.drawRect( r.left, r.top + i + 1, r.right, r.top + i + 2, mPaint ); color--; } // 绘制每一个tab for( int i = 0; i < mTabMembers.size( ); i++ ) { TabMember tabMember = mTabMembers.get( i ); Bitmap icon = BitmapFactory.decodeResource( getResources( ), tabMember.getIconResourceId( ) ); Bitmap iconColored = Bitmap.createBitmap( icon.getWidth(), icon.getHeight(), Bitmap.Config.ARGB_8888 ); Paint p = new Paint( Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); Canvas iconCanvas = new Canvas( ); iconCanvas.setBitmap( iconColored ); if( mActiveTab == i )//为已选中的tab绘制一个白蓝的渐变色,未选中的绘制一个白灰的渐变色 { p.setShader( new LinearGradient( 0, 0, icon.getWidth(), icon.getHeight(), 0xFFFFFFFF, 0xFF54C7E1, Shader.TileMode.CLAMP ) ); } else { p.setShader( new LinearGradient( 0, 0, icon.getWidth(), icon.getHeight(), 0xFFA2A2A2, 0xFF5F5F5F, Shader.TileMode.CLAMP ) ); } iconCanvas.drawRect( 0, 0, icon.getWidth( ), icon.getHeight( ), p ); for( int x = 0; x < icon.getWidth(); x++ ) { for( int y = 0; y < icon.getHeight(); y++ ) { if( ( icon.getPixel(x, y) & 0xFF000000 ) == 0 ) { iconColored.setPixel( x, y, 0x00000000 ); } } } // 计算tab图片的位置 int tabImgX = singleTabWidth * i + ( singleTabWidth / 2 - icon.getWidth( ) / 2 ); // 绘制tab图片 选中的和未选中的 if( mActiveTab == i ) { mPaint.setARGB( 37, 255, 255, 255 ); canvas.drawRoundRect( new RectF( r.left + singleTabWidth * i + 3, r.top + 3, r.left + singleTabWidth * ( i + 1 ) - 3, r.bottom - 2 ), 5, 5, mPaint ); canvas.drawBitmap( iconColored, tabImgX , r.top + 5, null ); canvas.drawText( tabMember.getText( ), singleTabWidth * i + ( singleTabWidth / 2), r.bottom - 2, mActiveTextPaint ); } else { canvas.drawBitmap( iconColored, tabImgX , r.top + 5, null ); canvas.drawText( tabMember.getText( ), singleTabWidth * i + ( singleTabWidth / 2), r.bottom - 2, mInactiveTextPaint ); } } } /* * 触摸事件 */ @Override public boolean onTouchEvent( MotionEvent motionEvent ) { Rect r = new Rect( ); this.getDrawingRect( r ); float singleTabWidth = r.right / ( mTabMembers.size( ) != 0 ? mTabMembers.size( ) : 1 ); int pressedTab = (int) ( ( motionEvent.getX( ) / singleTabWidth ) - ( motionEvent.getX( ) / singleTabWidth ) % 1 ); mActiveTab = pressedTab; if( this.mOnTabClickListener != null) { this.mOnTabClickListener.onTabClick( mTabMembers.get( pressedTab ).getId( ) ); } this.invalidate(); return super.onTouchEvent( motionEvent ); } void addTabMember( TabMember tabMember ) { mTabMembers.add( tabMember ); } void setOnTabClickListener( OnTabClickListener onTabClickListener ) { mOnTabClickListener = onTabClickListener; } public static class TabMember//处理tab成员 { protected int mId; protected String mText; protected int mIconResourceId; TabMember( int Id, String Text, int iconResourceId ) { mId = Id; mIconResourceId = iconResourceId; mText = Text; } public int getId( ) { return mId; } public String getText( ) { return mText; } public int getIconResourceId( ) { return mIconResourceId; } public void setText( String Text ) { mText = Text; } public void setIconResourceId( int iconResourceId ) { mIconResourceId = iconResourceId; } } public static interface OnTabClickListener { public abstract void onTabClick( int tabId ); } }
这是MainActivity这个类里面的两个static类,看我写的注释和上篇博客的内容应该都能理解。其中还定义了触摸事件,实现点击tab出现不同布局的效果。接下来我们只需要在我们的layout上添加就可以了,我们继续写一个内部类
public static class iRelativeLayout extends RelativeLayout//注意,还是声明为静态 { private Paint mPaint; private Rect mRect; public iRelativeLayout( Context context, AttributeSet attrs ) { super(context, attrs); mRect = new Rect( ); mPaint = new Paint( ); mPaint.setStyle( Paint.Style.FILL_AND_STROKE ); mPaint.setColor( 0xFFCBD2D8 ); } @Override protected void onDraw( Canvas canvas ) { super.onDraw( canvas ); canvas.drawColor( 0xFFC5CCD4 ); this.getDrawingRect( mRect ); for( int i = 0; i < mRect.right; i += 7 )//绘制屏幕背景的纹理效果 { canvas.drawRect( mRect.left + i, mRect.top, mRect.left + i + 2, mRect.bottom, mPaint ); } } } private static final int TAB_HIGHLIGHT = 1; private static final int TAB_CHAT = 2; private static final int TAB_LOOPBACK = 3; private static final int TAB_REDO = 4; private iTab mTabs; private LinearLayout mTabLayout_One; private LinearLayout mTabLayout_Two; private LinearLayout mTabLayout_Three; private LinearLayout mTabLayout_Four; private LinearLayout mTabLayout_Five; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTabs = (iTab) this.findViewById( R.id.Tabs ); mTabLayout_One = (LinearLayout) this.findViewById( R.id.TabLayout_One ); mTabLayout_Two = (LinearLayout) this.findViewById( R.id.TabLayout_Two ); mTabLayout_Three = (LinearLayout) this.findViewById( R.id.TabLayout_Three ); mTabLayout_Four = (LinearLayout) this.findViewById( R.id.TabLayout_Four ); mTabLayout_Five = (LinearLayout) this.findViewById( R.id.TabLayout_Four );//偷个懒,不写第五个界面啦 mTabs.addTabMember( new TabMember( TAB_HIGHLIGHT, "精选", R.drawable.jingxuan ) ); mTabs.addTabMember( new TabMember( TAB_CHAT, "类别", R.drawable.cat ) ); mTabs.addTabMember( new TabMember( TAB_LOOPBACK, "25大排行榜", R.drawable.rank ) ); mTabs.addTabMember( new TabMember( TAB_REDO, "搜索", R.drawable.search ) ); mTabs.addTabMember( new TabMember( TAB_REDO, "更新", R.drawable.download ) );//添加tab /*初始显示第一个界面*/ mTabLayout_One.setVisibility( View.VISIBLE ); mTabLayout_Two.setVisibility( View.GONE ); mTabLayout_Three.setVisibility( View.GONE ); mTabLayout_Four.setVisibility( View.GONE ); mTabs.setOnTabClickListener( new OnTabClickListener( ) { @Override public void onTabClick( int tabId )//实现点击事件 { if( tabId == TAB_HIGHLIGHT ) { mTabLayout_One.setVisibility( View.VISIBLE ); mTabLayout_Two.setVisibility( View.GONE ); mTabLayout_Three.setVisibility( View.GONE ); mTabLayout_Four.setVisibility( View.GONE ); } else if( tabId == TAB_CHAT ) { mTabLayout_One.setVisibility( View.GONE ); mTabLayout_Two.setVisibility( View.VISIBLE ); mTabLayout_Three.setVisibility( View.GONE ); mTabLayout_Four.setVisibility( View.GONE ); } else if( tabId == TAB_LOOPBACK ) { mTabLayout_One.setVisibility( View.GONE ); mTabLayout_Two.setVisibility( View.GONE ); mTabLayout_Three.setVisibility( View.VISIBLE ); mTabLayout_Four.setVisibility( View.GONE ); } else if( tabId == TAB_REDO ) { mTabLayout_One.setVisibility( View.GONE ); mTabLayout_Two.setVisibility( View.GONE ); mTabLayout_Three.setVisibility( View.GONE ); mTabLayout_Four.setVisibility( View.VISIBLE ); } } }); }
是不是非常漂亮呢,剩下的就是在xml里面配置了
<?xml version="1.0" encoding="utf-8"?> <view xmlns:android="http://schemas.android.com/apk/res/android" class="com.notice520.MainActivity$iRelativeLayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background = "#C5CCD4FF" > <LinearLayout android:id = "@+id/TabLayout_One" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:layout_above = "@+id/Tabs" > <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> <RelativeLayout android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:visibility = "visible" > <TextView android:textColor="@android:color/black" android:textSize="30sp" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "春节快乐!!" /> </RelativeLayout> </ScrollView> </LinearLayout> <LinearLayout android:id = "@+id/TabLayout_Two" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:layout_above = "@+id/Tabs" > <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> <RelativeLayout android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:visibility = "visible" android:layout_above = "@+id/Tabs" > <Button android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "祝大家事业有成!" android:textSize = "30sp" /> </RelativeLayout> </ScrollView> </LinearLayout> <LinearLayout android:id = "@+id/TabLayout_Three" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:layout_above = "@+id/Tabs" > <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> <RelativeLayout android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:visibility = "visible" android:layout_above = "@+id/Tabs" > <ImageView android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:src="@drawable/newq" /> </RelativeLayout> </ScrollView> </LinearLayout> <LinearLayout android:id = "@+id/TabLayout_Four" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:layout_above = "@+id/Tabs" > <ScrollView android:layout_width="fill_parent" android:layout_height="wrap_content"> <RelativeLayout android:id = "@+id/TabLayout_Four" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:visibility = "visible" android:layout_above = "@+id/Tabs" > <TextView android:textColor="@android:color/black" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "很简单,是么" /> </RelativeLayout> </ScrollView> </LinearLayout> <view class="com.notice520.MainActivity$iTab" android:id="@+id/Tabs" android:layout_width = "fill_parent" android:layout_height = "49px" android:layout_alignParentBottom = "true" /> </view>
来看看最终效果吧
是不是还不错呢 有问题可以留言交流。