HarmonyOS JAVA通用组件 精华

奶盖
发布于 2021-6-15 10:14
浏览
2收藏

1. 介绍

本篇Codelab目的

本篇Codelab旨在让开发者了解HarmonyOS应用开发常用布局和常用组件的使用方法,体验从工程创建到代码、布局的编写,再到编译构建、部署和运行的全过程。

您将会学到什么

  • 如何创建一个HarmonyOS Project并添加页面布局
  • 如何使用DirectionalLayout、DependentLayout、StackLayout、TableLayout等常用布局
  • 如何使用TabList、ListContainer、DatePicker、RadioContainer、Checkbox等常用组件

硬件要求

  • 操作系统:Windows10 64位
  • 内存:8G及以上
  • 硬盘:100G及以上
  • 分辨率:1280*800像素及以上

软件要求

  • 安装DevEco Studio,详情请参考DevEco Studio下载

  • 设置Huawei DevEco Studio开发环境,Huawei DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境

    1. 如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作
    2. 如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

说明
如需要在手机中运行程序,则需要提前生成秘钥和申请证书,如使用模拟器可忽略

技能要求

  1. Java基础开发能力
  2. XML布局文件编写能力

2. 下载Codelab起步应用

  1. 获取Codelab起步应用ComponentCodelab,可从gitee源码github源码下载
  2. 打开HUAWEI DevEco Studio,点击File > Open选择步骤1中下载的ComponentCodelab
  3. 点击Build > Build App(s)/Hap(s)>**Build Debug Hap(s)**构建hap包
  4. 点击**Run> Run ‘entry’**运行hap包,可看到运行效果如下:
    HarmonyOS JAVA通用组件-鸿蒙开发者社区

说明
此应用在模拟器或者真机上都可以运行。如果在真机上运行,则需要先在工程的File > Project Structure>Modules>Signing Configs配置签名和证书信息

3. 体验TabList和Tab组件

Tablist可以实现多个页签栏的切换,Tab为某个页签。子页签通常放在内容区上方,展示不同的分类。页签名称应该简洁明了,清晰描述分类的内容。TabList和Tab组件的使用方法详见常用组件开发指导

编写布局文件

在src/main/resources/base/layout目录下新建布局文件tab_list.xml,此布局文件中主要使用Tablist组件,并设置其样式。

<?xml version="1.0" encoding="utf-8"?> 
<DirectionalLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:width="match_parent" 
    ohos:height="match_parent" 
    ohos:top_margin="15vp" 
    ohos:orientation="vertical"> 
    <TabList 
        ohos:id="$+id:tab_list" 
        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="#afaafa" 
        ohos:selected_tab_indicator_color="#afaafa" 
        ohos:selected_tab_indicator_height="2vp"/> 
    <Text 
        ohos:id="$+id:tab_content" 
        ohos:width="match_parent" 
        ohos:height="match_parent" 
        ohos:text_alignment="center" 
        ohos:background_element="#70dbdb" 
        ohos:text_color="#2e2e2e" 
        ohos:text_size="16fp"/> 
</DirectionalLayout>

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建TabListSlice.java文件,继承AbilitySlice。
定义成员变量,加载布局:

private TabList tabList; 
private Text tabContent; 
 
@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_tab_list); 
    initComponent(); 
    addTabSelectedListener(); 
}

初始化组件:

private void initComponent() { 
    tabContent = (Text) findComponentById(ResourceTable.Id_tab_content); 
    tabList = (TabList) findComponentById(ResourceTable.Id_tab_list); 
    initTab(); 
} 
 
private void initTab() { 
    if (tabList.getTabCount() == 0) { 
        tabList.addTab(createTab("Image")); 
        tabList.addTab(createTab("Video")); 
        tabList.addTab(createTab("Audio")); 
        tabList.setFixedMode(true); 
        tabList.getTabAt(0).select(); 
        tabContent.setText("Select the " + tabList.getTabAt(0).getText()); 
    } 
} 
 
private TabList.Tab createTab(String text) { 
    TabList.Tab tab = tabList.new Tab(this); 
    tab.setText(text); 
    tab.setMinWidth(64); 
    tab.setPadding(12, 0, 12, 0); 
    return tab; 
}

绑定点击事件:

