前言

  为了更好的开发Android应用程序,除了熟练掌握基本的UI组件和API外,还需要掌握一些技巧,而这些技巧可以通过阅读一些代码来提高,本系列将与大家分享一些新浪微博布局方面的收获,欢迎交流!

转载,

    博客园:http://www.cnblogs.com

    农民伯伯:http://www.cnblogs.com/over140

版本

  新浪微博 weibo_10235010.apk

正文

  一、效果图

    

    红色部分是本文要实现的目标。

  二、实现

    maintabs.xml

[html] view plain copy
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <TabHostandroid:id="@android:id/tabhost"android:layout_width="fill_parent"android:layout_height="fill_parent"
  3. xmlns:android="http://schemas.android.com/apk/res/android">
  4. <LinearLayoutandroid:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent">
  5. <FrameLayoutandroid:id="@android:id/tabcontent"android:layout_width="fill_parent"android:layout_height="0.0dip"android:layout_weight="1.0"/>
  6. <TabWidgetandroid:id="@android:id/tabs"android:visibility="gone"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="0.0"/>
  7. <RadioGroupandroid:gravity="center_vertical"android:layout_gravity="bottom"android:orientation="horizontal"android:id="@id/main_radio"android:background="@drawable/maintab_toolbar_bg"android:layout_width="fill_parent"android:layout_height="wrap_content">
  8. <RadioButtonandroid:text="@string/main_home"android:checked="true"android:id="@+id/radio_button0"android:layout_marginTop="2.0dip"android:drawableTop="@drawable/icon_1_n"style="@style/main_tab_bottom"/>
  9. <RadioButtonandroid:id="@+id/radio_button1"android:layout_marginTop="2.0dip"android:text="@string/main_news"android:drawableTop="@drawable/icon_2_n"style="@style/main_tab_bottom"/>
  10. <RadioButtonandroid:id="@+id/radio_button2"android:layout_marginTop="2.0dip"android:text="@string/main_my_info"android:drawableTop="@drawable/icon_3_n"style="@style/main_tab_bottom"/>
  11. <RadioButtonandroid:id="@+id/radio_button3"android:layout_marginTop="2.0dip"android:text="@string/menu_search"android:drawableTop="@drawable/icon_4_n"style="@style/main_tab_bottom"/>
  12. <RadioButtonandroid:id="@+id/radio_button4"android:layout_marginTop="2.0dip"android:text="@string/more"android:drawableTop="@drawable/icon_5_n"style="@style/main_tab_bottom"/>
  13. </RadioGroup>
  14. </LinearLayout>
  15. </TabHost>


styles.xml

[html] view plain copy
  1. <stylename="main_tab_bottom">
  2. <itemname="android:textSize">@dimen/bottom_tab_font_size</item>
  3. <itemname="android:textColor">#ffffffff</item>
  4. <itemname="android:ellipsize">marquee</item>
  5. <itemname="android:gravity">center_horizontal</item>
  6. <itemname="android:background">@drawable/home_btn_bg</item>
  7. <itemname="android:paddingTop">@dimen/bottom_tab_padding_up</item>
  8. <itemname="android:layout_width">fill_parent</item>
  9. <itemname="android:layout_height">wrap_content</item>
  10. <itemname="android:button">@null</item>
  11. <itemname="android:singleLine">true</item>
  12. <itemname="android:drawablePadding">@dimen/bottom_tab_padding_drawable</item>
  13. <itemname="android:layout_weight">1.0</item>
  14. </style>


home_btn_bg.xml

[html] view plain copy
  1. <selector
  2. xmlns:android="http://schemas.android.com/apk/res/android">
  3. <itemandroid:state_focused="true"android:state_enabled="true"android:state_pressed="false"android:drawable="@drawable/home_btn_bg_s"/>
  4. <itemandroid:state_enabled="true"android:state_pressed="true"android:drawable="@drawable/home_btn_bg_s"/>
  5. <itemandroid:state_enabled="true"android:state_checked="true"android:drawable="@drawable/home_btn_bg_d"/>
  6. <itemandroid:drawable="@drawable/transparent"/>
  7. </selector>


代码说明:

        1.  需要注意的是他这里把TabWidget的Visibility设置成了gone!也就是默认难看的风格不见了:,取而代之的是5个带风格的单选按钮.

        2.  注意为单选按钮设置的style,其中最重要的是为其background设置了home_btn_bg.xml,也就是自定义了选中效果。

    Java文件

