转载请注明出处:http://blog.csdn.net/yangyu20121224/article/details/8989063


从这一篇文章开始,我们将进入到一个应用程序主界面UI的开发和设计中了,底部菜单栏在Android的应用开发当中占有非常重要的地位。几乎所有的手机应用程序都有底部菜单栏这样的控件,主要是因为手机的屏幕大小有限,这样一种底部菜单栏实现起来的效果可以很方便的为用户切换自己所需要的界面,具有更强的交互性。底部菜单栏的样式和效果也是五花八门,多的数不胜数,但是实现的基本原理都是一样的。

这个专题的几篇文章将更加详细的介绍几种大家比较常见的和效果比较炫的实例来进行讲解。话不多说,进入正题。


一、TabActivity之感叹


1、TabActivity的现状


打开Google的API文档搜索TabActivity,在介绍这个类时会发现有这么一句话,

大概的意思是说:这个类已经在Android4.0的系统中被弃用了,新的应用程序应该使用Fragment来代替该类的开发大家可以查看:Google开发文档

2、TabActivity是否还有存在的必要性


其实谷歌有此举动,我们也应该早就想到了,为什么会这么说呢?那就要从TabActivity的原理开始说起了。


做个假定先: 比如我们最外面的Activity是MainActivity, 第一个tab是FirstActivty, 第二个tab是SecondActivity。

相信大家都用过TabActivity, 它是一个特殊的Activity,它特殊的地方在哪里?有以下几点为证:

<1> 它看起来违反了Activity的单一窗口的原则。因为它可以同时加载几个activity, 当用户点击它上面的tab时,就会跳到相应的Activity上面去。

<2> 用户首先进去FirstActivity,然后进去SecondActivity,再点击返回键的时候。它返回的界面不是FirstActivity,而是退出我们的应用程序。

<3> 当用户在FirstActivity按返回键的时候,如果MainActivity和FirstActivity通过重写onKeyDown()方法,那么收到事件回调的只有FirstActivity。

3、谷歌当时的困扰


<1> 首先我们要明白一点,android系统是单窗口系统,不像windows是多窗口的(比如在windows系统上,我们可以一边聊QQ,一边斗地主等等)。也就是说,在一个时刻,android里面只有一个activity可以显示给用户。这样就大大降低了操作系统设计的复杂性(包括事件派发等等)。

<2> 但是像TabActivity那种效果又非常必要,用户体验也比较好。所以我觉得当时google开发人员肯定很纠结,于是,一个畸形的想法产生了,就是在单窗口系统下加载多个activity,它就是TabActivity。


4、TabActivity实现加载多个Activity原理


我们都知道,想启动一个Activity,一般是调用startActivty(Intent i)方法,然后这个方法会辗转调用到ams(ActivityManagerService)来启动目标activity, 所以,TabActivity实现的要点有两个:

<1> 找到一个入口,这个入口可以访问到ActivityThread类(这个类是隐藏的,应用程序是访问不到的),然后调用ActivityThread里面的启动activity方法

<2> 绕开ams,就是我们TabActivity加载的FirstActivity和SecondActivity是不能让ams知道的。


所以,一个新的类诞生了 ---- LocalActivityManager , 它的作用如下:

<1> 这个类和ActivityThread处于一个包内,所以它有访问ActivityThread的权限。

<2> 这个类提供了类似Ams管理Activity的方法,比如调用activity的onCreate方法,onResume()等等,维护了activity生命周期。


也正如其名字一样,它是本地的activity管理。就是说它运行的进程和它管理的Activity是在一个进程里面。所以,当TabActivity要启动一个activity的时候,会调用到LocalActivityManager的创建activity方法,然后调用ActivityThread.startActivityNow(),这个方法绕过了ams,就是说ams此时根本不知LocalActivityManager已经在暗渡陈仓的启动了一个activity(所以ams的task列表里面没有新启动activity的记录,所以用户按back键就直接退出我们的应用)。然后和正常启动activity一样,初始化activity,在初始化activity的时候,有个方法非常重要:activity.attch()

