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

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

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


是不是非常漂亮呢,剩下的就是在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>

来看看最终效果吧

是不是还不错呢  有问题可以留言交流。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值