基于RadioGroup的TabHost实现[ 转]

转自: http://blog.csdn.net/mongdb/article/details/7056024

TabHost 可以让手机屏幕的内容尽量丰富,是一个比较常用的控件,但原生的 TabHost 用户体验并不好,实际开发中通常是借助其他控件来达到更好的控制显示效果。比如 GridView+ActivityGroup 的组合、RadioGroup 等等。今天就给出 RadioGroup 的实现方式。老规矩,先上图:


    仿周末画报(iWeekly)双击隐藏 bottom。实际应用场景:阅读一篇文章时,为了享受更大的屏幕空间,双击屏幕,隐藏顶部、底部的一些功能性控件,比如回退按钮、刷新按钮,当你想回退或者刷新时,再双击一次,显示控件。

 双击前:

双击后:

 

下面给出具体的实现代码:

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.focustech.radiogrouptabhost"
    android:versionCode="1"
    android:versionName="1.0" >
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">uses-sdk </span><span style="color: rgba(255, 0, 0, 1)">android:minSdkVersion</span><span style="color: rgba(0, 0, 255, 1)">="14"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">application
    </span><span style="color: rgba(255, 0, 0, 1)">android:label</span><span style="color: rgba(0, 0, 255, 1)">="@string/app_name"</span> <span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">activity
        </span><span style="color: rgba(255, 0, 0, 1)">android:label</span><span style="color: rgba(0, 0, 255, 1)">="@string/app_name"</span><span style="color: rgba(255, 0, 0, 1)">
        android:name</span><span style="color: rgba(0, 0, 255, 1)">=".RadioGroupTabHostActivity"</span> <span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">intent-filter </span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">action </span><span style="color: rgba(255, 0, 0, 1)">android:name</span><span style="color: rgba(0, 0, 255, 1)">="android.intent.action.MAIN"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>

            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">category </span><span style="color: rgba(255, 0, 0, 1)">android:name</span><span style="color: rgba(0, 0, 255, 1)">="android.intent.category.LAUNCHER"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">intent-filter</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">activity</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">application</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</manifest>

定义按钮被点击,选中时的背景 :

<?xml version="1.0" encoding="utf-8"?>
<!--定义按钮被点击,选中时的背景 -->
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/main_btn_bg" />
    <item android:state_enabled="true" android:state_checked="true" android:drawable="@drawable/main_btn_bg" />
</selector>

样式文件,主要是为了改造原生的单选按钮:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--设定按钮样式-->
<style name="main_btn_style">
<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 去除原生的单选按钮图标 </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:button"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>@null<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:textSize"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>10dp<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:textColor"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>#ffffff<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:gravity"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>center_horizontal<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:layout_width"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>fill_parent<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:layout_height"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>wrap_content<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:drawablePadding"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>4dp<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:layout_weight"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>1.0<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 引用 main_btn_bg_d.xml,设定当按钮被press、checked时的背景图,以此增强点击、选中按钮时的视觉效果</span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">item </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="android:background"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>@drawable/main_btn_bg_d<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</style>

</resources>

布局文件:

<?xml version="1.0" encoding="utf-8"?>

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:background
="#104E8B"
android:id
="@android:id/tabhost"
>
<LinearLayout
android:orientation="vertical"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
>

<TabWidget android:id="@android:id/tabs"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:visibility
="gone"/>

<FrameLayout android:id="@android:id/tabcontent"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:layout_weight
="1.0"
>

 <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">TextView </span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/home_content"</span><span style="color: rgba(255, 0, 0, 1)">
    android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="fill_parent"</span><span style="color: rgba(255, 0, 0, 1)">
    android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="fill_parent"</span><span style="color: rgba(255, 0, 0, 1)">
    android:text</span><span style="color: rgba(0, 0, 255, 1)">="主页"</span>
    <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>

 <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">TextView </span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/message_content"</span><span style="color: rgba(255, 0, 0, 1)">
    android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="fill_parent"</span><span style="color: rgba(255, 0, 0, 1)">
    android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="fill_parent"</span><span style="color: rgba(255, 0, 0, 1)">
    android:text</span><span style="color: rgba(0, 0, 255, 1)">="信息"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>

 <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">TextView </span><span style="color: rgba(255, 0, 0, 1)">android:id</span><span style="color: rgba(0, 0, 255, 1)">="@+id/more_content"</span><span style="color: rgba(255, 0, 0, 1)">
    android:layout_width</span><span style="color: rgba(0, 0, 255, 1)">="fill_parent"</span><span style="color: rgba(255, 0, 0, 1)">
    android:layout_height</span><span style="color: rgba(0, 0, 255, 1)">="fill_parent"</span><span style="color: rgba(255, 0, 0, 1)">
    android:text</span><span style="color: rgba(0, 0, 255, 1)">="更多"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>