private void addTabSelectedListener() { 
    tabList.addTabSelectedListener(new TabList.TabSelectedListener() { 
        @Override 
        public void onSelected(TabList.Tab tab) { 
            tabContent.setText("Select the " + tab.getText()); 
        } 
 
        @Override 
        public void onUnselected(TabList.Tab tab) { 
        } 
 
        @Override 
        public void onReselected(TabList.Tab tab) { 
        } 
    }); 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_tab_list: 
            className = "com.huawei.codelab.slice.TabListSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的TabList and Tab即可看到TabList页面,点击页面上方不同的Tab,页面内容将同步变化。效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区 HarmonyOS JAVA通用组件-鸿蒙开发者社区

4. 体验ListContainer组件

ListContainer是用来呈现连续、多行数据的组件,包含一系列相同类型的列表项。ListContainer组件的使用方法详见常用组件开发指导。在本章节,我们将利用ListContainer组件编写一个新闻首页界面,上方的新闻类别和中间的新闻列表都将使用ListContainer组件来实现。

编写布局文件

在src/main/resources/base/layout目录下新建布局文件news_list_layout.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:orientation="vertical"> 
    <ListContainer 
        ohos:id="$+id:selector_list" 
        ohos:height="36vp" 
        ohos:width="match_parent" 
        ohos:top_padding="8vp" 
        ohos:orientation="horizontal"/> 
    <Component 
        ohos:height="1vp" 
        ohos:width="match_parent" 
        ohos:background_element="#70dbdb"/> 
    <ListContainer 
        ohos:id="$+id:news_container" 
        ohos:height="match_parent" 
        ohos:width="match_parent"/> 
</DirectionalLayout>

在src/main/resources/base/layout目录下新建布局文件item_news_type_layout.xml作为上方的新闻类别的item详情布局。

<?xml version="1.0" encoding="utf-8"?> 
<DirectionalLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:height="40vp" 
    ohos:width="match_content"> 
    <Text 
        ohos:id="$+id:news_type_text" 
        ohos:height="match_content" 
        ohos:width="match_content" 
        ohos:text_alignment="center" 
        ohos:left_padding="20vp" 
        ohos:right_padding="20vp" 
        ohos:text_color="#55000000" 
        ohos:text_size="16fp"/> 
</DirectionalLayout>

在src/main/resources/base/layout目录下新建布局文件item_news_layout.xml作为中间的新闻列表的item详情布局。

<?xml version="1.0" encoding="utf-8"?> 
<DirectionalLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:height="110vp" 
    ohos:width="match_parent" 
    ohos:orientation="vertical"> 
    <DirectionalLayout 
        ohos:height="109vp" 
        ohos:width="match_parent" 
        ohos:orientation="horizontal" 
        ohos:padding="10vp"> 
        <Text 
            ohos:id="$+id:item_news_title" 
            ohos:height="match_content" 
            ohos:width="0vp" 
            ohos:max_text_lines="3" 
            ohos:multiple_lines="true" 
            ohos:right_padding="20vp" 
            ohos:text_size="18vp" 
            ohos:weight="2"/> 
        <Image 
            ohos:id="$+id:item_news_image" 
            ohos:height="match_content" 
            ohos:width="0vp" 
            ohos:image_src="$media:news_image" 
            ohos:weight="1"/> 
    </DirectionalLayout> 
    <Component 
        ohos:height="1vp" 
        ohos:width="match_parent" 
        ohos:background_element="#70dbdb"/> 
</DirectionalLayout>

编写Provider文件

在src/main/java/com/huawei/codelab/provider目录下新建NewsTypeProvider.java文件,构造新闻类别的Provider。

public class NewsTypeProvider extends BaseItemProvider { 
    private String[] newsTypeList; 
    private Context context; 
 
    public NewsTypeProvider(String[] listBasicInfo, Context context) { 
        this.newsTypeList = listBasicInfo; 
        this.context = context; 
    } 
 
    @Override 
    public int getCount() { 
        return newsTypeList == null ? 0 : newsTypeList.length; 
    } 
 
    @Override 
    public Object getItem(int position) { 
        return Optional.of(this.newsTypeList[position]); 
    } 
 
    @Override 
    public long getItemId(int position) { 
        return position; 
    } 
 
    @Override 
    public Component getComponent(int position, Component componentP, ComponentContainer componentContainer) { 
        ViewHolder viewHolder = null; 
        Component component = componentP; 
        if (component == null) { 
            component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_news_type_layout, null, false); 
            viewHolder = new ViewHolder(); 
            Component componentText = component.findComponentById(ResourceTable.Id_news_type_text); 
            if (componentText instanceof Text) { 
                viewHolder.title = (Text) componentText; 
            } 
            component.setTag(viewHolder); 
        } else { 
            if (component.getTag() instanceof ViewHolder) { 
                viewHolder = (ViewHolder) component.getTag(); 
            } 
        } 
        if (viewHolder != null) { 
            viewHolder.title.setText(newsTypeList[position]); 
        } 
        return component; 
    } 
 
    private static class ViewHolder { 
        Text title; 
    } 
}

在src/main/java/com/huawei/codelab/provider目录下新建NewsListProvider.java文件,构造新闻列表的Provider。

public class NewsListProvider extends BaseItemProvider { 
    private List<NewsInfo> newsInfoList; 
    private Context context; 
 
    public NewsListProvider(List<NewsInfo> listBasicInfo, Context context) { 
        this.newsInfoList = listBasicInfo; 
        this.context = context; 
    } 
 
    @Override 
    public int getCount() { 
        return newsInfoList == null ? 0 : newsInfoList.size(); 
    } 
 
    @Override 
    public Object getItem(int position) { 
        return Optional.of(this.newsInfoList.get(position)); 
    } 
 
    @Override 
    public long getItemId(int position) { 
        return position; 
    } 
 
    @Override 
    public Component getComponent(int position, Component componentP, ComponentContainer componentContainer) { 
        ViewHolder viewHolder = null; 
        Component component = componentP; 
        if (component == null) { 
            component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_news_layout, null, false); 
            viewHolder = new ViewHolder(); 
            Component componentTitle = component.findComponentById(ResourceTable.Id_item_news_title); 
            Component componentImage = component.findComponentById(ResourceTable.Id_item_news_image); 
            if (componentTitle instanceof Text) { 
                viewHolder.title = (Text) componentTitle; 
            } 
            if (componentImage instanceof Image) { 
                viewHolder.image = (Image) componentImage; 
            } 
            component.setTag(viewHolder); 
        } else { 
            if (component.getTag() instanceof ViewHolder) { 
                viewHolder = (ViewHolder) component.getTag(); 
            } 
        } 
        if (viewHolder != null) { 
            viewHolder.title.setText(newsInfoList.get(position).getTitle()); 
            viewHolder.image.setScaleMode(Image.ScaleMode.STRETCH); 
        } 
        return component; 
    } 
 
    private static class ViewHolder { 
        Text title; 
        Image image; 
    } 
}

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建ListContainerSlice.java文件,继承AbilitySlice。
定义成员变量,加载布局:

private static final float FOCUS_TEXT_SIZE = 1.2f; 
private static final float UNFOCUS_TEXT_SIZE = 1.0f; 
private Text selectText; 
private ListContainer newsListContainer; 
private ListContainer selectorListContainer; 
private List<NewsInfo> totalNews; 
private List<NewsInfo> selectNews; 
private NewsTypeProvider newsTypeProvider; 
private NewsListProvider newsListProvider; 
 
@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_news_list_layout); 
    initView(); 
    initProvider(); 
    setListContainer(); 
    initListener(); 
}

初始化组件:

