android UI进阶之仿iphone的tab效果

 

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

在开始之前,我们必须掌握最基础的,也就是android中图形界面的绘制。首先讲下简单图形的绘制,这里我们就借绘制这个的背景部分来讲下吧。直接看代码

 

public  class Itab  extends View {
         
      private Paint mPaint;
     
      public Itab(Context context, AttributeSet attrs) { // 构造器,View下构造器有三种方式,在xml中配置必须实现这种方式
           super(context, attrs);
     
      }
     
     @Override
     protected  void onDraw( Canvas canvas )
     {
        
         super.onDraw( canvas );
        
         mPaint =  new Paint( ); // 创建画笔
          mPaint.setStyle( Paint.Style.FILL ); // 设置画笔 为实心
         
         Rect r =  new Rect( ); // 创建一个矩形
          this.getDrawingRect( r );
 
         canvas.drawColor( 0xFF000000 );
         mPaint.setColor( 0xFF434343 );
         canvas.drawLine( r.left, r.top + 1, r.right, r.top + 1, mPaint ); // 绘制这个矩形图形
      }
 }

 

 

在xml中这样配置

 

<? xml version="1.0" encoding="utf-8" ?>
< RelativeLayout  xmlns:android ="http://schemas.android.com/apk/res/android"
    android:orientation
="vertical"
    android:layout_width
="fill_parent"
    android:layout_height
="fill_parent"
    android:background
="#C5CCD4FF"
    
>
     < com.notice520.itab.Itab
        
android:id ="@+id/Tabs"
        android:layout_width
="fill_parent"
        android:layout_height 
= "49px"
        android:layout_alignParentBottom 
= "true"
        
/>
</ RelativeLayout >

 

这样就会得到如下的效果,这显然不是我们想要的。

 

不过别着急,我们只要在onDraw()这个方法里面添加如下一段代码:

 

int color = 46;
        
         forint 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--;
        }

 

 

通过循环的绘制,我们就可以得到如下的效果

是不是很简单呢。图形绘制中还有一个比较重要的是贴图的绘制。同样这个例子,我们在这个背景上绘制一个图标,非常的简单,同样在onDraw()这个方法里面添加如下代码

Bitmap icon = BitmapFactory.decodeResource( getResources( ), R.drawable.monitor );
         Paint p =  new Paint( Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
         p.setColor(Color.WHITE);    
         canvas.drawBitmap(icon, 10, 10, p);

 

代码非常简单,第一行获得图片资源,第二行第一一个画笔,同时打开抗锯齿和过滤,第三行设置画笔颜色,最后一行绘制图片。

来看看效果

还不错吧,当然要实现完全的tab效果,这还是远远不够的。

这个例子参考国外rolle3k共享的代码,感谢rolle3k。

 

我们继续来完成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;
             
              forint 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
               forint 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 );
                 
                  forint x = 0; x < icon.getWidth(); x++ )
                 {
                      forint 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;
             
              ifthis.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 );
             
              forint 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 >
 

 

来看看最终的效果吧

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

 

 

 

 

Trackback:http://www.cnblogs.com/noTice520/archive/2011/01/29/1947490.html

转载于:https://www.cnblogs.com/hdjjun/archive/2011/10/13/2210798.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值