#2020征文-TV# Tab切换选项卡同时更换内容 原创 精华
Tab选项卡是应用程序中最最常用,也是最普遍存在的一种布局形态,无论是在PC端还是在移动端,都是一种清晰明了,层级关系简单的,能够使用户明确所处位置。Tab选项卡可以置于页面的底部,比如微信底部选项卡;也可以置于顶部,比如新闻类的APP顶部的类别选项;还可以置于左侧或者右侧,一般常见的是后台应用左侧的树形导航栏。它们存在一个共同的特性,那就无论我点击那个选项卡,都不会跳转到二级页面,而是在同级页面中在选项卡下的内容区域中去渲染当前选中的选项卡内容。比如下面的示例图片中,我们有三个Tab,图片、视频以及音频,首次加载时我们选中的是图片(Image)选项卡,底部内容区域是一些排列的图片,如果我们选择视频(Video),那么底部的图片将被移除,视频列表页将被载入。
1、首先修改ability_main.xml代码,在布局中添加顶部选项卡列表。
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:background_element="#444444"
ohos:orientation="vertical">
<TabList
ohos:id="$+id:tab_list"
ohos:weight="1"
ohos:top_margin="10vp"
ohos:tab_margin="24vp"
ohos:tab_length="140vp"
ohos:text_size="20fp"
ohos:height="36vp"
ohos:width="match_parent"
ohos:layout_alignment="center"
ohos:orientation="horizontal"
ohos:text_alignment="center"
ohos:normal_text_color="#999999"
ohos:selected_text_color="#FFFFFF"
ohos:selected_tab_indicator_color="#FFFFFF"
ohos:selected_tab_indicator_height="2vp"/>
</DirectionalLayout>
2、在MainAbilitySlice中为TabList容器添加Tab选项卡。
//列表项
TabList tabList = (TabList) findComponentById(ResourceTable.Id_tab_list);
TabList.Tab imageTab = tabList.new Tab(getContext());
imageTab.setText("Image");
tabList.addTab(imageTab, true);
scrollView.addComponent(imageGrid);
TabList.Tab videoTab = tabList.new Tab(getContext());
videoTab.setText("Video");
tabList.addTab(videoTab);
TabList.Tab audioTab = tabList.new Tab(getContext());
audioTab.setText("Audio");
tabList.addTab(audioTab);
3、选项卡切换状态需要监听选项卡的选中状态。我们可以在监听事件中对选项卡的业务逻辑做处理,其提供给我们三种方法,一当前选中的Tab,二取消选中的Tab,三再次选中当前Tab。在这三个方法中,我们可以具体的实现业务逻辑,比如当前选中的Tab被连续点击时,我们可以刷新我们呈现的内容。
tabList.addTabSelectedListener(new TabList.TabSelectedListener() {
@Override
public void onSelected(TabList.Tab tab) {
//TODO 具体业务逻辑代码
}
@Override
public void onUnselected(TabList.Tab tab) {
//TODO 具体业务逻辑代码
}
@Override
public void onReselected(TabList.Tab tab) {
//TODO 具体业务逻辑代码
}
});
4、顶部选项卡我们已经实现了,那么怎么去实现点击后内容的更改呢?这里就需要用到一个新的组件ScrollView,ScrollView是一种带有滚动功能的组件。如果我们使用常规的布局组件,内容超出范围后,上下左右滚动是需要我们自己去重写,而ScrollView组件只需要设置它的子组件方向即可。修改ability_main.xml代码添加ScrollView组件。
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:background_element="#444444"
ohos:orientation="vertical">
<TabList
... />
<ScrollView
ohos:id="$+id:tab_content"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:padding="10vp"
ohos:weight="9">
</ScrollView>
</DirectionalLayout>
5、首先初始化两个TableLayout组件,在其中添加多个子组件,用于显示图片列表和视频列表(仅供参考学习,未实现真正的图片和视频)。
private void initVideoGrid() {
videoGrid = new TableLayout(this);
videoGrid.setWidth(MATCH_PARENT);
videoGrid.setHeight(MATCH_CONTENT);
videoGrid.setColumnCount(1);
videoGrid.setRowCount(2);
for (int i = 1; i < 4; i++) {
Text text = new Text(this);
text.setWidth(MATCH_PARENT);
text.setHeight(800);
text.setTextAlignment(TextAlignment.CENTER);
text.setText("第" + i + "块视频");
ShapeElement shapeElement = new ShapeElement();
shapeElement.setCornerRadius(20);
shapeElement.setRgbColor(new RgbColor(192,0,255));
text.setBackground(shapeElement);
text.setPadding(10,10,10,10);
text.setMarginsTopAndBottom(10,10);
text.setMarginsLeftAndRight(20,20);
text.setTextSize(50);
videoGrid.addComponent(text);
}
}
private void initImageGrid() {
imageGrid = new TableLayout(this);
imageGrid.setWidth(MATCH_PARENT);
imageGrid.setHeight(MATCH_CONTENT);
imageGrid.setColumnCount(4);
imageGrid.setRowCount(2);
for (int i = 1; i <= 10; i++) {
Text text = new Text(this);
text.setWidth(400);
text.setHeight(400);
text.setTextAlignment(TextAlignment.CENTER);
text.setText("第" + i + "块图片");
ShapeElement shapeElement = new ShapeElement();
shapeElement.setCornerRadius(20);
shapeElement.setRgbColor(new RgbColor(0,192,255));
text.setBackground(shapeElement);
text.setPadding(10,10,10,10);
text.setMarginsTopAndBottom(10,10);
text.setMarginsLeftAndRight(20,20);
text.setTextSize(50);
imageGrid.addComponent(text);
}
}
6、 构建好各自的Tab的内容后,我们需要在选择监听中去做显示处理。选中图片后,需要加载图片列表,选中视频后,需要加载视频列表的同时移除图片列表,不然会存在小问题,你也可以尝试一下。看看出现了什么问题。
tabList.addTabSelectedListener(new TabList.TabSelectedListener() {
@Override
public void onSelected(TabList.Tab tab) {
if (tab.getPosition() == 0) {
scrollView.addComponent(imageGrid);
} else if (tab.getPosition() == 1) {
scrollView.addComponent(videoGrid);
} else {
scrollView.addComponent(new DirectionalLayout(getContext()));
}
HiLog.info(label, "onSelected:" + tab.getPosition());
}
@Override
public void onUnselected(TabList.Tab tab) {
if (tab.getPosition() == 0) {
scrollView.removeComponent(imageGrid);
} else if (tab.getPosition() == 1) {
scrollView.removeComponent(videoGrid);
} else {
scrollView.removeComponent(new DirectionalLayout(getContext()));
}
HiLog.info(label, "onUnselected:" + tab.getText());
}
@Override
public void onReselected(TabList.Tab tab) {
HiLog.info(label, "onReselected:" + tab.getText());
}
});
}
在这里我是以Tab的序号去判断选中后的操作,你也可以使用它的text属性来判断。到这里基本的功能已经实现了,我们运行查看一下效果。
图片中有个小Bug,你发现了吗?应该怎么解决这个问题呢?欢迎大家积极讨论^_^。
bug没看出来,有大佬指点下吗?
你这个实际上还是3个页面共用了同一个容器,滑动进度肯定是同步的。用fraction,相当于android的fragment
^_^,被你发现了
老师好,怎么实现TabList不均分呢,我仔细看了您和我的代码,一样,但是我的均分了,就是想实现Tab不会根据宽度均分。还有就是TabList需要共用一个TabContent吗,我没有共用,写了两个Layout,想通过显示隐藏的方式实现切换,但发现不行,显示了第二个后就再也切换不了了。但是想移除又不知道怎么移除。
怎样监听每个页签中的控件,比如在第一个页签中有一个按钮,单击后弹出一个提示语