private void initView() { 
    selectorListContainer = (ListContainer) findComponentById(ResourceTable.Id_selector_list); 
    newsListContainer = (ListContainer) findComponentById(ResourceTable.Id_news_container); 
}

使用POJO类封装数据源中与每个列表项对应的数据:

public class NewsInfo { 
    private String title; 
    private String type; 
 
    public String getTitle() { 
        return title; 
    } 
 
    public void setTitle(String title) { 
        this.title = title; 
    } 
 
    public String getType() { 
        return type; 
    } 
 
    public void setType(String type) { 
        this.type = type; 
    } 
}

初始化Provider:

private void initProvider() { 
    String[] listNames = new String[]{"All", "Health", "Finance", "Technology", "Sport", "Internet", "Game"}; 
    newsTypeProvider = new NewsTypeProvider(listNames, this); 
    newsTypeProvider.notifyDataChanged(); 
 
    String[] newsTypes = new String[]{"Health", "Finance", "Finance", "Technology", "Sport", "Health", "Internet", "Game", "Game", "Internet"}; 
    String[] newsTitles = new String[]{ 
        "Best Enterprise Wi-Fi Network Award of the Wireless Broadband Alliance 2020", 
        "Openness and Cooperation Facilitate Industry Upgrade", 
        "High-voltage super-fast charging is an inevitable trend", 
        "Ten Future Trends of Digital Energy", 
        "Ascend Helps Industry, Learning, and Research Promote AI Industry Development in the National AI Contest", 
        "Enterprise data centers are moving towards autonomous driving network", 
        "One optical fiber lights up a green smart room", 
        "Trust technology, embrace openness, and share the world prosperity brought by technology", 
        "Intelligent Twins Won the Leading Technology Achievement Award at the 7th World Internet Conference", 
        "Maximizing the Value of Wireless Networks and Ushering in the Golden Decade of 5G" 
    }; 
    totalNews = new ArrayList<>(); 
    selectNews = new ArrayList<>(); 
    for (int i = 0; i < newsTypes.length; i++) { 
        NewsInfo newsInfo = new NewsInfo(); 
        newsInfo.setTitle(newsTitles[i]); 
        newsInfo.setType(newsTypes[i]); 
        totalNews.add(newsInfo); 
    } 
    selectNews.addAll(totalNews); 
    newsListProvider = new NewsListProvider(selectNews, this); 
    newsListProvider.notifyDataChanged(); 
}

将Provider应用到ListContainer:

private void  setListContainer() { 
    selectorListContainer.setItemProvider(newsTypeProvider); 
    newsListContainer.setItemProvider(newsListProvider); 
}

为ListContainer绑定点击事件:

private void initListener() { 
    selectorListContainer.setItemClickedListener((listContainer, component, position, listener) -> { 
        setCategorizationFocus(false); 
        Component newsTypeText = component.findComponentById(ResourceTable.Id_news_type_text); 
        if (newsTypeText instanceof Text) { 
            selectText = (Text) newsTypeText; 
        } 
        setCategorizationFocus(true); 
        selectNews.clear(); 
        if (position == 0) { 
            selectNews.addAll(totalNews); 
        } else { 
            String newsType = selectText.getText(); 
            for (NewsInfo newsData : totalNews) { 
                if (newsType.equals(newsData.getType())) { 
                    selectNews.add(newsData); 
                } 
            } 
        } 
        updateListView(); 
    }); 
    selectorListContainer.setSelected(true); 
    selectorListContainer.setSelectedItemIndex(0); 
} 
 
private void setCategorizationFocus(boolean isFocus) { 
    if (selectText == null) { 
        return; 
    } 
    if (isFocus) { 
        selectText.setTextColor(new Color(Color.getIntColor("#afaafa"))); 
        selectText.setScaleX(FOCUS_TEXT_SIZE); 
        selectText.setScaleY(FOCUS_TEXT_SIZE); 
    } else { 
        selectText.setTextColor(new Color(Color.getIntColor("#999999"))); 
        selectText.setScaleX(UNFOCUS_TEXT_SIZE); 
        selectText.setScaleY(UNFOCUS_TEXT_SIZE); 
    } 
} 
 
private void updateListView() { 
    newsListProvider.notifyDataChanged(); 
    newsListContainer.invalidate(); 
    newsListContainer.scrollToCenter(0); 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_list_container: 
            className = "com.huawei.codelab.slice.ListContainerSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的ListContainer即可看到新闻列表页面,点击页面上方不同的新闻类型,新闻列表会随之变化,效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区 HarmonyOS JAVA通用组件-鸿蒙开发者社区

5. 体验RadioContainer组件

RadioContainer是RadioButton的容器,在其包裹下的RadioButton保证只有一个被选项。RadioContainer组件的使用方法详见常用组件开发指导。在本章节,我们将利用RadioContainer组件编写一道单选题。

编写布局文件

在src/main/resources/base/layout目录下新建布局文件radio_container.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:alignment="horizontal_center" 
    ohos:orientation="vertical" 
    ohos:left_padding="32vp"> 
    <Text 
        ohos:height="match_content" 
        ohos:width="match_parent" 
        ohos:top_margin="32vp" 
        ohos:text="Question:Which of the following options belong to fruit?" 
        ohos:text_size="20fp" 
        ohos:layout_alignment="left" 
        ohos:multiple_lines="true"/> 
    <DirectionalLayout 
        ohos:height="match_content" 
        ohos:width="match_parent" 
        ohos:orientation="horizontal" 
        ohos:top_margin="8vp"> 
        <Text 
            ohos:height="match_content" 
            ohos:width="match_content" 
            ohos:text="Your Answer:" 
            ohos:text_size="20fp"/> 
        <Text 
            ohos:id="$+id:answer" 
            ohos:height="match_content" 
            ohos:width="match_content" 
            ohos:text_size="20fp" 
            ohos:left_margin="18vp" 
            ohos:text="[]" 
            ohos:text_color="#FF3333"/> 
    </DirectionalLayout> 
    <RadioContainer 
        ohos:id="$+id:radio_container" 
        ohos:height="match_content" 
        ohos:width="200vp" 
        ohos:layout_alignment="left" 
        ohos:orientation="vertical" 
        ohos:top_margin="16vp" 
        ohos:left_margin="4vp"> 
        <RadioButton 
            ohos:id="$+id:radio_button_1" 
            ohos:height="40vp" 
            ohos:width="match_content" 
            ohos:text="A.Apple" 
            ohos:text_size="20fp" 
            ohos:text_color_on="#FF3333"/> 
        <RadioButton 
            ohos:id="$+id:radio_button_2" 
            ohos:height="40vp" 
            ohos:width="match_content" 
            ohos:text="B.Potato" 
            ohos:text_size="20fp" 
            ohos:text_color_on="#FF3333"/> 
        <RadioButton 
            ohos:id="$+id:radio_button_3" 
            ohos:height="40vp" 
            ohos:width="match_content" 
            ohos:text="C.Pumpkin" 
            ohos:text_size="20fp" 
            ohos:text_color_on="#FF3333"/> 
        <RadioButton 
            ohos:id="$+id:radio_button_4" 
            ohos:height="40vp" 
            ohos:width="match_content" 
            ohos:text="D.Vegetables" 
            ohos:text_size="20fp" 
            ohos:text_color_on="#FF3333"/> 
    </RadioContainer> 
</DirectionalLayout>

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建RadioContainerSlice.java文件,继承AbilitySlice。
加载布局:

@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_radio_container); 
    initComponent(); 
}