[java] view plain copy
  1. publicclassMainTabActivityextendsTabActivityimplements
  2. OnCheckedChangeListener{
  3. privateTabHostmHost;
  4. privateIntentmMBlogIntent;
  5. privateIntentmMoreIntent;
  6. privateIntentmInfoIntent;
  7. privateIntentmSearchIntent;
  8. privateIntentmUserInfoIntent;
  9. @Override
  10. protectedvoidonCreate(BundlesavedInstanceState){
  11. super.onCreate(savedInstanceState);
  12. requestWindowFeature(Window.FEATURE_NO_TITLE);
  13. setContentView(R.layout.maintabs);
  14. //~~~~~~~~~~~~初始化
  15. this.mMBlogIntent=newIntent(this,HomeListActivity.class);
  16. this.mSearchIntent=newIntent(this,SearchSquareActivity.class);
  17. this.mInfoIntent=newIntent(this,MessageGroup.class);
  18. this.mUserInfoIntent=newIntent(this,MyInfoActivity.class);
  19. this.mMoreIntent=newIntent(this,MoreItemsActivity.class);
  20. initRadios();
  21. setupIntent();
  22. }
  23. /**
  24. *初始化底部按钮
  25. */
  26. privatevoidinitRadios(){
  27. ((RadioButton)findViewById(R.id.radio_button0)).setOnCheckedChangeListener(this);
  28. ((RadioButton)findViewById(R.id.radio_button1)).setOnCheckedChangeListener(this);
  29. ((RadioButton)findViewById(R.id.radio_button2)).setOnCheckedChangeListener(this);
  30. ((RadioButton)findViewById(R.id.radio_button3)).setOnCheckedChangeListener(this);
  31. ((RadioButton)findViewById(R.id.radio_button4)).setOnCheckedChangeListener(this);
  32. }
  33. /**
  34. *切换模块
  35. */
  36. @Override
  37. publicvoidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked){
  38. if(isChecked){
  39. switch(buttonView.getId()){
  40. caseR.id.radio_button0:
  41. this.mHost.setCurrentTabByTag("mblog_tab");
  42. break;
  43. caseR.id.radio_button1:
  44. this.mHost.setCurrentTabByTag("message_tab");
  45. break;
  46. caseR.id.radio_button2:
  47. this.mHost.setCurrentTabByTag("userinfo_tab");
  48. break;
  49. caseR.id.radio_button3:
  50. this.mHost.setCurrentTabByTag("search_tab");
  51. break;
  52. caseR.id.radio_button4:
  53. this.mHost.setCurrentTabByTag("more_tab");
  54. break;
  55. }
  56. }
  57. }
  58. privatevoidsetupIntent(){
  59. this.mHost=getTabHost();
  60. TabHostlocalTabHost=this.mHost;
  61. localTabHost.addTab(buildTabSpec("mblog_tab",R.string.main_home,
  62. R.drawable.icon_1_n,this.mMBlogIntent));
  63. localTabHost.addTab(buildTabSpec("message_tab",R.string.main_news,
  64. R.drawable.icon_2_n,this.mInfoIntent));
  65. localTabHost.addTab(buildTabSpec("userinfo_tab",R.string.main_my_info,
  66. R.drawable.icon_3_n,this.mUserInfoIntent));
  67. localTabHost.addTab(buildTabSpec("search_tab",R.string.menu_search,
  68. R.drawable.icon_4_n,this.mSearchIntent));
  69. localTabHost.addTab(buildTabSpec("more_tab",R.string.more,
  70. R.drawable.icon_5_n,this.mMoreIntent));
  71. }
  72. privateTabHost.TabSpecbuildTabSpec(Stringtag,intresLabel,intresIcon,
  73. finalIntentcontent){
  74. returnthis.mHost
  75. .newTabSpec(tag)
  76. .setIndicator(getString(resLabel),
  77. getResources().getDrawable(resIcon))
  78. .setContent(content);
  79. }


代码说明

      1.  由于TabWidget被隐藏,所以相关的事件也会无效,这里取巧用RadioGroup与RadioButton的特性来处理切换,然后监听事件调用setCurrentTabByTag来切换Activity。

      2.  注意即使TabWidget被隐藏,也要为其设置indicator,否则会保持。

  三、总结

    在这之前如果要做这种效果我恐怕第一时间就会想到用ActivityGroup来做,主要是因为TabHost的TabWidget非常难看,用起来也不方便。其实从源码可以看出,TabActivity也是继承自ActivityGroup,这里结合了单选按钮和TabHost,各取其长,有时间可以专门写一个这样的自定义控件:)



