Android: Tab的使用总结

Android TabView 使用
本文探讨了Android开发中TabView的使用方法,详细介绍了通过TabHost管理TabPage的过程,并对比了三种添加TabPage的不同方式。
之前在[url]t.sina.com.cn/kevinlynx[/url]陆续贴了些android开发涉及到的一些code snippets,主要目的是记录,供以后需要的时候查阅方便。但是因为miniblog的字数限制,在记录较多信息的时候还是有诸多不便。so, i'm here.

Tab view算是我接触android平台第二个比较迷惑的地方(第一个是ListView的adapter)。在百度了一些别人的使用心得/总结后,依然发现对tab view的使用存在很多疑问。包括ApiDemo里的例子以及其他一些例子代码。就目前而言我依然存在部分疑点,不过,就单纯的使用而言,倒是足够了。

Tab view通过TabHost来管理tab page:
A TabHost is(copyed from official reference):
Container for a tabbed window view. This object holds two children: a set of tab labels that the user clicks to select a specific tab, and a FrameLayout object that displays the contents of that page.

使用TabHost必然涉及到TabActivity:
[code]
class TabSample extends TabActivity {
protected void onCreate( Bundle savedInstanceState ) {
TabHost tabHost = getTabHost();
}
};
[/code]
取得TabHost 更多地是为tab添加page,即标签页。

此外,android用TabSpec来表示一个标签页,可以通过tabHost.newTabSpec来创建,创建的时候一般会立即设置各种属性,如下代码:

[code]
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("tab1")
.setContent(R.id.view1));
[/code]


添加标签页的方式就多了,方式太多正是迷惑人的地方。就我目前所查阅的资料来看,有3个方式添加子标签(添加子标签即为tab setContent):
[color=red]
1、如ApiDemo Tabs1.java所示,使用layout (declared in xml)来作为内容[/color]:
[code]
LayoutInflater.from(this).inflate(R.layout.tabs1, tabHost.getTabContentView(), true);

tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("tab1")
.setContent(R.id.view1));
[/code]
这里的inflate实际上我不太理解,好像是将tabs1这个layout实力化为java对象,并作为tabHost.getTabContentView()的子views。inflat相关机制还没去研究。
[color=red]
2、如ApiDemo Tabs2.java所示,使用TabHost.TabContentFactory来设置标签页的内容:[/color]
[code]
public class Tabs2 extends TabActivity implements TabHost.TabContentFactory {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

final TabHost tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("tab1", getResources().getDrawable(R.drawable.star_big_on))
.setContent(this));
....
public View createTabContent(String tag) {
final TextView tv = new TextView(this);
tv.setText("Content for tab with tag " + tag);
return tv;
}
[/code]
[color=red]
3、我想这才是我目前所需要的方式,直接嵌入其他的Activity进来。通过Intent的方式,如ApiDemo Tabs3.java所示:[/color]
[code]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

final TabHost tabHost = getTabHost();

tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("list")
.setContent(new Intent(this, List1.class)));
....
[/code]


以上几种方式中,只有方式1需要使用一个layout(我的意思是xml配置的)。在我查看的另一份代码中(UROP1,一个闹钟程序),他使用了第三种方式,但却在开头setContentView。在我注释掉这行代码时,效果依然没变。包括在网上的很多其他文章,都会使用setContentView,但看起来有点多余。这也是让我迷惑的地方。

综合来说,三种方式,[color=red]都不需要setContentView,方式1需要inflat一份layout,其他2种则不需要。[/color]

BTW,Javaeye的blog编辑功能还不错。:D
[color=red]
1.2.2011 update
[/color]
默认设置下,TabActivity中的content是activity的话,第一次切换会触发onCreate,切换标签页
不会导致当前activity onStop/onDestroy,只有当退出TabActivity时,才触发。