</FrameLayout>

<RadioGroup android:id="@+id/rg_main_btns"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:background
="@drawable/bar"
android:layout_gravity
="bottom"
android:orientation
="horizontal"
android:gravity
="center_vertical"
>

<RadioButton android:id="@+id/rd_home"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
android:text
="主页"
style
="@style/main_btn_style"
android:checked
="true"
android:drawableTop
="@drawable/home_icon"/>

<RadioButton android:id="@+id/rd_msg"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
android:text
="信息"
style
="@style/main_btn_style"
android:drawableTop
="@drawable/msg_icon"/>

<RadioButton android:id="@+id/rd_more"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
android:text
="更多"
style
="@style/main_btn_style"
android:drawableTop
="@drawable/more_icon"/>

</RadioGroup>

</LinearLayout>
</TabHost>

RadioGroupTabHostActivity.java 文件:

package com.focustech.radiogrouptabhost;

import android.app.TabActivity;

@SuppressWarnings("deprecation")
public class RadioGroupTabHostActivity extends TabActivity implements
OnCheckedChangeListener, OnTouchListener {

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String HOME_TAB = "home"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MSG_TAB = "message"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String MORE_TAB = "more"<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> TextView homeContent;

</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> count = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> firClick = 0L<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> TabHost tabHost;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> RadioGroup radioGroup;

</span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onCreate(Bundle savedInstanceState) {

    </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    init();

}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> init() {

    tabHost </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getTabHost();

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 由于在布局文件main中已经定义了TabHost、FrameLayout布局,这里不需要手动将布局文件添加到tabHost的FrameLayout下面
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> LayoutInflater.from(this).inflate(R.layout.main,
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> tabHost.getTabContentView(), true);</span>
TabSpec homeSpec = tabHost.newTabSpec(HOME_TAB).setIndicator(HOME_TAB) .setContent(R.id.home_content); TabSpec msgSpec = tabHost.newTabSpec(MSG_TAB).setIndicator(MSG_TAB) .setContent(R.id.message_content); TabSpec moreSpec = tabHost.newTabSpec(MORE_TAB).setIndicator(MORE_TAB) .setContent(R.id.more_content);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 添加面板</span>

tabHost.addTab(homeSpec);
tabHost.addTab(msgSpec);
tabHost.addTab(moreSpec);

    homeContent </span>= (TextView) <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.findViewById(R.id.home_content);
    homeContent.setOnTouchListener(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);

    radioGroup </span>= (RadioGroup) <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.findViewById(R.id.rg_main_btns);
    radioGroup.setOnCheckedChangeListener(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> onCheckedChanged(RadioGroup group, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> checkedId) {

    </span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (checkedId) {
    </span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> R.id.rd_home:
        tabHost.setCurrentTabByTag(HOME_TAB);
        </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> R.id.rd_msg:
        tabHost.setCurrentTabByTag(MSG_TAB);
        </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> R.id.rd_more:
        tabHost.setCurrentTabByTag(MORE_TAB);
        </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
        </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
    }

}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 模拟双击事件</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> onTouch(View v, MotionEvent event) {

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (MotionEvent.ACTION_DOWN ==<span style="color: rgba(0, 0, 0, 1)"> event.getAction()) {
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 这里的count、firClick都要定义成全局变量,secClick则没有必要</span>
        count++<span style="color: rgba(0, 0, 0, 1)">;
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (count == 1<span style="color: rgba(0, 0, 0, 1)">) {
            firClick </span>=<span style="color: rgba(0, 0, 0, 1)"> System.currentTimeMillis();

        } </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (count == 2<span style="color: rgba(0, 0, 0, 1)">) {
            Long secClick </span>=<span style="color: rgba(0, 0, 0, 1)"> System.currentTimeMillis();
            count </span>= 0<span style="color: rgba(0, 0, 0, 1)">;
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设定当两次触摸时间间隔小于一秒时为双击事件</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> ((secClick - firClick) &lt; 1000<span style="color: rgba(0, 0, 0, 1)">) {
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 切换底部tab的显示与隐藏</span>
                <span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (radioGroup.getVisibility()) {
                </span><span style="color: rgba(0, 0, 255, 1)">case</span><span style="color: rgba(0, 0, 0, 1)"> View.VISIBLE:
                    radioGroup.setVisibility(View.GONE);
                    </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
                </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
                    radioGroup.setVisibility(View.VISIBLE);
                    </span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
                }

            }

        }
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
}

}