通过以下方法,定义RadioButton的背景:

private StateElement getStateElement() { 
    ShapeElement elementButtonOn = new ShapeElement(); 
    elementButtonOn.setRgbColor(RgbPalette.RED); 
    elementButtonOn.setShape(ShapeElement.OVAL); 
 
    ShapeElement elementButtonOff = new ShapeElement(); 
    elementButtonOff.setRgbColor(RgbPalette.DARK_GRAY); 
    elementButtonOff.setShape(ShapeElement.OVAL); 
 
    StateElement checkElement = new StateElement(); 
    checkElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, elementButtonOn); 
    checkElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, elementButtonOff); 
    return checkElement; 
}

初始化组件并设置响应RadioContainer状态改变的事件,显示单选结果:

private void initComponent() { 
    Text answer = (Text) findComponentById(ResourceTable.Id_answer); 
    RadioContainer container = (RadioContainer)findComponentById(ResourceTable.Id_radio_container); 
    int count = container.getChildCount(); 
    for (int i = 0; i < count; i++) { 
        ((RadioButton) container.getComponentAt(i)).setButtonElement(getStateElement()); 
    } 
    container.setMarkChangedListener((radioContainer1, index) -> { 
        answer.setText(String.format("[%c]", (char)('A'+index))); 
    }); 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_radio_container: 
            className = "com.huawei.codelab.slice.RadioContainerSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的RadioContainer即可看到单选题页面,点击不同的选项,单选结果将同步刷新。效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区 HarmonyOS JAVA通用组件-鸿蒙开发者社区

6. 体验Checkbox组件

Checkbox可以实现选中和取消选中的功能。Checkbox组件的使用方法详见常用组件开发指导。在本章节,我们将利用Checkbox组件编写一道多选题。

编写布局文件

在src/main/resources/base/layout目录下新建布局文件checkbox.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:alignment="horizontal_center" 
    ohos:orientation="vertical" 
    ohos:left_padding="32vp"> 
    <Text 
        ohos:height="match_content" 
        ohos:width="match_parent" 
        ohos:top_margin="32vp" 
        ohos:text="Question:Which of the following options belong to fruit?" 
        ohos:text_size="20fp" 
        ohos:layout_alignment="left" 
        ohos:multiple_lines="true"/> 
    <DirectionalLayout 
        ohos:height="match_content" 
        ohos:width="match_parent" 
        ohos:orientation="horizontal" 
        ohos:top_margin="8vp"> 
        <Text 
            ohos:height="match_content" 
            ohos:width="match_content" 
            ohos:text="Your Answer:" 
            ohos:text_size="20fp"/> 
        <Text 
            ohos:id="$+id:answer" 
            ohos:height="match_content" 
            ohos:width="match_content" 
            ohos:text_size="20fp" 
            ohos:left_margin="18vp" 
            ohos:text="[]" 
            ohos:text_color="#FF3333"/> 
    </DirectionalLayout> 
    <RadioContainer 
        ohos:id="$+id:radio_container" 
        ohos:height="match_content" 
        ohos:width="200vp" 
        ohos:layout_alignment="left" 
        ohos:orientation="vertical" 
        ohos:top_margin="16vp" 
        ohos:left_margin="4vp"> 
        <RadioButton 
            ohos:id="$+id:radio_button_1" 
            ohos:height="40vp" 
            ohos:width="match_content" 
            ohos:text="A.Apple" 
            ohos:text_size="20fp" 
            ohos:text_color_on="#FF3333"/> 
        <RadioButton 
            ohos:id="$+id:radio_button_2" 
            ohos:height="40vp" 
            ohos:width="match_content" 
            ohos:text="B.Potato" 
            ohos:text_size="20fp" 
            ohos:text_color_on="#FF3333"/> 
        <RadioButton 
            ohos:id="$+id:radio_button_3" 
            ohos:height="40vp" 
            ohos:width="match_content" 
            ohos:text="C.Pumpkin" 
            ohos:text_size="20fp" 
            ohos:text_color_on="#FF3333"/> 
        <RadioButton 
            ohos:id="$+id:radio_button_4" 
            ohos:height="40vp" 
            ohos:width="match_content" 
            ohos:text="D.Vegetables" 
            ohos:text_size="20fp" 
            ohos:text_color_on="#FF3333"/> 
    </RadioContainer> 
</DirectionalLayout>

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建CheckboxSlice.java文件,继承AbilitySlice。
定义成员变量,加载布局:

@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_radio_container); 
    initComponent(); 
}