标签页切换会导致子activity onPause,只有当前处于前台的activity,才会接收到
onBackPressed,整个TabActivity退出时,只会触发一次finishedFromChild。
现在,我的activity_route_plan.xml如下:<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:layout_marginTop="?attr/actionBarSize"> <!-- 垂直三等分 Guideline --> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline_left_third" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.33" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline_right_third" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.67" /> <!-- 三个 Tab TextView --> <TextView android:id="@+id/tab_fastest" android:layout_width="0dp" android:layout_height="48dp" android:gravity="center" android:text="⏱️ 最快捷" android:textColor="@color/black" android:textSize="14sp" android:background="#B2EBF2" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@id/guideline_left_third" app:layout_constraintBottom_toTopOf="@id/tv_route_info" android:layout_marginStart="4dp" android:layout_marginEnd="2dp" android:layout_marginTop="4dp" android:layout_marginBottom="4dp"/> <TextView android:id="@+id/tab_transfer" android:layout_width="0dp" android:layout_height="48dp" android:gravity="center" android:text="🚌 最少换乘" android:textColor="@color/black" android:textSize="14sp" android:background="#FFFFFF" app:layout_constraintTop_toTopOf="@id/tab_fastest" app:layout_constraintStart_toEndOf="@id/guideline_left_third" app:layout_constraintEnd_toStartOf="@id/guideline_right_third" app:layout_constraintBottom_toBottomOf="@id/tab_fastest" android:layout_marginStart="2dp" android:layout_marginEnd="2dp" /> <TextView android:id="@+id/tab_walk" android:layout_width="0dp" android:layout_height="48dp" android:gravity="center" android:text="🚶 最少步行" android:textColor="@color/black" android:textSize="14sp" android:background="#FFFFFF" app:layout_constraintTop_toTopOf="@id/tab_fastest" app:layout_constraintStart_toEndOf="@id/guideline_right_third" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="@id/tab_fastest" android:layout_marginStart="2dp" android:layout_marginEnd="4dp" /> <!-- TextView --> <TextView android:id="@+id/tv_route_info" android:layout_width="0dp" android:layout_height="wrap_content" android:padding="12dp" android:background="#F0F8FF" android:text="正在规划路线..." android:textSize="14sp" android:textColor="#333" android:gravity="center" app:layout_constraintTop_toBottomOf="@id/tab_fastest" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toTopOf="@id/map_view" /> <!-- 地图区域 --> <com.amap.api.maps.MapView android:id="@+id/map_view" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintTop_toBottomOf="@id/tv_route_info" app:layout_constraintBottom_toTopOf="@id/recycler_steps" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHeight_percent="0.45" /> <!-- 步骤列表 --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_steps" android:layout_width="0dp" android:layout_height="0dp" android:elevation="4dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHeight_percent="0.4" /> </androidx.constraintlayout.widget.ConstraintLayout> 就是这三个TextView看上去不太好看,深色模式倒是还好,浅色模式很难看
11-26
我要处理一个大显示下的文本长度适配:不选择文件的情况下,在中文语言下显示正常,切换到文本较长的语言并且字体设置超大,显示设置较大后,文本会把按钮挤到屏幕边缘,怎么处理<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/dialog_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="@dimen/dimen_84dp" android:orientation="vertical"> <com.google.android.material.appbar.COUIDividerAppBarLayout android:id="@+id/appbar" style="@style/CommonAppBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/color_transparent" android:clickable="true" android:focusable="true" android:paddingLeft="@dimen/dimen_0dp" android:paddingRight="@dimen/dimen_0dp" app:elevation="@dimen/toolbar_elevation"> <com.coui.appcompat.toolbar.COUIToolbar android:id="@+id/toolbar" style="@style/COUIToolBarInAppBarLayoutStyle" android:layout_width="match_parent" android:background="@null" app:supportTitleTextAppearance="@style/textAppearanceSecondTitle" app:titleCenter="false" /> <com.coui.appcompat.tablayout.COUITabLayout android:id="@+id/tab_layout" android:background="@color/color_transparent" style="@style/COUISmallTabLayoutStyle" /> </com.google.android.material.appbar.COUIDividerAppBarLayout> <RelativeLayout android:id="@+id/content_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <com.filemanager.common.view.ViewPagerWrapperForPC android:id="@+id/view_pager_wrapper" android:layout_width="match_parent" android:layout_height="match_parent"> <com.filemanager.common.view.viewpager.RTLViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/appbar" android:clipChildren="false" android:clipToPadding="false" android:orientation="horizontal" /> </com.filemanager.common.view.ViewPagerWrapperForPC> </RelativeLayout> </LinearLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="?attr/couiColorBackgroundElevatedWithCard" android:minHeight="@dimen/operation_btn_background_height"> <View android:id="@+id/button_divider" android:layout_width="match_parent" android:layout_height="@dimen/divider_background_height" android:layout_gravity="top" android:alpha="0" android:background="?attr/couiColorDivider" android:forceDarkAllowed="false" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <LinearLayout android:id="@+id/select_root_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginStart="@dimen/dimen_16dp" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:orientation="horizontal"> <TextView android:id="@+id/select_title_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/not_selected_file" android:textSize="16sp" android:lineHeight="22dp" android:textColor="?attr/couiColorLabelPrimary" android:textAppearance="@style/couiTextHeadlineXS" android:visibility="visible"/> <ImageView android:id="@+id/select_arraw_up" android:layout_width="18dp" android:layout_height="18dp" android:src="@drawable/arrow_up" android:layout_marginLeft="@dimen/dimen_6dp" android:visibility="gone" android:layout_gravity="center"/> </LinearLayout> <TextView android:id="@+id/select_body_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:lineHeight="20dp" android:textSize="14sp" android:textAppearance="?attr/couiTextBodyXS" android:textColor="?attr/couiColorLabelSecondary" android:visibility="gone" android:text="@string/selected_size"/> </LinearLayout> <View android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="1"/> <com.coui.appcompat.button.COUIButton android:id="@+id/btn_add_file" style="@style/Widget.COUI.Button.Large" android:layout_width="@dimen/dimen_96dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginEnd="@dimen/dimen_16dp" android:text="@string/label_add_recent_file" /> </LinearLayout> </FrameLayout> </FrameLayout>
07-29
【事件触发一致性】研究多智能体网络如何通过分布式事件驱动控制实现有限时间内的共识(Matlab代码实现)内容概要:本文围绕多智能体网络中的事件触发一致性问题,研究如何通过分布式事件驱动控制实现有限时间内的共识,并提供了相应的Matlab代码实现方案。文中探讨了事件触发机制在降低通信负担、提升系统效率方面的优势,重点分析了多智能体系统在有限时间收敛的一致性控制策略,涉及系统模型构建、触发条件设计、稳定性与收敛性分析等核心技术环节。此外,文档还展示了该技术在航空航天、电力系统、机器人协同、无人机编队等多个前沿领域的潜在应用,体现了其跨学科的研究价值和工程实用性。; 适合人群:具备一定控制理论基础和Matlab编程能力的研究生、科研人员及从事自动化、智能系统、多智能体协同控制等相关领域的工程技术人员。; 使用场景及目标:①用于理解和实现多智能体系统在有限时间内达成一致的分布式控制方法;②为事件触发控制、分布式优化、协同控制等课题提供算法设计与仿真验证的技术参考;③支撑科研项目开发、学术论文复现及工程原型系统搭建; 阅读建议:建议结合文中提供的Matlab代码进行实践操作,重点关注事件触发条件的设计逻辑与系统收敛性证明之间的关系,同时可延伸至其他应用场景进行二次开发与性能优化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值