UI___tab view 的实现

本文详细介绍TabHost组件的使用方法,包括XML配置、自定义样式、响应屏幕旋转、监听事件等高级功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.通过xml文件实现

[size=large]1.创建一个tab iew,[/size]所需的xml文件
<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:fadingEdge="none"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<RelativeLayout
android:id="@+id/LinearLayout01"
android:drawingCacheQuality="high"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="false"
android:layout_below="@android:id/tabs"
android:layout_marginTop="-5dp">
</FrameLayout>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:tabStripEnabled="false" />

</RelativeLayout>

</TabHost>
[color=red]android:layout_marginTop="-5dp"
红色部分是为了让接下来加一排button的时候两个layout之间看上去没有黑边框。[/color]

[size=large]2.创建一个tab iew[/size],所需的activity代码
final TabHost tabs = (TabHost) this.findViewById(android.R.id.tabhost);
final TabSpec tspec1 = tabs.newTabSpec("Journal [3]");
//设置tab的lable,跟icon
tspec1.setIndicator("Journal [3]", getResources().getDrawable(R.drawable.navi_journal));
tspec1.setContent(new Intent(this, SubPageJournal.class));
tabs.addTab(tspec1);
final TabSpec tspec2 = tabs.newTabSpec("Appointments");
tspec2.setIndicator("Appointments", getResources().getDrawable(R.drawable.navi_appointment));
tspec2.setContent(new Intent(this, SubPageAppointment.class));
tabs.addTab(tspec2);
final TabSpec tspec3 = tabs.newTabSpec("My Lab");
tspec3.setIndicator("My Lab", getResources().getDrawable(R.drawable.navi_lab));
tspec3.setContent(new Intent(this, SubPageLab.class));
tabs.addTab(tspec3);
final TabSpec tspec4 = tabs.newTabSpec("Medications");
tspec4.setIndicator("Medications", getResources().getDrawable(R.drawable.navi_medication));
tspec4.setContent(new Intent(this, SubPageMedications.class));
tabs.addTab(tspec4);

//设置背景颜色
tabs.getTabWidget().getChildAt(0).setBackgroundColor(0xffDE2852);
tabs.getTabWidget().getChildAt(1).setBackgroundColor(0xff007DC6);
tabs.getTabWidget().getChildAt(2).setBackgroundColor(0xffFF9631);
tabs.getTabWidget().getChildAt(3).setBackgroundColor(0xff94CB31);
tabs.setBackgroundColor(0xffDE2852);


[size=large]3.给某个tab 标签下面加一个排横着的button[/size]

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF">
<RadioGroup
android:id="@+id/RadioGroup01"
android:background="#DE2852"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="5dp">
<RadioButton
android:text="My Care"
android:id="@+id/myCare"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#ff000000"
android:background="@drawable/buttonbackground"
android:button="@drawable/no_image"
android:layout_weight="1"
android:gravity="center_horizontal"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"></RadioButton>
<RadioButton
android:text="Vital"
android:id="@+id/vital"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#ff000000"
android:background="@drawable/buttonbackground"
android:button="@drawable/no_image"
android:layout_weight="1"
android:gravity="center_horizontal"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"></RadioButton>
<RadioButton
android:text="Givers"
android:id="@+id/givers"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#ff000000"
android:background="@drawable/buttonbackground"
android:button="@drawable/no_image"
android:layout_weight="1"
android:gravity="center_horizontal"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"></RadioButton>
<RadioButton
android:text="History"
android:id="@+id/history"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#ff000000"
android:background="@drawable/buttonbackground"
android:button="@drawable/no_image"
android:layout_weight="1"
android:gravity="center_horizontal"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"></RadioButton>
</RadioGroup>
<ListView
android:id="@+id/content_list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:cacheColorHint="#00000000"
android:dividerHeight="0dp"
android:divider="@null">
</ListView>
</LinearLayout>

[color=red]<RadioGroup>----- <RadioGroup>
红色部分为加的button。[/color]

[size=large]4.如何让tab标签切换的时候始终显示的是sub tab的home page[/size]
(当sub tab下有子页面跳转(多级跳转)的时候)
举例:tabhost中共有3个sub tab(A, B, C)
程序启动后点击 tab 标签 A 进入 A 界面
A中点击某个button的时候会changeContent 到 a1 界面,
如果这个时候点击tab 标签 B,就会跳转到 B 界面,
然后再点击 tab 标签 A的时候 显示的就不是 A 界面 而是 a1 界面,

因为 在标签间切换的时候 不会重新调activity的oncreate 而是 调的onresume,
如果 在A界面的时候changecontent,下一次回来,还会停留在上次的content界面上。
为了解决这个问题就需要重写 onresume 函数,然后重新设置一下UI,根据自己的具体需要重新设置content就是了
  @Override
protected void onResume() {
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
initUI();
//System.out.println("SubpageAppointment.onResume");
super.onResume();
}

[color=red] initUI();[/color]
[color=red]红色部分initUI是自己写的函数哈。[/color]

[size=large]5. 实现当某个sub tab 中有多级跳转(子页面跳转)的时候
按返回键有返回到上一级的效果而不是关闭程序[/size]
按返回键,程序关闭是activity的默认设置,为了解决这个文集需要从写onBackPressed() 函数。
为了表示层级关系我给每个page 指定了一个int变量。
然后给当前这个sub tab 添加 mSubPage int 变量
当changecontent的时候把当前page的int 的值置赋给这个mSubPage就是了
然后在onBackPressed函数中判断 mSubPage 的值 再决定跳转到他的上一级页面。
下面是部分代码

/** The PAG e_ chem. */
private final int PAGE_CHEM = 1;

