`
shuai1234
  • 浏览: 972516 次
  • 性别: Icon_minigender_1
  • 来自: 山西
社区版块
存档分类
最新评论

android UI进阶之仿iphone的tab效果

 
阅读更多

 

今天把这个仿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.             forint 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.             // 绘制每一个tab   
  64.             forint i = 0; i < mTabMembers.size( ); i++ )  
  65.             {  
  66.                 TabMember tabMember = mTabMembers.get( i );  
  67.                   
  68.                 Bitmap icon = BitmapFactory.decodeResource( getResources( ), tabMember.getIconResourceId( ) );  
  69.                 Bitmap iconColored = Bitmap.createBitmap( icon.getWidth(), icon.getHeight(), Bitmap.Config.ARGB_8888 );  
  70.                 Paint p = new Paint( Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);  
  71.                 Canvas iconCanvas = new Canvas( );  
  72.                 iconCanvas.setBitmap( iconColored );  
  73.    
  74.                 if( mActiveTab == i )//为已选中的tab绘制一个白蓝的渐变色,未选中的绘制一个白灰的渐变色   
  75.                 {  
  76.                     p.setShader( new LinearGradient( 00, icon.getWidth(), icon.getHeight(),  
  77.                             0xFFFFFFFF0xFF54C7E1, Shader.TileMode.CLAMP ) );  
  78.                 }  
  79.                 else {      
  80.                     p.setShader( new LinearGradient( 00, icon.getWidth(), icon.getHeight(),   
  81.                             0xFFA2A2A20xFF5F5F5F, Shader.TileMode.CLAMP ) );  
  82.                 }  
  83.                   
  84.                 iconCanvas.drawRect( 00, icon.getWidth( ), icon.getHeight( ), p );  
  85.                   
  86.                 forint x = 0; x < icon.getWidth(); x++ )  
  87.                 {  
  88.                     forint y = 0; y < icon.getHeight(); y++ )  
  89.                     {  
  90.                         if( ( icon.getPixel(x, y) & 0xFF000000 ) == 0 )  
  91.                         {  
  92.                             iconColored.setPixel( x, y, 0x00000000 );  
  93.                         }  
  94.                     }  
  95.                 }  
  96.                   
  97.                 // 计算tab图片的位置   
  98.                 int tabImgX = singleTabWidth * i + ( singleTabWidth / 2 - icon.getWidth( ) / 2 );  
  99.                   
  100.                 // 绘制tab图片 选中的和未选中的   
  101.                 if( mActiveTab == i )  
  102.                 {         
  103.                     mPaint.setARGB( 37255255255 );  
  104.                     canvas.drawRoundRect(  new RectF( r.left + singleTabWidth * i + 3, r.top + 3,   
  105.                             r.left + singleTabWidth * ( i + 1 ) - 3, r.bottom - 2 ), 55, mPaint );  
  106.                     canvas.drawBitmap( iconColored, tabImgX , r.top + 5null );  
  107.                     canvas.drawText( tabMember.getText( ),   
  108.                             singleTabWidth * i + ( singleTabWidth / 2), r.bottom - 2, mActiveTextPaint );  
  109.                 } else  
  110.                 {  
  111.                     canvas.drawBitmap( iconColored, tabImgX , r.top + 5null );  
  112.                     canvas.drawText( tabMember.getText( ),  
  113.                             singleTabWidth * i + ( singleTabWidth / 2), r.bottom - 2, mInactiveTextPaint );  
  114.                 }  
  115.             }  
  116.         }  
  117.         /* 
  118.          * 触摸事件 
  119.          */  
  120.         @Override  
  121.         public boolean onTouchEvent( MotionEvent motionEvent )  
  122.         {  
  123.             Rect r = new Rect( );  
  124.             this.getDrawingRect( r );             
  125.             float singleTabWidth = r.right / ( mTabMembers.size( ) != 0 ? mTabMembers.size( ) : 1 );  
  126.               
  127.             int pressedTab = (int) ( ( motionEvent.getX( ) / singleTabWidth ) - ( motionEvent.getX( ) / singleTabWidth ) % 1 );  
  128.               
  129.             mActiveTab = pressedTab;  
  130.               
  131.             ifthis.mOnTabClickListener != null)  
  132.             {  
  133.                 this.mOnTabClickListener.onTabClick( mTabMembers.get( pressedTab ).getId( ) );            
  134.             }  
  135.               
  136.             this.invalidate();  
  137.               
  138.             return super.onTouchEvent( motionEvent );  
  139.         }  
  140.           
  141.         void addTabMember( TabMember tabMember )  
  142.         {  
  143.             mTabMembers.add( tabMember );  
  144.         }  
  145.           
  146.         void setOnTabClickListener( OnTabClickListener onTabClickListener )  
  147.         {  
  148.             mOnTabClickListener = onTabClickListener;  
  149.         }  
  150.           
  151.         public static class TabMember//处理tab成员   
  152.         {  
  153.             protected int       mId;  
  154.             protected String    mText;  
  155.             protected int       mIconResourceId;  
  156.               
  157.             TabMember( int Id, String Text, int iconResourceId )  
  158.             {  
  159.                 mId = Id;  
  160.                 mIconResourceId = iconResourceId;  
  161.                 mText = Text;  
  162.             }  
  163.               
  164.             public int getId( )  
  165.             {  
  166.                 return mId;  
  167.             }  
  168.               
  169.             public String getText( )  
  170.             {  
  171.                 return mText;  
  172.             }  
  173.               
  174.             public int getIconResourceId( )  
  175.             {  
  176.                 return mIconResourceId;  
  177.             }  
  178.                   
  179.             public void setText( String Text )  
  180.             {  
  181.                 mText = Text;  
  182.             }  
  183.               
  184.             public void setIconResourceId( int iconResourceId )  
  185.             {  
  186.                 mIconResourceId = iconResourceId;  
  187.             }  
  188.         }  
  189.           
  190.         public static interface OnTabClickListener  
  191.         {  
  192.             public abstract void onTabClick( int tabId );  
  193.         }  
  194.     }  
 这是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.             canvas.drawColor( 0xFFC5CCD4 );  
  22.               
  23.             this.getDrawingRect( mRect );  
  24.               
  25.             forint i = 0; i < mRect.right; i += 7 )//绘制屏幕背景的纹理效果   
  26.             {  
  27.                 canvas.drawRect( mRect.left + i, mRect.top, mRect.left + i + 2, mRect.bottom, mPaint );  
  28.             }  
  29.         }  
  30.     }  
  31.       
  32.     private static final int TAB_HIGHLIGHT = 1;  
  33.     private static final int TAB_CHAT = 2;  
  34.     private static final int TAB_LOOPBACK = 3;  
  35.     private static final int TAB_REDO = 4;  
  36.     private iTab            mTabs;  
  37.     private LinearLayout    mTabLayout_One;  
  38.     private LinearLayout    mTabLayout_Two;  
  39.     private LinearLayout    mTabLayout_Three;  
  40.     private LinearLayout    mTabLayout_Four;  
  41.     private LinearLayout    mTabLayout_Five;  
  42.       
  43.     @Override  
  44.     public void onCreate(Bundle savedInstanceState)   
  45.     {  
  46.         super.onCreate(savedInstanceState);  
  47.         setContentView(R.layout.main);   
  48.           
  49.         mTabs = (iTab) this.findViewById( R.id.Tabs );  
  50.         mTabLayout_One = (LinearLayout) this.findViewById( R.id.TabLayout_One );  
  51.         mTabLayout_Two = (LinearLayout) this.findViewById( R.id.TabLayout_Two );  
  52.         mTabLayout_Three = (LinearLayout) this.findViewById( R.id.TabLayout_Three );  
  53.         mTabLayout_Four = (LinearLayout) this.findViewById( R.id.TabLayout_Four );  
  54.         mTabLayout_Five = (LinearLayout) this.findViewById( R.id.TabLayout_Four );//偷个懒,不写第五个界面啦   
  55.           
  56.         mTabs.addTabMember( new TabMember( TAB_HIGHLIGHT, "精选", R.drawable.jingxuan ) );  
  57.         mTabs.addTabMember( new TabMember( TAB_CHAT, "类别", R.drawable.cat ) );  
  58.         mTabs.addTabMember( new TabMember( TAB_LOOPBACK, "25大排行榜", R.drawable.rank ) );  
  59.         mTabs.addTabMember( new TabMember( TAB_REDO, "搜索", R.drawable.search ) );  
  60.         mTabs.addTabMember( new TabMember( TAB_REDO, "更新", R.drawable.download ) );//添加tab   
  61.           
  62.         /*初始显示第一个界面*/  
  63.         mTabLayout_One.setVisibility( View.VISIBLE );  
  64.         mTabLayout_Two.setVisibility( View.GONE );  
  65.         mTabLayout_Three.setVisibility( View.GONE );  
  66.         mTabLayout_Four.setVisibility( View.GONE );  
  67.           
  68.         mTabs.setOnTabClickListener( new OnTabClickListener( ) {  
  69.             @Override  
  70.             public void onTabClick( int tabId )//实现点击事件   
  71.             {  
  72.                 if( tabId == TAB_HIGHLIGHT )  
  73.                 {  
  74.                     mTabLayout_One.setVisibility( View.VISIBLE );  
  75.                     mTabLayout_Two.setVisibility( View.GONE );  
  76.                     mTabLayout_Three.setVisibility( View.GONE );  
  77.                     mTabLayout_Four.setVisibility( View.GONE );  
  78.                 } else if( tabId == TAB_CHAT )  
  79.                 {  
  80.                     mTabLayout_One.setVisibility( View.GONE );  
  81.                     mTabLayout_Two.setVisibility( View.VISIBLE );  
  82.                     mTabLayout_Three.setVisibility( View.GONE );  
  83.                     mTabLayout_Four.setVisibility( View.GONE );  
  84.                 } else if( tabId == TAB_LOOPBACK )  
  85.                 {  
  86.                     mTabLayout_One.setVisibility( View.GONE );  
  87.                     mTabLayout_Two.setVisibility( View.GONE );  
  88.                     mTabLayout_Three.setVisibility( View.VISIBLE );  
  89.                     mTabLayout_Four.setVisibility( View.GONE );  
  90.                 } else if( tabId == TAB_REDO )  
  91.                 {  
  92.                     mTabLayout_One.setVisibility( View.GONE );  
  93.                     mTabLayout_Two.setVisibility( View.GONE );  
  94.                     mTabLayout_Three.setVisibility( View.GONE );  
  95.                     mTabLayout_Four.setVisibility( View.VISIBLE );  
  96.                 }  
  97.             }  
  98.         });  
  99.     }  
 其中onDraw()方法里面实现了背景的纹理效果,配合xml里面背景色的配置,实现了如下图所示的效果:

 


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

 

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

 

来看看最终效果吧

 

 

http://blog.csdn.net/notice520/article/details/6169904

分享到:
评论

相关推荐

    APP开发教程 Java Android移动端开发 4、Android UI进阶编程 (1) 共34页.pptx

    Android UI进阶编程主要涉及了Drawable的使用以及2D图形绘制的相关概念,这些是构建Android应用界面的关键元素。首先,我们来深入理解Android Drawable。 Android Drawable是一个抽象的概念,它涵盖了各种图形对象...

    android_UI进阶之style和theme的使用

    Android_UI进阶之style和theme的使用 Android 中的样式(style)和主题(theme)是两种资源,都是 Android 提供的默认资源,可以供开发者使用。同时,开发者也可以自己定义style和theme,以满足不同的需求。 style...

    《Android高级进阶》

    《Android高级进阶》这本书是为那些已经掌握了Android基础,并希望深入学习和提升技能的开发者准备的。在Android开发的世界中,"进阶"通常意味着更复杂的技术、更高效的编程实践以及更深层次的理解。以下是对这本书...

    Android高手进阶教程

    《Android高手进阶教程》是一本专为对Android开发有一定基础并希望进一步提升技能的开发者设计的教材。这本书深入探讨了Android平台的核心概念和技术,旨在帮助读者从初级开发者跃升为高级工程师。以下是对该教程中...

    Android高手进阶指南

    《Android高手进阶指南》是一本专为已经具备一定Android基础的开发者准备的深度学习资料。这本书涵盖了Android开发中的高级主题和技术,旨在帮助读者提升在Android领域的专业技能,成为真正的技术专家。 首先,本书...

    高清版 Android高级进阶-顾浩鑫-高清版本-带目录

    由于提供的文件信息中,标题、描述和标签均相同,且部分内容仅有重复的“霏霏”二字,无法提供具体的Android高级进阶知识点。为了满足您的要求,我将基于Android高级进阶这一主题,提供一些该领域的通用知识点,希望...

    Android开发进阶从小工到专家(pdf书签版)

    《Android开发进阶从小工到专家》是一本专为Android开发者设计的进阶教程,旨在帮助初学者和有一定基础的开发者提升技能,成为一名精通Android开发的专家。这本书涵盖了Android开发的各个方面,包括基础概念、核心...

    android仿iphone滚轮UI效果

    在Android平台上实现类似iPhone的滚轮UI效果,是一种常见的需求,尤其在开发跨平台应用时。这个项目提供了源码实现,使得开发者可以深入理解并自定义这种交互方式。滚轮UI,通常被称为“Picker”,是iOS系统中的一个...

    Android开发进阶从小工到专家(书签版)

    《Android开发进阶从小工到专家》是由资深Android开发者何红辉编著的一本专业书籍,旨在帮助初入Android开发领域的工程师逐步提升技能,直至达到专家级别。这本书以清晰的结构和高清的书签版形式呈现,使得学习过程...

    Android开发进阶:从小工到专家

    《Android开发进阶:从小工到专家》这本书是Android开发者提升技能的重要参考资料,它面向有一定基础的Android程序员,旨在帮助他们从初级阶段过渡到高级专家水平。书中涵盖了一系列深入的Android开发主题,包括但不...

    Android开发进阶 从小工到专家.PDF

    根据提供的文件信息,“Android开发进阶 从小工到专家.PDF”主要聚焦于Android平台上的应用程序开发技术。尽管文件描述部分未提供具体内容,但从标题和标签来看,这本书应该是旨在帮助读者从初学者成长为精通Android...

    android开发进阶从小工到专家 ,何红辉著.pdf

    根据提供的信息,《Android开发进阶从小工到专家》这本书由何红辉所著,主要针对的是希望在Android开发领域从入门到精通的学习者。虽然给定的部分内容并未包含实际的知识点,但从书名及描述来看,我们可以推断出这...

    android高级进阶

    《Android高级进阶》是一本面向已有基础的Android开发者,旨在提升其技能和理解的教程。这份完整版的PDF教程涵盖了Android开发中的诸多高级主题,是个人学习和提升的宝贵资源。以下将对其中的关键知识点进行详细阐述...

    Android 基于TabLayout实现的TAB页效果 仿今日头条.rar

    Android 基于TabLayout实现的TAB页导航切换效果 仿今日头条底部的TAB选项卡效果,TabLayout与ViewPager结合使用可以达到点击tab更新ViewPager、滑动ViewPager更新Tab的效果。这种效果现在在PC端、移动设备端已经很...

    第05章 UI进阶.html

    第05章 UI进阶.html

    Android应用源码仿微米全部UI项目多种效果值得借鉴

    本项目是一个高仿微米UI的项目,虽然是个UI项目但是很多东西还是值得学习和借鉴的,例如里面漂亮的仿IOS开关、仿QQ的圆角退出登录按钮 、字母索引、图文混编、九宫格图片多选、二维码扫描、仿微信的附近的人列表、仿...

    Android应用源码之仿iphone 气泡短信 DEMO.zip

    这个“Android应用源码之仿iPhone气泡短信DEMO”就是一个很好的例子,它为Android开发者提供了实现类似iPhone气泡效果的参考。下面我们将详细分析这个DEMO中的关键知识点。 首先,我们关注到几个关键的项目配置文件...

    android高手进阶教程

    《Android高手进阶教程》是一本专为已经具备一定Android基础知识的开发者准备的深度学习资料。这本教程的出现,旨在帮助读者从初级开发者跃升为Android开发的专家,掌握更多的高级技术和实战经验。 首先,Android...

Global site tag (gtag.js) - Google Analytics