通过以下方法设置Checkbox的背景:

private StateElement getStateElement() { 
    ShapeElement elementButtonOn = new ShapeElement(); 
    elementButtonOn.setRgbColor(RgbPalette.RED); 
    elementButtonOn.setShape(ShapeElement.OVAL); 
 
    ShapeElement elementButtonOff = new ShapeElement(); 
    elementButtonOff.setRgbColor(RgbPalette.DARK_GRAY); 
    elementButtonOff.setShape(ShapeElement.OVAL); 
 
    StateElement checkElement = new StateElement(); 
    checkElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, elementButtonOn); 
    checkElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, elementButtonOff); 
    return checkElement; 
}

通过以下方法订阅Checkbox状态变化:

private StateElement getStateElement() { 
    ShapeElement elementButtonOn = new ShapeElement(); 
    elementButtonOn.setRgbColor(RgbPalette.RED); 
    elementButtonOn.setShape(ShapeElement.OVAL); 
 
    ShapeElement elementButtonOff = new ShapeElement(); 
    elementButtonOff.setRgbColor(RgbPalette.DARK_GRAY); 
    elementButtonOff.setShape(ShapeElement.OVAL); 
 
    StateElement checkElement = new StateElement(); 
    checkElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, elementButtonOn); 
    checkElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, elementButtonOff); 
    return checkElement; 
}

初始化Checkbox并设置订阅事件:

private void initComponent() { 
    Text answer = (Text) findComponentById(ResourceTable.Id_answer); 
    RadioContainer container = (RadioContainer)findComponentById(ResourceTable.Id_radio_container); 
    int count = container.getChildCount(); 
    for (int i = 0; i < count; i++) { 
        ((RadioButton) container.getComponentAt(i)).setButtonElement(getStateElement()); 
    } 
    container.setMarkChangedListener((radioContainer1, index) -> { 
        answer.setText(String.format("[%c]", (char)('A'+index))); 
    }); 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_checkbox: 
            className = "com.huawei.codelab.slice.CheckboxSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的Checkbox即可看到多选题页面,点击不同的选项,多选结果将同步刷新。效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区 HarmonyOS JAVA通用组件-鸿蒙开发者社区

7. 体验DatePicker组件

DatePicker主要供用户选择日期。DatePicker组件的使用方法详见常用组件开发指导。在本章节,我们将利用DatePicker组件编写一个日期选择小程序。

编写布局文件

在src/main/resources/base/layout目录下新建布局文件data_picker.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:orientation="vertical" 
    ohos:left_padding="32vp"> 
    <Text 
        ohos:height="match_content" 
        ohos:width="match_parent" 
        ohos:top_margin="32vp" 
        ohos:text="Question:Which of the following are fruits?" 
        ohos:text_size="20fp" 
        ohos:layout_alignment="left" 
        ohos:multiple_lines="true"/> 
    <DirectionalLayout 
        ohos:height="match_content" 
        ohos:width="match_parent" 
        ohos:orientation="horizontal" 
        ohos:top_margin="8vp"> 
        <Text 
            ohos:height="match_content" 
            ohos:width="match_content" 
            ohos:text="Your Answer:" 
            ohos:text_size="20fp"/> 
        <Text 
            ohos:id="$+id:text_answer" 
            ohos:height="match_content" 
            ohos:width="match_content" 
            ohos:text_size="20fp" 
            ohos:left_margin="18vp" 
            ohos:text="[]" 
            ohos:text_color="#FF3333"/> 
    </DirectionalLayout> 
    <Checkbox 
        ohos:id="$+id:checkbox_1" 
        ohos:top_margin="20vp" 
        ohos:height="match_content" 
        ohos:width="match_content" 
        ohos:text="A Apples" 
        ohos:text_size="20fp" 
        ohos:text_color_on="#FF3333" 
        ohos:text_color_off="#000000"/> 
    <Checkbox 
        ohos:id="$+id:checkbox_2" 
        ohos:top_margin="20vp" 
        ohos:height="match_content" 
        ohos:width="match_content" 
        ohos:text="B Bananas" 
        ohos:text_size="20fp" 
        ohos:text_color_on="#FF3333" 
        ohos:text_color_off="#000000"/> 
    <Checkbox 
        ohos:id="$+id:checkbox_3" 
        ohos:top_margin="20vp" 
        ohos:height="match_content" 
        ohos:width="match_content" 
        ohos:text="C Strawberries" 
        ohos:text_size="20fp" 
        ohos:text_color_on="#FF3333" 
        ohos:text_color_off="#000000" /> 
    <Checkbox 
        ohos:id="$+id:checkbox_4" 
        ohos:top_margin="20vp" 
        ohos:height="match_content" 
        ohos:width="match_content" 
        ohos:text="D Potatoes" 
        ohos:text_size="20fp" 
        ohos:text_color_on="#FF3333" 
        ohos:text_color_off="black" /> 
</DirectionalLayout>

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建DatePickerSlice.java文件,继承AbilitySlice。
定义成员变量,加载布局:

private Text answer; 
private Set<String> selectedSet = new HashSet<>(); 
 
@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_checkbox); 
    answer = (Text) findComponentById(ResourceTable.Id_text_answer); 
    initCheckbox(); 
}

初始化组件:

private void initComponent() { 
    datePicker = (DatePicker) findComponentById(ResourceTable.Id_date_pick); 
    textDate = (Text) findComponentById(ResourceTable.Id_text_date); 
}

显示初始日期:

private void initDate() { 
    int day = datePicker.getDayOfMonth(); 
    int month = datePicker.getMonth(); 
    int year = datePicker.getYear(); 
    textDate.setText(String.format("%02d/%02d/%4d", day, month, year)); 
}

为DatePicker设置订阅事件:

private void setValueChangedListener(){ 
    datePicker.setValueChangedListener( 
        new DatePicker.ValueChangedListener() { 
            @Override 
            public void onValueChanged(DatePicker picker, int year, int monthOfYear, int dayOfMonth) { 
                textDate.setText(String.format("%02d/%02d/%4d", dayOfMonth, monthOfYear, year)); 
            } 
        } 
    ); 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_date_picker: 
            className = "com.huawei.codelab.slice.DatePickerSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的DatePicker即可看到日期选择页面,默认显示当前日期;滑动年/月/日,下面显示的日期将同步刷新。效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区 HarmonyOS JAVA通用组件-鸿蒙开发者社区

8. 体验DirectionalLayout布局

DirectionalLayout是Java UI中的一种重要组件布局,用于将一组组件(Component)按照水平或者垂直方向排布,能够方便地对齐布局内的组件。DirectionalLayout布局的使用方法详见常用布局开发指导。在此章节,我们将利用DirectionalLayout布局编写一个中秋灯谜列表。

编写布局文件

在src/main/resources/base/layout目录下新建布局文件directional_layout.xml。

<?xml version="1.0" encoding="utf-8"?> 
<DirectionalLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:width="match_parent" 
    ohos:height="match_parent" 
    ohos:top_margin="13fp" 
    ohos:orientation="vertical"> 
    <Text 
        ohos:width="match_content" 
        ohos:height="match_content" 
        ohos:text="Lantern riddles of Mid Autumn Festival" 
        ohos:text_alignment="center" 
        ohos:multiple_lines="true" 
        ohos:layout_alignment="center" 
        ohos:top_margin="20vp" 
        ohos:text_size="23vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="1.what man cannot live in a house?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="2.What never asks questions but gets a lot of answers?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="3.A mouse has a large pocket.What is it?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="4.What can hear you without ears and can answer you without a mouth?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="5.What is higher without a head than with a head?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="6.What is dark but made by light?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="7.What person tried to make you smile most of the time?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="8.You have it.You read it.There're some pictures in it?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="9.What animal has a head like a cat, eyes like a cat, a tail like a cat, but isn't a cat? " 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
    <Text 
        ohos:width="match_parent" 
        ohos:height="match_content" 
        ohos:text="10.What has hands but no feet, a face but no eyes, tells but not talk?" 
        ohos:multiple_lines="true" 
        ohos:left_margin="20vp" 
        ohos:top_margin="20vp" 
        ohos:text_size="18vp"/> 
</DirectionalLayout>

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建DirectionalLayoutSlice.java文件,继承AbilitySlice。
加载布局:

@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_directional_layout); 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_directional_layout: 
            className = "com.huawei.codelab.slice.DirectionalLayoutSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的DirectionalLayout即可看到中秋灯谜页面。效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区

9. 体验DependentLayout布局

DependentLayout是Java UI系统里的一种常见布局。与DirectionalLayout相比,拥有更多的排布方式,每个组件可以指定相对于其他同级元素的位置,或者指定相对于父组件的位置。DependentLayout布局的使用方法可详见常用布局开发指导。在本章节,我们将利用DirectionalLayout和DependentLayout布局编写一个新闻详情页面。

编写布局文件

在src/main/resources/base/layout目录下新建布局文件dependent_layout.xml。