/** The PAG e_ ray. */
private final int PAGE_RAY = 2;

/** The PAG e_ pathology. */
private final int PAGE_PATHOLOGY = 3;

/** The PAG e_ mico. */
private final int PAGE_MICO = 4;

/** The PAG e_ iagedetail. */
private final int PAGE_IAGEDETAIL = 5;

private final int PAGE_CHEMEDTAIL = 6;

private final int PAGE_PATHOLOGYDETAIL = 7;

/** The m sub page. */
private int mSubPage;

。。。。。。
@Override
public void onBackPressed() {
if (mSubPage == PAGE_IAGEDETAIL) {
mSubPage = PAGE_RAY;
initView();
} else if (mSubPage == PAGE_CHEMEDTAIL) {
mSubPage = PAGE_CHEM;
initView();
} else if (mSubPage == PAGE_PATHOLOGYDETAIL) {
mSubPage = PAGE_PATHOLOGY;
initView();
} else {
super.onBackPressed();
}
}

[color=red]initView();是自定义的函数,会根据mSubPage 的值初始化不同的页面。[/color]

[size=large]6. 避免tabHost中横竖屏切换的时候会自动重启activity,会自动调用onpase ondestory onstart onreume 等函数影响ui显示的逻辑的问题。[/size]
其实很简单,只需要在 mainifest.xml的tabhost的main activity标签中添加一个属性就可以了
[color=red]android:configChanges="orientation|keyboardHidden[/color]这样就不会自动去重启了。


[size=large]7.设置自定义的tab标签样式。。[/size]
自定义tab标签的layout
tab_wiget.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="@+id/image_tab"
android:layout_height="60dp"
android:layout_width="60dp"
android:background="@drawable/navi_home"
android:layout_centerHorizontal="true">
</ImageView>
<TextView
android:id="@+id/title_tab"
android:layout_width="fill_parent"
android:textSize="12dp"
android:text="ddffd"
android:textColor="#ffFFFFFF"
android:textStyle="bold"
android:gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@+id/image_tab"
android:layout_marginTop="-10dp" />

</RelativeLayout>

在代码中添加sub tab
final TabHost tabs = (TabHost) this.findViewById(android.R.id.tabhost);
final TabSpec tspec1 = tabs.newTabSpec("Journal [1]");
RelativeLayout tabWidget1 = (RelativeLayout) LayoutInflater.from(this)
.inflate(R.layout.tab_widget, null);
ImageView imageTab1 = (ImageView) tabWidget1
.findViewById(R.id.image_tab);
TextView titleTab1 = (TextView) tabWidget1.findViewById(R.id.title_tab);

imageTab1.setImageResource(R.drawable.redactivities);
titleTab1.setText("Journal [1]");
tspec1.setIndicator(tabWidget1);
tspec1.setContent(new Intent(this, SubPageJournal.class));
tabs.addTab(tspec1);



[color=red] tspec1.setIndicator(tabWidget1);[/color]指定自定义的layout


[size=large]8.如何让tabhost在设备切换到横屏的时候改变tabhost 的layout,
比如让标签竖直排列在屏幕右边。[/size]
a.在res 下新建一个 layout-land文件夹
b.重写tabhost 的 xml 布局文件
<TabHost   xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@android:id/tabhost"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<FrameLayout android:id="@android:id/tabcontent"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#ffffffff"
android:layout_weight="1"/>
<TabWidget android:id="@android:id/tabs"
android:tabStripEnabled="false"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:background="#ffDE2852"
android:layout_weight="0"/>
</LinearLayout>
</TabHost>


[color=red]注意把原来portrait中的relativeLayout 换成了LinearLayout
并且 加上了属性android:orientation="horizontal"[/color]
c.在建立tabhost 的主activity的oncreate函数中添加如下代码,修改tabwiget的排列为竖直的排列,这个只能在代码中修改,在xml中设置Orientation属性是不顶用的。
Configuration cfg = getResources().getConfiguration();
boolean hor = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE;

if (hor) {
TabWidget tw = tabs.getTabWidget();
tw.setOrientation(LinearLayout.VERTICAL);

}


d.在layou-land的文件夹下,调整sub page的layout,注意文件名一定要跟layout中的文件名相同,这样在横置手机的时候才会自动调用layout-land下的布局。


[size=large]9.如何控制某些sub page下可以横竖切换,有些sub page下不可以横竖切换。[/size]
可以根据不同的情况,在onResume() 跟 onPause() 函数中分别调用下面两行代码

//恢复横竖切换
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

//设置为竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

//同理设置为横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

[size=large]10.给tab 标签设置监听[/size]
举例:tabhost中共有3个sub tab(A, B, C)
程序启动后点击 tab 标签 A 进入 A 界面
A中点击某个button的时候会changeContent 到 a1 界面,
如果这个时候点击tab 标签 A,android默认的是不会发生变化的,仍然停留在a1界面
假如我们想点击tab 标签 A后让他回到上一级,就得给tab 标签设置监听
 TabHost tabs;
。。。。。。。。
//0 是tab 标签的id
tabs.getTabWidget().getChildAt(0).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (0 != tabs.getCurrentTab()) {
//Journal [1]是之前add tab 的时候的标签

tabs.setCurrentTabByTag("Journal [1]");
} else {
LocalActivityManager manager = getLocalActivityManager();
//SubPageJournal 这个是在add tad 的时候setContent的 activity
SubPageJournal subpage = (SubPageJournal) manager
.getActivity("Journal [1]");
//backMainPage()是自己写的函数,用来changeContent,类似于上面提到的initUI()
subpage.backMainPage();
}

}
});

[color=red] LocalActivityManager可以在ActivityGroup里面访问子Activity的View 并操作它去改变UI[/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值