基于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)"><</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)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">intent-filter </span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">/></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">intent-filter</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">activity</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">application</span><span style="color: rgba(0, 0, 255, 1)">></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)"><!--</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)"><</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)">></span>@null<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span>10dp<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span>#ffffff<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span>center_horizontal<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span>fill_parent<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span>wrap_content<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span>4dp<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span>1.0<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 128, 0, 1)"><!--</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)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">></span>@drawable/main_btn_bg_d<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">item</span><span style="color: rgba(0, 0, 255, 1)">></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)"><</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)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">/></span> <span style="color: rgba(0, 0, 255, 1)"><</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)">/></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 {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, 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>
</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) < 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)">; }
}