[java] view plain copy
  1. finalvoidattach(...){
  2. ....
  3. mWindow.setCallback(this);
  4. .....
  5. }
mWindow.setCallback(this)这个方法非常重要,它设置了window的回调接口,这是我们activity能够接受到key事件的关键所在!因为在DecorView在接受到事件的时候,会回调这个接口,如:

[java] view plain copy
  1. finalCallbackcb=getCallback();
  2. finalbooleanhandled=cb!=null&&mFeatureId<0?cb.dispatchKeyEvent(event):super.dispatchKeyEvent(event);
当我们启动FirstActivity的时候,我们设置FirstActivity为PhoneWindow的回调实现,所以,按back键的时候,调用的是FirstActivity的onKeyDown方法。

5、TabActivity小结


从以上的种种分析来看,TabActivity只是一个怪胎而已。所以,在后面的发展中肯定会被代替,只是没想到会被替代的这么快。不经让我有了一种英雄暮路,美人辞暮的感觉,至少TabActivity曾经在Android2.2/2.3版本那么显赫一时,不过终究还是逃不过被谷歌遗弃的命运。

二、TabActivity实现方法


说了这么多,那就让我们来看看它当年到底是怎样的叱咤风云,我们将使用两种不同的方式来实现,但是最终的效果都是一样的,

如下图所示:



三、程序的目录结构



四、具体的编码实现