<?xml version="1.0" encoding="utf-8"?> 
<DependentLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:id="$+id:parent_layout" 
    ohos:height="match_parent" 
    ohos:width="match_parent"> 
    <ScrollView 
        ohos:height="match_parent" 
        ohos:width="match_parent"> 
        <DirectionalLayout 
            ohos:height="match_content" 
            ohos:width="match_parent" 
            ohos:bottom_padding="70vp" 
            ohos:orientation="vertical"> 
            <DirectionalLayout 
                ohos:height="match_content" 
                ohos:width="match_parent" 
                ohos:alignment="vertical_center" 
                ohos:orientation="horizontal" 
                ohos:background_element="#FFFFFF"> 
                <Text 
                    ohos:id="$+id:title_icon" 
                    ohos:height="match_content" 
                    ohos:width="match_content" 
                    ohos:text="NewsDemo" 
                    ohos:left_margin="20vp" 
                    ohos:text_size="20fp" 
                    ohos:weight="1"/> 
                <Text 
                    ohos:id="$+id:read_num" 
                    ohos:height="match_content" 
                    ohos:width="match_content" 
                    ohos:right_margin="10vp" 
                    ohos:text="reads:10" 
                    ohos:text_size="10fp"/> 
                <Text 
                    ohos:id="$+id:likes_num" 
                    ohos:height="match_content" 
                    ohos:width="match_content" 
                    ohos:right_margin="20vp" 
                    ohos:text="likes:9" 
                    ohos:text_size="10fp"/> 
            </DirectionalLayout> 
            <Text 
                ohos:id="$+id:title_text" 
                ohos:height="match_content" 
                ohos:width="match_parent" 
                ohos:left_margin="20vp" 
                ohos:max_text_lines="4" 
                ohos:multiple_lines="true" 
                ohos:right_margin="20vp" 
                ohos:text="Ten Future Trends of Digital Energy" 
                ohos:text_color="#000000" 
                ohos:text_size="18fp" 
                ohos:top_margin="10vp"/> 
            <Text 
                ohos:id="$+id:title_content" 
                ohos:height="match_content" 
                ohos:width="match_parent" 
                ohos:left_margin="20vp" 
                ohos:multiple_lines="true" 
                ohos:right_margin="20vp" 
                ohos:text="Energy digitalization is an inevitable trend. Innovative integration of digital and energy technologies enables end-to-end visual, manageable, and controllable intelligent management of energy infrastructure, improving energy efficiency." 
                ohos:text_alignment="center_horizontal" 
                ohos:text_color="#708090" 
                ohos:text_size="16fp" 
                ohos:top_margin="5vp"/> 
            <DirectionalLayout 
                ohos:height="match_content" 
                ohos:width="match_parent" 
                ohos:orientation="horizontal"> 
                <Image 
                    ohos:id="$+id:image_content1" 
                    ohos:height="100vp" 
                    ohos:width="0vp" 
                    ohos:image_src="$media:news_image_left" 
                    ohos:layout_alignment="center" 
                    ohos:left_margin="20vp" 
                    ohos:right_margin="2vp" 
                    ohos:top_margin="10vp" 
                    ohos:weight="1"/> 
                <Image 
                    ohos:id="$+id:image_content2" 
                    ohos:height="100vp" 
                    ohos:width="0vp" 
                    ohos:image_src="$media:news_image" 
                    ohos:layout_alignment="center" 
                    ohos:left_margin="10vp" 
                    ohos:right_margin="2vp" 
                    ohos:top_margin="10vp" 
                    ohos:weight="1"/> 
                <Image 
                    ohos:id="$+id:image_content3" 
                    ohos:height="100vp" 
                    ohos:width="0vp" 
                    ohos:image_src="$media:news_image_right" 
                    ohos:layout_alignment="center" 
                    ohos:left_margin="2vp" 
                    ohos:right_margin="20vp" 
                    ohos:top_margin="10vp" 
                    ohos:weight="1"/> 
            </DirectionalLayout> 
        </DirectionalLayout> 
    </ScrollView> 
    <Component 
        ohos:height="0.5vp" 
        ohos:width="match_parent" 
        ohos:above="$+id:bottom_layout" 
        ohos:background_element="#EAEAEC"/> 
    <DirectionalLayout 
        ohos:id="$+id:bottom_layout" 
        ohos:height="50vp" 
        ohos:width="match_parent" 
        ohos:align_parent_bottom="true" 
        ohos:alignment="vertical_center" 
        ohos:background_element="#ffffff" 
        ohos:left_padding="20vp" 
        ohos:orientation="horizontal" 
        ohos:right_padding="20vp"> 
        <TextField 
            ohos:height="30vp" 
            ohos:width="160vp" 
            ohos:background_element="$graphic:corner_bg_comment" 
            ohos:hint="Enter a comment." 
            ohos:left_padding="5vp" 
            ohos:right_padding="10vp" 
            ohos:text_alignment="vertical_center" 
            ohos:text_size="15vp"/> 
        <Image 
            ohos:height="20vp" 
            ohos:width="20vp" 
            ohos:scale_mode="stretch" 
            ohos:image_src="$media:message_icon" 
            ohos:left_margin="20vp"/> 
        <Image 
            ohos:height="20vp" 
            ohos:width="20vp" 
            ohos:scale_mode="stretch" 
            ohos:image_src="$media:collect_icon" 
            ohos:left_margin="20vp"/> 
        <Image 
            ohos:height="20vp" 
            ohos:width="20vp" 
            ohos:scale_mode="stretch" 
            ohos:image_src="$media:like_icon" 
            ohos:left_margin="20vp"/> 
        <Image 
            ohos:height="20vp" 
            ohos:width="20vp" 
            ohos:scale_mode="stretch" 
            ohos:image_src="$media:share_icon" 
            ohos:left_margin="20vp"/> 
    </DirectionalLayout> 
</DependentLayout>

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建DependentLayoutSlice.java文件,继承AbilitySlice。
加载布局:

@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_dependent_layout); 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_dependent_layout: 
            className = "com.huawei.codelab.slice.DependentLayoutSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的DependentLayout即可看到新闻详情页面,效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区

10. 体验StackLayout布局

StackLayout直接在屏幕上开辟出一块空白的区域,添加到这个布局中的视图都是以层叠的方式显示,而它会把这些视图默认放到这块区域的左上角,第一个添加到布局中的视图显示在最底层,最后一个被放在最顶层。上一层的视图会覆盖下一层的视图。StackLayout布局的使用方法详见常用布局开发指导

编写布局文件

在src/main/resources/base/layout目录下新建布局文件stack_layout.xml。

<?xml version="1.0" encoding="utf-8"?> 
<StackLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:id="$+id:stack_layout" 
    ohos:height="match_parent" 
    ohos:width="match_parent"> 
    <Text 
        ohos:id="$+id:text_blue" 
        ohos:text_alignment="bottom|horizontal_center" 
        ohos:text_size="24fp" 
        ohos:text="Layer1" 
        ohos:height="400vp" 
        ohos:width="match_parent" 
        ohos:background_element="#70dbdb" /> 
    <Text 
        ohos:id="$+id:text_light_purple" 
        ohos:text_alignment="bottom|horizontal_center" 
        ohos:text_size="24fp" 
        ohos:text="Layer2" 
        ohos:height="300vp" 
        ohos:width="300vp" 
        ohos:background_element="#EED2EE" /> 
    <Text 
        ohos:id="$+id:text_green" 
        ohos:text_alignment="center" 
        ohos:text_size="24fp" 
        ohos:text="Layer3" 
        ohos:height="200vp" 
        ohos:width="200vp" 
        ohos:background_element="#B4EEB4" /> 
</StackLayout>

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建StackLayoutSlice.java文件,继承AbilitySlice。
加载布局:

@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_stack_layout); 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_stack_layout: 
            className = "com.huawei.codelab.slice.StackLayoutSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的StackLayout即可看到页面效果如下:

HarmonyOS JAVA通用组件-鸿蒙开发者社区

11. 体验TableLayout布局

TableLayout使用表格的方式划分子组件。TableLayout布局的使用方法详见常用组件开发指导。在本章节,我们将利用TableLayout布局编写一个拨号盘。

编写布局文件

在src/main/resources/base/layout目录下新建布局文件table_layout.xml。

