zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    JAVA基础——编程练习(二)
    JAVA基础——面向对象三大特性:封装、继承、多态
    JVM内存
    50. Pow(x, n) (JAVA)
    47. Permutations II (JAVA)
    46. Permutations (JAVA)
    45. Jump Game II (JAVA)
    43. Multiply Strings (JAVA)
    42. Trapping Rain Water (JAVA)
    41. First Missing Positive (JAVA)
  • 原文地址:https://www.cnblogs.com/hdjjun/p/2210798.html
Copyright © 2011-2022 走看看