自定义TabHost,TabWidget样式 .

分类:Android 9142人阅读 评论(7) 收藏 举报 android layout tabs encoding null button 大家好,今天我为大家分享TabHost中怎样修改TabWidget样式。在很多界面美观的应用中很多都用到了TabHost,但他们要比系统默认的要漂亮得多。先看几张图:


京东商城底部菜单栏


新浪微博底部菜单栏

好了,看到这些漂亮的菜单栏是不是很惊讶,你可能会说用Button就可以实现啊 ,可是用Button的话控制显示的内容很麻烦,不如用TabHost控制效率更高。很想知道用TabHost是怎么实现的吧,下面就来研究如何实现这种漂亮的TabHost。先看一下效果图:

界面比较简单,要想做得漂亮换几张图片就可以了。

第一步:先在布局(这里用了main.xml创建时自动生成的)里面放上TabHost ,只要将TabHost控件托至屏幕中就可:

[html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <TabHostandroid:id="@+id/tabhost"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. xmlns:android="http://schemas.android.com/apk/res/android">
  6. <LinearLayoutandroid:layout_width="fill_parent"
  7. android:id="@+id/linearLayout1"
  8. android:layout_height="fill_parent"
  9. android:orientation="vertical">
  10. <TabWidgetandroid:layout_width="fill_parent"
  11. android:layout_height="wrap_content"
  12. android:id="@android:id/tabs"></TabWidget>
  13. <FrameLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:id="@android:id/tabcontent">
  14. <LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:id="@+id/tab1"></LinearLayout>
  15. <LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:id="@+id/tab2"></LinearLayout>
  16. <LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:id="@+id/tab3"></LinearLayout>
  17. </FrameLayout>
  18. </LinearLayout>
  19. </TabHost>


这里我们已经把LinearLayout和TextView去掉了,并将“xmlns:android="……" ”添加大TabHost里了,这里要注意我们将TabHost的id定义为自己定义的id比不用android规定的id="@android:id/tabhost"。

第二步:创建显示此TabWidget的布局tabmini.xml:

[html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="40dp"
  5. android:paddingLeft="5dip"
  6. android:paddingRight="5dip"
  7. android:background="@drawable/head_bg">
  8. <TextViewandroid:id="@+id/tab_label"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. android:layout_centerInParent="true"
  12. android:gravity="center"
  13. android:textColor="#000000"
  14. android:textStyle="bold"
  15. android:background="@drawable/tabmini"/>
  16. </RelativeLayout>


第三步:创建一个selector在drawable里面 命名tabmini.xml,用来点击TabHost的一个tab时TextView的变化:

[html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <selector
  3. xmlns:android="http://schemas.android.com/apk/res/android">
  4. <itemandroid:state_selected="true"
  5. android:drawable="@drawable/add_managebg_down"/>
  6. <itemandroid:state_selected="false"
  7. android:drawable="@drawable/add_managebg"/>
  8. </selector>


第四步:在Activity里实现TabHost:

[java] view plain copy
  1. packagecn.li.tabstyle;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.view.LayoutInflater;
  5. importandroid.view.View;
  6. importandroid.widget.TabHost;
  7. importandroid.widget.TextView;
  8. publicclassTabHostStyleActivityextendsActivity{
  9. /**Calledwhentheactivityisfirstcreated.*/
  10. @Override
  11. publicvoidonCreate(BundlesavedInstanceState){
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.main);
  14. ViewniTab=(View)LayoutInflater.from(this).inflate(R.layout.tabmini,null);
  15. TextViewtext0=(TextView)niTab.findViewById(R.id.tab_label);
  16. text0.setText("ni");
  17. ViewwoTab=(View)LayoutInflater.from(this).inflate(R.layout.tabmini,null);
  18. TextViewtext1=(TextView)woTab.findViewById(R.id.tab_label);
  19. text1.setText("wo");
  20. ViewtaTab=(View)LayoutInflater.from(this).inflate(R.layout.tabmini,null);
  21. TextViewtext2=(TextView)taTab.findViewById(R.id.tab_label);
  22. text2.setText("ta");
  23. ViewweTab=(View)LayoutInflater.from(this).inflate(R.layout.tabmini,null);
  24. TextViewtext3=(TextView)weTab.findViewById(R.id.tab_label);
  25. text3.setText("we");
  26. TabHosttabHost=(TabHost)findViewById(R.id.tabhost);
  27. tabHost.setup();//Callsetup()beforeaddingtabsifloadingTabHostusingfindViewById().
  28. tabHost.addTab(tabHost.newTabSpec("nitab").setIndicator(niTab).setContent(R.id.tab1));
  29. tabHost.addTab(tabHost.newTabSpec("wotab").setIndicator(woTab).setContent(R.id.tab2));
  30. tabHost.addTab(tabHost.newTabSpec("tatab").setIndicator(taTab).setContent(R.id.tab3));
  31. tabHost.addTab(tabHost.newTabSpec("wetab").setIndicator(weTab).setContent(R.id.tab4));
  32. }
  33. }


这里我们用findViewById创建了TabHost,这样的话我们就需要在添加tab时调用TabHost的setup()方法;这里我们添加内容时添加的是布局,我们完全可以换成自己创建的Activity。

好了,让我们来看看运行效果吧:



好了,我们自定义的TabHost算是结束了。不过看到Activity里的代码很多都是重复的我们可以这样把他们简化:

[java] view plain copy
  1. packagecn.li.tabstyle;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.view.LayoutInflater;
  5. importandroid.view.View;
  6. importandroid.widget.TabHost;
  7. importandroid.widget.TextView;
  8. publicclassTabHostStyleActivityextendsActivity{
  9. /**Calledwhentheactivityisfirstcreated.*/
  10. String[]title=newString[]{"ni","wo","ta","we"};
  11. ViewuserTab,articeTab,feedTab,weTab;
  12. View[]tabs=newView[]{userTab,articeTab,feedTab,weTab};
  13. int[]tabIds=newint[]{R.id.tab1,R.id.tab2,R.id.tab3,R.id.tab4};
  14. @Override
  15. publicvoidonCreate(BundlesavedInstanceState){
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.main);
  18. TabHosttabHost=(TabHost)findViewById(R.id.tabhost);
  19. tabHost.setup();//Callsetup()beforeaddingtabsifloadingTabHostusingfindViewById().
  20. for(inti=0;i<tabs.length;i++){
  21. tabs[i]=(View)LayoutInflater.from(this).inflate(R.layout.tabmini,null);
  22. TextViewtext=(TextView)tabs[i].findViewById(R.id.tab_label);
  23. text.setText(title[i]);
  24. tabHost.addTab(tabHost.newTabSpec(title[i]).setIndicator(tabs[i]).setContent(tabIds[i]));
  25. }
  26. }
  27. }





另外相关资料:

在上一篇文章中,我们花了大量的篇幅来讲解Fragment这个新引进类的使用,目的就是为了让大家能够牢牢的掌握它的使用方法,以便读者在今后的开发中能够熟练的使用它。

一、实现效果图



二、项目工程结构

三、详细代码编写

1、主tab布局界面,main_tab_layout:

双击代码全选
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:orientation = "vertical" > < FrameLayout android:id = "@+id/realtabcontent" android:layout_width = "fill_parent" android:layout_height = "0dip" android:layout_weight = "1" /> < android.support.v4.app.FragmentTabHost android:id = "@android:id/tabhost" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:background = "@drawable/maintab_toolbar_bg" > < FrameLayout android:id = "@android:id/tabcontent" android:layout_width = "0dp" android:layout_height = "0dp" android:layout_weight = "0" /> </ android.support.v4.app.FragmentTabHost > </ LinearLayout >

2、Tab按钮选项布局,tab_item_view.xml:

双击代码全选
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <? xml version = "1.0" encoding = "utf-8"

更多相关文章

  1. Android(安卓)在一个程序中启动另一个程序(包名,或者类名)
  2. #Android项目# ——day03 Android(安卓)沉浸式状态栏的解决方案
  3. 浅谈Android五大布局——LinearLayout、FrameLayout、AbsoulteLa
  4. Android(安卓)zygote与进程创建(一)
  5. adroid之Sqlite篇
  6. android 自学日记(五) ——ListView
  7. ubuntu12.04 64bit编译android ics4.0代码出现的/usr/bin/ld.bfd
  8. 【Android开篇】开始 Hello Android
  9. android listview滑动删除

随机推荐

  1. Android SDK Tutorial: Button onClick E
  2. Android之设计模式
  3. Carrier Configuration in Android 6.0
  4. android jni 调用结构体示例
  5. Android简单实现猜拳游戏
  6. ObservableInt 无法使用
  7. Android(安卓)简单的Http框架
  8. Android — 制作悬浮窗口
  9. Android Media Scanner Process
  10. android折叠展开列表测试