<?xml version="1.0" encoding="utf-8"?> 
<DirectionalLayout 
    xmlns:ohos="http://schemas.huawei.com/res/ohos" 
    ohos:width="match_parent" 
    ohos:height="match_parent" 
    ohos:background_element="#EDEDED" 
    ohos:layout_alignment="center" 
    ohos:orientation="vertical"> 
    <Text 
        ohos:id="$+id:info" 
        ohos:width="match_content" 
        ohos:height="30vp" 
        ohos:text_size="20fp" 
        ohos:top_margin="20vp" 
        ohos:text="" 
        ohos:text_alignment="center" 
        ohos:layout_alignment="horizontal_center"/> 
    <TableLayout 
        ohos:id="$+id:table" 
        ohos:width="700" 
        ohos:height="match_content" 
        ohos:orientation="horizontal" 
        ohos:layout_alignment="horizontal_center" 
        ohos:top_margin="10" 
        ohos:column_count="3"> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="1" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="2" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="3" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="4" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="5" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="6" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="7" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="8" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="9" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="*" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="0" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:width="50vp" 
            ohos:height="50vp" 
            ohos:text_size="15fp" 
            ohos:left_margin="20vp" 
            ohos:top_margin="15vp" 
            ohos:background_element="$graphic:circle_button_element" 
            ohos:text="#" 
            ohos:text_alignment="center"/> 
    </TableLayout> 
    <DirectionalLayout 
        ohos:width="match_content" 
        ohos:height="match_content" 
        ohos:top_margin="20vp" 
        ohos:layout_alignment="horizontal_center" 
        ohos:orientation="horizontal"> 
        <Button 
            ohos:id="$+id:call" 
            ohos:width="60vp" 
            ohos:height="35vp" 
            ohos:text_size="15fp" 
            ohos:text="CALL" 
            ohos:background_element="$graphic:button_element" 
            ohos:text_alignment="center"/> 
        <Button 
            ohos:id="$+id:clear" 
            ohos:width="60vp" 
            ohos:height="35vp" 
            ohos:text_size="15fp" 
            ohos:text="CLEAR" 
            ohos:background_element="$graphic:button_element" 
            ohos:left_margin="10vp" 
            ohos:text_alignment="center"/> 
    </DirectionalLayout> 
</DirectionalLayout>

编写AbilitySlice文件

在src/main/java/com/huawei/codelab/slice目录下新建TableLayoutSlice.java文件,继承AbilitySlice。
定义成员变量,加载布局:

private Text info; 
private Button call; 
private Button clear; 
 
@Override 
public void onStart(Intent intent) { 
    super.onStart(intent); 
    super.setUIContent(ResourceTable.Layout_table_layout); 
    initComponent(); 
    setClickedListener(); 
}

初始化组件:

private void initComponent() { 
    info = (Text)findComponentById(ResourceTable.Id_info); 
    call = (Button)findComponentById(ResourceTable.Id_call); 
    clear = (Button)findComponentById(ResourceTable.Id_clear); 
}

设置点击事件:

private void setClickedListener() { 
    call.setClickedListener(new Component.ClickedListener() { 
        @Override 
        public void onClick(Component component) { 
            String toastInfo = info.getText(); 
            if (toastInfo == null || toastInfo.isEmpty()) { 
                toastInfo = "Please enter the number!"; 
            } else { 
                toastInfo = "Call " + info.getText(); 
            } 
            new ToastDialog(getContext()) 
                    .setText(toastInfo) 
                    .setAlignment(LayoutAlignment.CENTER) 
                    .setOffset(0,180) 
                    .show(); 
        } 
    }); 
 
    clear.setClickedListener(new Component.ClickedListener() { 
        @Override 
        public void onClick(Component component) { 
            info.setText(""); 
        } 
    }); 
 
    TableLayout table = (TableLayout)findComponentById(ResourceTable.Id_table); 
    int childNum = table.getChildCount(); 
    for (int index = 0; index < childNum; index++) { 
        Button child = (Button)(table.getComponentAt(index)); 
        child.setClickedListener(new Component.ClickedListener() { 
            @Override 
            public void onClick(Component component) { 
                if (component instanceof Button) { 
                    Button button = (Button)component; 
                    info.setText(info.getText() + button.getText()); 
                } 
            } 
        }); 
    } 
}

关联主页跳转

在src/main/java/com/huawei/codelab/slice/MainAbilitySlice.java的onClick方法中增加关联跳转。

@Override 
public void onClick(Component component) { 
    String className = ""; 
    switch (component.getId()) { 
        case ResourceTable.Id_table_layout: 
            className = "com.huawei.codelab.slice.TableLayoutSlice"; 
            break; 
        default: 
            break; 
    } 
    abilitySliceJump(className); 
}

运行程序

点击**Run> Run ‘entry’**运行hap包,进入到程序主页,点击主页的TableLayout即可看到拨号盘页面。点击拨号盘上的按钮,拨号盘上方会显示输入的号码;点击拨号盘下方的CLEAR按钮,拨号盘上方显示内容将清空。效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区 HarmonyOS JAVA通用组件-鸿蒙开发者社区

点击下方的CALL按钮,将弹出ToastDialog,效果如下所示:

HarmonyOS JAVA通用组件-鸿蒙开发者社区 HarmonyOS JAVA通用组件-鸿蒙开发者社区

说明
此篇Codelab中的所有代码仅供demo演示参考使用。

12. 恭喜您

您已经成功完成了HarmonyOS Project开发常用布局和组件的体验,并学到了:

  • 如何创建一个手机HarmonyOS Project并添加页面布局
  • 如何使用DirectionalLayout、DependentLayout、StackLayout、TableLayout等常用布局
  • 如何使用TabList、ListContainer、DatePicker、RadioContainer、Checkbox等常用组件

如何在此篇Codelab的框架基础上实现一个组件或者布局?相信您的心中已有答案,快来试一试吧!

已于2021-6-15 10:14:36修改
3
收藏 2
回复
举报
2条回复
按时间正序
/
按时间倒序
mb609898e2cfb86
mb609898e2cfb86

很详细的Codelab讲解,学习了!

回复
2021-6-15 10:20:57
Yue_A_人们
Yue_A_人们

学到了

回复
2021-6-15 19:22:28
回复
    相关推荐