(1)第一种实现方式:自定义TabWidget
1、首先创建一个TabWidget的布局文件,main_tab_layout1.xml: [html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <TabHostxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@android:id/tabhost"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent">
  6. <LinearLayout
  7. android:orientation="vertical"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent">
  10. <FrameLayout
  11. android:id="@android:id/tabcontent"
  12. android:layout_width="fill_parent"
  13. android:layout_height="0.0dip"
  14. android:layout_weight="1.0"/>
  15. <TabWidget
  16. android:id="@android:id/tabs"
  17. android:layout_width="fill_parent"
  18. android:layout_height="wrap_content"
  19. android:padding="2dip"
  20. android:background="@drawable/tab_widget_background"
  21. android:layout_weight="0.0"/>
  22. </LinearLayout>
  23. </TabHost>
注意: <1>不管你是使用TabActivity 还是自定义TabHost,都要求以TabHost作为XML布局文件的根; <2> 将FrameLayout的属性值layout_weight设置为了1.0,这样就可以把TabWidget的组件从顶部挤了下来变成了底部菜单栏。 <3> <TabWidger> 和<FrameLayout>的Id 必须使用系统id,分别为android:id/tabs 和 android:id/tabcontent 。因为系统会使用者两个id来初始化TabHost的两个实例变量(mTabWidget 和 mTabContent)。

2、然后在定义一个tab_item_view.xml布局文件,这个布局文件在后面初始化Tab按钮的时候会用到 [html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content"
  5. android:gravity="center"
  6. android:orientation="vertical">
  7. <ImageView
  8. android:id="@+id/imageview"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:focusable="false"
  12. android:padding="3dp">
  13. </ImageView>
  14. <TextView
  15. android:id="@+id/textview"
  16. style="@style/tab_item_text_style"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content">
  19. </TextView>
  20. </LinearLayout>
3、这里我为了方便Tab按钮字体和背景格式的统一,在styles.xml数据文件中还添加了以下内容: [html] view plain copy
  1. <stylename="tab_item_text_style">
  2. <itemname="android:textSize">10.0dip</item>
  3. <itemname="android:textColor">#ffffffff</item>
  4. <itemname="android:ellipsize">marquee</item>
  5. <itemname="android:singleLine">true</item>
  6. </style>
  7. <stylename="tab_item_background">
  8. <itemname="android:textAppearance">@style/tab_item_text_style</item>
  9. <itemname="android:gravity">center_horizontal</item>
  10. <itemname="android:background">@drawable/selector_tab_background2</item>
  11. <itemname="android:layout_width">fill_parent</item>
  12. <itemname="android:layout_height">wrap_content</item>
  13. <itemname="android:button">@null</item>
  14. <itemname="android:drawablePadding">3.0dip</item>
  15. <itemname="android:layout_weight">1.0</item>
  16. </style>
4、定义一个自定义Tab按钮资源文件, selector_tab_background.xml: [html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <selectorxmlns:android="http://schemas.android.com/apk/res/android">
  3. <itemandroid:drawable="@drawable/tab_item_p"android:state_pressed="true"/>
  4. <itemandroid:drawable="@drawable/tab_item_d"android:state_selected="true"/>
  5. </selector>
5、最后在定义几个用来存放Tab选项卡内容的activity布局文件,由于几个布局文件的内容都差不多,所以这里就列出一个给读者参考,有需要的话可以直接下载源码,activity1_layout.xml: [html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <ImageView
  6. android:id="@+id/imageview"
  7. android:layout_width="fill_parent"
  8. android:layout_height="fill_parent"
  9. android:scaleType="fitCenter"
  10. android:src="@drawable/xianjian01">
  11. </ImageView>
  12. </LinearLayout>
6、布局完毕,接下来讲解java代码,定义一个常量工具类,Constant.java: [java] view plain copy
  1. packagecom.yangyu.mycustomtab01;
  2. /**
  3. *@authoryangyu
  4. *功能描述:常量工具类
  5. */
  6. publicclassConstant{
  7. publicstaticfinalclassConValue{
  8. /**
  9. *Tab选项卡的图标
  10. */
  11. publicstaticintmImageViewArray[]={R.drawable.tab_icon1,
  12. R.drawable.tab_icon2,
  13. R.drawable.tab_icon3,
  14. R.drawable.tab_icon4,
  15. R.drawable.tab_icon5};
  16. /**
  17. *Tab选项卡的文字
  18. */
  19. publicstaticStringmTextviewArray[]={"主页","关于","设置","搜索","更多"};
  20. /**
  21. *每一个Tab界面
  22. */
  23. publicstaticClassmTabClassArray[]={Activity1.class,
  24. Activity2.class,
  25. Activity3.class,
  26. Activity4.class,
  27. Activity5.class};
  28. }
  29. }
7、定义自定义Tab选项卡Activity类,在这个类中我们可以采用两种方法编写标签页: <1> 第一种是继承TabActivity ,然后使用getTabHost()获取TabHost对象; <2> 第二种方法是使用自定的TabHost在布局文件上<TabHost>的自定义其ID,然后通过findViewById(),方法获得TabHost对象。
本文中采用是继承TabActivity的方法, CustomTabActivity1.java: [java] view plain copy
  1. packagecom.yangyu.mycustomtab01;
  2. importandroid.app.TabActivity;
  3. importandroid.content.Intent;
  4. importandroid.os.Bundle;
  5. importandroid.view.LayoutInflater;
  6. importandroid.view.View;
  7. importandroid.widget.ImageView;
  8. importandroid.widget.TabHost;
  9. importandroid.widget.TabHost.TabSpec;
  10. importandroid.widget.TextView;
  11. importcom.yangyu.mycustomtab01.Constant.ConValue;
  12. /**
  13. *@authoryangyu
  14. *功能描述:第一种实现方法,自定义TabHost
  15. */
  16. publicclassCustomTabActivity1extendsTabActivity{
  17. //定义TabHost对象
  18. privateTabHosttabHost;
  19. //定义一个布局
  20. privateLayoutInflaterlayoutInflater;
  21. publicvoidonCreate(BundlesavedInstanceState){
  22. super.onCreate(savedInstanceState);
  23. setContentView(R.layout.main_tab_layout1);
  24. initView();
  25. }
  26. /**
  27. *初始化组件
  28. */
  29. privatevoidinitView(){
  30. //实例化TabHost对象,得到TabHost
  31. tabHost=getTabHost();
  32. //实例化布局对象
  33. layoutInflater=LayoutInflater.from(this);
  34. //得到Activity的个数
  35. intcount=ConValue.mTabClassArray.length;
  36. for(inti=0;i<count;i++){
  37. //为每一个Tab按钮设置图标、文字和内容
  38. TabSpectabSpec=tabHost.newTabSpec(ConValue.mTextviewArray[i]).setIndicator(getTabItemView(i)).setContent(getTabItemIntent(i));
  39. //将Tab按钮添加进Tab选项卡中
  40. tabHost.addTab(tabSpec);
  41. //设置Tab按钮的背景
  42. tabHost.getTabWidget().getChildAt(i).setBackgroundResource(R.drawable.selector_tab_background);
  43. }
  44. }
  45. /**
  46. *给Tab按钮设置图标和文字
  47. */
  48. privateViewgetTabItemView(intindex){
  49. Viewview=layoutInflater.inflate(R.layout.tab_item_view,null);
  50. ImageViewimageView=(ImageView)view.findViewById(R.id.imageview);
  51. if(imageView!=null){
  52. imageView.setImageResource(ConValue.mImageViewArray[index]);
  53. }
  54. TextViewtextView=(TextView)view.findViewById(R.id.textview);
  55. textView.setText(ConValue.mTextviewArray[index]);
  56. returnview;
  57. }
  58. /**
  59. *给Tab选项卡设置内容(每个内容都是一个Activity)
  60. */
  61. privateIntentgetTabItemIntent(intindex){
  62. Intentintent=newIntent(this,ConValue.mTabClassArray[index]);
  63. returnintent;
  64. }
  65. }

这段代码比较复杂,我们需要详细分析一下: <1> 首先需要做的是获取TabHost对象,可以通过TabActivtiy里的getTabHsot()方法; <2> 接着向TabHost添加tabs.即调用tabHost.addTab(TabSpec) 方法。TabSpec主要包含了setIndicator 和 setContent 方法,通过这两个方法来指定Tab 和 TanContent; <3> TabSpec 通过.newTabSpec(String tag)来创建实例。实例化后对其属性进行设置。setIndicator()设置tab,它有3个重载的函数:
  • public TabHost.TabSpec setIndicatior(CharSwquence label,Drawable icon).指定tab的标题和图标。
  • public TabHost.TabSpec (View view)通过View来自定义tab
  • public TabHost.TabSpec(CharSequence label) 指定tab的标题,此时无图标。
<4>setContent 指定tab的展示内容,它也有3种重载:
  • public TabHost.TabSpec setContent(TabHost.TabContentFactory )
  • public TabHost.TabSpec setContent(int ViewId)
  • public TabHost.TabSpec setContent(Intent intent)
   后两种方法比较后理解一个是通过 ViewId指定显示的内容,如.setContent(R.id.Team_EditText),第三种则是直接通过Intent加载一个新的Activity页。如.setContent(new Intent(this, MeetingActivity.class)));
8、最后再定义Tab选项卡内容的Activity,这里只列出一个,Activity1.java: [java] view plain copy
  1. packagecom.yangyu.mycustomtab01;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.util.Log;
  5. publicclassActivity1extendsActivity{
  6. privatefinalstaticStringTAG="Activity1";
  7. publicvoidonCreate(BundlesavedInstanceState){
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity1_layout);
  10. Log.i(TAG,"=============>onCreate");
  11. }
  12. @Override
  13. protectedvoidonResume(){
  14. super.onResume();
  15. Log.i(TAG,"=============>onResume");
  16. }
  17. @Override
  18. protectedvoidonDestroy(){
  19. super.onDestroy();
  20. Log.i(TAG,"=============>onDestroy");
  21. }
  22. }


(二)第二中实现方式:隐藏TabWidget,通过RadioGroup和RadioButton实现底部菜单栏

这种方式更漂亮,也更灵活,大部分的应用程序基本都是使用这种方式,通过setCurrentTabByTag()方法来切换不同的选项卡。

1、首先创建一个布局界面,main_tab_layout2.xml: [html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <TabHostxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@android:id/tabhost"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent">
  6. <LinearLayout
  7. android:layout_width="fill_parent"
  8. android:layout_height="fill_parent"
  9. android:orientation="vertical">
  10. <FrameLayout
  11. android:id="@android:id/tabcontent"
  12. android:layout_width="fill_parent"
  13. android:layout_height="0.0dip"
  14. android:layout_weight="1.0"/>
  15. <TabWidget
  16. android:id="@android:id/tabs"
  17. android:layout_width="fill_parent"
  18. android:layout_height="wrap_content"
  19. android:layout_weight="0.0"
  20. android:visibility="gone"/>
  21. <RadioGroup
  22. android:id="@+id/main_radiogroup"
  23. android:layout_width="fill_parent"
  24. android:layout_height="wrap_content"
  25. android:layout_gravity="bottom"
  26. android:background="@drawable/tab_widget_background"
  27. android:gravity="center_vertical"
  28. android:orientation="horizontal"
  29. android:padding="2dip">
  30. <RadioButton
  31. android:id="@+id/RadioButton0"
  32. style="@style/tab_item_background"
  33. android:drawableTop="@drawable/tab_icon1"
  34. android:text="主页"/>
  35. <RadioButton
  36. android:id="@+id/RadioButton1"
  37. style="@style/tab_item_background"
  38. android:drawableTop="@drawable/tab_icon2"
  39. android:text="关于"/>
  40. <RadioButton
  41. android:id="@+id/RadioButton2"
  42. style="@style/tab_item_background"
  43. android:drawableTop="@drawable/tab_icon3"
  44. android:text="设置"/>
  45. <RadioButton
  46. android:id="@+id/RadioButton3"
  47. style="@style/tab_item_background"
  48. android:drawableTop="@drawable/tab_icon4"
  49. android:text="搜索"/>
  50. <RadioButton
  51. android:id="@+id/RadioButton4"
  52. style="@style/tab_item_background"
  53. android:drawableTop="@drawable/tab_icon5"
  54. android:text="更多"/>
  55. </RadioGroup>
  56. </LinearLayout>
  57. </TabHost>
2、然后在定义几个用来存放Tab选项卡内容的activity布局文件,这里只列出一个activity1_layout.xml: [html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <ImageView
  6. android:id="@+id/imageview"
  7. android:layout_width="fill_parent"
  8. android:layout_height="fill_parent"
  9. android:scaleType="fitCenter"
  10. android:src="@drawable/xianjian01">
  11. </ImageView>
  12. </LinearLayout>
3、最后再定义一个自定义Tab按钮的资源文件,selector_tab_background2.xml: [html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <selectorxmlns:android="http://schemas.android.com/apk/res/android">
  3. <itemandroid:drawable="@drawable/tab_item_p"android:state_pressed="true"/>
  4. <itemandroid:drawable="@drawable/tab_item_d"android:state_checked="true"/>
  5. </selector>
4、布局界面讲解完毕,接下来详细讲解java代码 [java] view plain copy
  1. packagecom.yangyu.mycustomtab01;
  2. importandroid.app.TabActivity;
  3. importandroid.content.Intent;
  4. importandroid.os.Bundle;
  5. importandroid.widget.RadioButton;
  6. importandroid.widget.RadioGroup;
  7. importandroid.widget.RadioGroup.OnCheckedChangeListener;
  8. importandroid.widget.TabHost;
  9. importandroid.widget.TabHost.TabSpec;
  10. importcom.yangyu.mycustomtab01.Constant.ConValue;
  11. /**
  12. *@authoryangyu
  13. *功能描述:第二种实现方式,自定义RadioGroup
  14. */
  15. publicclassCustomTabActivity2extendsTabActivity{
  16. //定义TabHost对象
  17. privateTabHosttabHost;
  18. //定义RadioGroup对象
  19. privateRadioGroupradioGroup;
  20. publicvoidonCreate(BundlesavedInstanceState){
  21. super.onCreate(savedInstanceState);
  22. setContentView(R.layout.main_tab_layout2);
  23. initView();
  24. initData();
  25. }
  26. /**
  27. *初始化组件
  28. */
  29. privatevoidinitView(){
  30. //实例化TabHost,得到TabHost对象
  31. tabHost=getTabHost();
  32. //得到Activity的个数
  33. intcount=ConValue.mTabClassArray.length;
  34. for(inti=0;i<count;i++){
  35. //为每一个Tab按钮设置图标、文字和内容
  36. TabSpectabSpec=tabHost.newTabSpec(ConValue.mTextviewArray[i]).setIndicator(ConValue.mTextviewArray[i]).setContent(getTabItemIntent(i));
  37. //将Tab按钮添加进Tab选项卡中
  38. tabHost.addTab(tabSpec);
  39. }
  40. //实例化RadioGroup
  41. radioGroup=(RadioGroup)findViewById(R.id.main_radiogroup);
  42. }
  43. /**
  44. *初始化组件
  45. */
  46. privatevoidinitData(){
  47. //给radioGroup设置监听事件
  48. radioGroup.setOnCheckedChangeListener(newOnCheckedChangeListener(){
  49. @Override
  50. publicvoidonCheckedChanged(RadioGroupgroup,intcheckedId){
  51. switch(checkedId){
  52. caseR.id.RadioButton0:
  53. tabHost.setCurrentTabByTag(ConValue.mTextviewArray[0]);
  54. break;
  55. caseR.id.RadioButton1:
  56. tabHost.setCurrentTabByTag(ConValue.mTextviewArray[1]);
  57. break;
  58. caseR.id.RadioButton2:
  59. tabHost.setCurrentTabByTag(ConValue.mTextviewArray[2]);
  60. break;
  61. caseR.id.RadioButton3:
  62. tabHost.setCurrentTabByTag(ConValue.mTextviewArray[3]);
  63. break;
  64. caseR.id.RadioButton4:
  65. tabHost.setCurrentTabByTag(ConValue.mTextviewArray[4]);
  66. break;
  67. }
  68. }
  69. });
  70. ((RadioButton)radioGroup.getChildAt(0)).toggle();
  71. }
  72. /**
  73. *给Tab选项卡设置内容(每个内容都是一个Activity)
  74. */
  75. privateIntentgetTabItemIntent(intindex){
  76. Intentintent=newIntent(this,ConValue.mTabClassArray[index]);
  77. returnintent;
  78. }
  79. }
5、最后再定义Tab选项卡内容的Activity,这里只列出一个Activity1.java: [java] view plain copy
  1. packagecom.yangyu.mycustomtab01;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.util.Log;
  5. publicclassActivity1extendsActivity{
  6. privatefinalstaticStringTAG="Activity1";
  7. publicvoidonCreate(BundlesavedInstanceState){
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity1_layout);
  10. Log.i(TAG,"=============>onCreate");
  11. }
  12. @Override
  13. protectedvoidonResume(){
  14. super.onResume();
  15. Log.i(TAG,"=============>onResume");
  16. }
  17. @Override
  18. protectedvoidonDestroy(){
  19. super.onDestroy();
  20. Log.i(TAG,"=============>onDestroy");
  21. }
  22. }

(三)这里为了演示方便,我把两种效果放到了一个应用程序里
1、效果图所示:
2、主布局界面activity_main.xml: [html] view plain copy
  1. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:background="@drawable/main_background">
  6. <Button
  7. android:id="@+id/button2"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:layout_alignRight="@+id/button1"
  11. android:layout_below="@+id/button1"
  12. android:background="@drawable/selector_btn"
  13. android:padding="10dp"
  14. android:text="RadioGroup"/>
  15. <Button
  16. android:id="@+id/button1"
  17. android:layout_width="fill_parent"
  18. android:layout_height="wrap_content"
  19. android:layout_alignParentLeft="true"
  20. android:layout_alignParentTop="true"
  21. android:layout_marginTop="186dp"
  22. android:background="@drawable/selector_btn"
  23. android:padding="10dp"
  24. android:text="CustomTab"/>
  25. </RelativeLayout>
3、然后定义一个自定义按钮资源文件,selector_btn.xml: [html] view plain copy
  1. <selectorxmlns:android="http://schemas.android.com/apk/res/android">
  2. <itemandroid:drawable="@drawable/btn_press"android:state_pressed="true"/>
  3. <itemandroid:drawable="@drawable/btn_background"/>
  4. </selector>
4、最后是主界面Activity类,MainActivity.java: [java] view plain copy
  1. packagecom.yangyu.mycustomtab01;
  2. importandroid.app.Activity;
  3. importandroid.content.Intent;
  4. importandroid.os.Bundle;
  5. importandroid.view.View;
  6. importandroid.view.View.OnClickListener;
  7. importandroid.widget.Button;
  8. publicclassMainActivityextendsActivity{
  9. //定义Button按钮对象
  10. privateButtonbtn1,btn2;
  11. @Override
  12. protectedvoidonCreate(BundlesavedInstanceState){
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.activity_main);
  15. initView();
  16. }
  17. /**
  18. *初始化组件
  19. */
  20. privatevoidinitView(){
  21. //实例化按钮对象
  22. btn1=(Button)findViewById(R.id.button1);
  23. btn2=(Button)findViewById(R.id.button2);
  24. //设置监听,进入CustomTab界面
  25. btn1.setOnClickListener(newOnClickListener(){
  26. @Override
  27. publicvoidonClick(Viewv){
  28. startActivity(newIntent(MainActivity.this,CustomTabActivity1.class));
  29. }
  30. });
  31. //设置监听,进入RadioGroup界面
  32. btn2.setOnClickListener(newOnClickListener(){
  33. @Override
  34. publicvoidonClick(Viewv){
  35. startActivity(newIntent(MainActivity.this,CustomTabActivity2.class));
  36. }
  37. });
  38. }
  39. }

今天就写到这里吧,下一篇继续给大家带来底部菜单栏的实例讲解,希望大家可以继续支持,晚安了。

源码下载地址

更多相关文章

  1. android 4.2的新特性layoutRtl,让布局自动从右往左显示
  2. 终结者:电脑显示Android手机屏幕之asm.jar工具正确的使用方法
  3. Android中用seekbar控件控制歌曲的进度
  4. 保护你的隐私,五种控制Android应用的权限的方法
  5. Android(安卓)button自定义显示
  6. 让Camera在portrait模式下不旋转90度
  7. Android(安卓)Context 到底是什么?
  8. Android注解框架Annotations从配置到应用
  9. 分享五种Android常用布局方式

随机推荐

  1. Android中使用语音引擎入门七步曲
  2. 領航桌面App一秒鐘把你的 Android(安卓)
  3. Android敲诈者病毒“安卓性能激活”分析(2
  4. Android逆向之旅---Android中锁屏密码算
  5. android 仿ios 对话框已封装成工具类
  6. Learning Android(安卓)- 第0章 - 我印象
  7. 老于的开发经历
  8. 【Android(安卓)内存优化】使用 Memory A
  9. Android开发 第五课 Android的几种布局方
  10. 电商应用开发实例分享:《凡客移动应用之An