HarmonyOS官方模板学习之Category Ability(Java)

开发 后端 OpenHarmony
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

[[406362]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

Category Ability(Java)

介绍

使用Java语言开发,用于Phone设备的Feature Ability模板,使用XML布局,显示分类页效果。

搭建环境

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

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

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。

如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境。

代码结构解读

注意:'#'代表注释

功能逻辑代码

  1. ├─java 
  2. │  └─com 
  3. │      └─buty 
  4. │          └─categoryabilityjava 
  5. │              │  MainAbility.java 
  6. │              │  MyApplication.java 
  7. │              │ 
  8. │              ├─data 
  9. │              │      CategoryData.java #用来构造分类数据 
  10. │              │ 
  11. │              ├─model 
  12. │              │      CategoryList.java #分类列表模型 
  13. │              │      Item.java #子项模型 
  14. │              │      ItemChild.java #小子项模型 
  15. │              │      ItemList.java #子项列表模型 
  16. │              │ 
  17. │              ├─provider 
  18. │              │      CategoryListProvider.java #继承自BaseItemProvider为ListContainer提供数据 
  19. │              │ 
  20. │              ├─slice 
  21. │              │      MainAbilitySlice.java #主页片 
  22. │              │ 
  23. │              ├─utils 
  24. │              │      ElementUtil.java #获取element颜色值, 
  25. │              │      LogUtils.java #日志工具类 
  26. │              │      Toast.java #Toast工具类 
  27. │              │ 
  28. │              └─view 
  29. │                      GridAdapter.java #grid适配器,适配不同的gridview 
  30. │                      GridView.java #自定义组件,类似grid,继承自TableLayout并且实现Component.LayoutRefreshedListener 
  31. │ 

布局及样式代码

  1. └─resources 
  2.     ├─base 
  3.     │  ├─element 
  4.     │  │      color.json 
  5.     │  │      float.json 
  6.     │  │      string.json 
  7.     │  │ 
  8.     │  ├─graphic 
  9.     │  │      background_ability_main.xml 
  10.     │  │      background_item_grid_per.xml 
  11.     │  │      background_search_bar.xml 
  12.     │  │ 
  13.     │  ├─layout 
  14.     │  │      ability_main.xml  #主页面 
  15.     │  │      category_list_per.xml #每个分类组件 
  16.     │  │      item_child_per.xml #分类下面的子类别 
  17.     │  │      item_child_per_grid_per.xml #子类别下的网格项组件 
  18.     │  │      item_grid_per.xml #分类下面的网格项 
  19.     │  │      search_bar.xml #search组件 
  20.     │  │      tab.xml #单个tab组件 
  21.     │  │      title_bar.xml #标题组件 
  22.     │  │ 
  23.     │  ├─media 
  24.     │  │      addIcon.png 
  25.     │  │      icon.png 
  26.     │  │      icon_actived.png 
  27.     │  │      icon_normal.png 
  28.     │  │      rightIcon.png 
  29.     │  │      searchIcon.png 
  30.     │  │ 
  31.     │  └─profile 
  32.     ├─en 
  33.     │  └─element 
  34.     │          string.json 
  35.     │ 
  36.     ├─rawfile 
  37.     └─zh 
  38.         └─element 
  39.                 string.json 

效果展示

我们先看一下运行起来的效果

HarmonyOS官方模板学习 之 Category Ability(Java)-鸿蒙HarmonyOS技术社区

相关权限

不需要额外申请权限

页面布局

1.ability_main.xml #主页面

页面的布局包括DependentLayout和DirectionalLayout布局。

包括ListContainer、ScrollView、自定义的GridView 等组件

还使用了include标签来导入预设的组件,导入了search组件和标题组件。

HarmonyOS官方模板学习 之 Category Ability(Java)-鸿蒙HarmonyOS技术社区

2.category_list_per.xml #每个分类组件

分类组件比较简单,DirectionalLayout包含一个Text。

  1. <?xml version="1.0" encoding="utf-8"?> 
  2.  
  3. <DirectionalLayout 
  4.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  5.     ohos:height="match_content" 
  6.     ohos:width="match_parent" 
  7.     ohos:bottom_margin="$float:defaultMargin" 
  8.     ohos:orientation="vertical" 
  9.     ohos:top_margin="$float:defaultMargin"
  10.  
  11.     <Text 
  12.         ohos:id="$+id:categoryListPerText" 
  13.         ohos:height="match_parent" 
  14.         ohos:width="match_parent" 
  15.         ohos:bottom_padding="$float:componentPadding" 
  16.         ohos:end_padding="$float:defaultPadding" 
  17.         ohos:multiple_lines="true" 
  18.         ohos:text_alignment="vertical_center|left" 
  19.         ohos:text_size="16vp" 
  20.         ohos:top_padding="$float:componentPadding"/> 

3.item_child_per.xml #分类下面的子类别

包含了一个自定义的GridView,我们可以学习一下如何自定义组件。

HarmonyOS官方模板学习 之 Category Ability(Java)-鸿蒙HarmonyOS技术社区

4.item_child_per_grid_per.xml #子类别下的网格项组件

比较简单

  1. <?xml version="1.0" encoding="utf-8"?> 
  2.  
  3. <DirectionalLayout 
  4.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  5.     ohos:height="match_content" 
  6.     ohos:width="60vp" 
  7.     ohos:alpha="0" 
  8.     ohos:top_margin="$float:defaultMargin"
  9.  
  10.     <Image 
  11.         ohos:height="60vp" 
  12.         ohos:width="match_parent" 
  13.         ohos:background_element="$graphic:background_item_grid_per"/> 
  14.  
  15.     <Text 
  16.         ohos:id="$+id:itemChildPerGridPerText" 
  17.         ohos:height="match_content" 
  18.         ohos:width="match_parent" 
  19.         ohos:bottom_padding="$float:componentPadding" 
  20.         ohos:multiple_lines="true" 
  21.         ohos:text_alignment="center" 
  22.         ohos:text_size="16vp" 
  23.         ohos:top_padding="$float:componentPadding"/> 
  24. </DirectionalLayout> 

5.item_grid_per.xml #分类下面的网格项

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DependentLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="match_content" 
  5.     ohos:width="108vp" 
  6.     ohos:background_element="$graphic:background_item_grid_per"
  7.  
  8.     <Image 
  9.         ohos:id="$+id:itemGridPerImage" 
  10.         ohos:height="65vp" 
  11.         ohos:width="match_parent"/> 
  12.  
  13.     <Text 
  14.         ohos:id="$+id:itemGridPerText" 
  15.         ohos:height="match_content" 
  16.         ohos:width="match_parent" 
  17.         ohos:align_parent_start="true" 
  18.         ohos:align_parent_top="true" 
  19.         ohos:bottom_padding="$float:componentPadding" 
  20.         ohos:end_padding="$float:defaultPadding" 
  21.         ohos:multiple_lines="true" 
  22.         ohos:start_padding="$float:defaultPadding" 
  23.         ohos:text_alignment="vertical_center" 
  24.         ohos:text_size="16vp" 
  25.         ohos:top_padding="$float:componentPadding"/> 
  26. </DependentLayout> 

6.search_bar.xml #search组件

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="match_content" 
  5.     ohos:width="match_parent" 
  6.     ohos:background_element="$color:colorSubBackground"
  7.  
  8.     <DependentLayout 
  9.         ohos:height="match_content" 
  10.         ohos:width="match_parent" 
  11.         ohos:background_element="$graphic:background_search_bar" 
  12.         ohos:bottom_margin="$float:componentPadding" 
  13.         ohos:end_margin="$float:defaultMargin" 
  14.         ohos:start_margin="$float:defaultMargin" 
  15.         ohos:top_margin="$float:componentPadding"
  16.  
  17.         <Image 
  18.             ohos:id="$+id:searchImage" 
  19.             ohos:height="match_content" 
  20.             ohos:width="match_content" 
  21.             ohos:image_src="$media:searchIcon" 
  22.             ohos:start_margin="$float:defaultMargin" 
  23.             ohos:vertical_center="true"/> 
  24.  
  25.         <TextField 
  26.             ohos:id="$+id:searchTextField" 
  27.             ohos:height="match_content" 
  28.             ohos:width="match_parent" 
  29.             ohos:bottom_padding="$float:componentPadding" 
  30.             ohos:element_cursor_bubble="#00000000" 
  31.             ohos:end_of="$id:searchImage" 
  32.             ohos:end_padding="$float:defaultPadding" 
  33.             ohos:hint="$string:search" 
  34.             ohos:multiple_lines="false" 
  35.             ohos:start_padding="$float:defaultPadding" 
  36.             ohos:text_alignment="vertical_center" 
  37.             ohos:text_size="16fp" 
  38.             ohos:top_padding="$float:componentPadding" 
  39.             ohos:vertical_center="true"/> 
  40.     </DependentLayout> 
  41.  
  42. </DirectionalLayout> 

7.tab.xml #单个tab组件

  1. <?xml version="1.0" encoding="utf-8"?> 
  2.  
  3. <DirectionalLayout 
  4.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  5.     ohos:id="$+id:tab" 
  6.     ohos:height="match_content" 
  7.     ohos:width="0vp" 
  8.     ohos:alignment="center" 
  9.     ohos:orientation="vertical" 
  10.     ohos:weight="1"
  11.  
  12.     <Image 
  13.         ohos:id="$+id:bottom_tab_button_image" 
  14.         ohos:height="$float:heightTab" 
  15.         ohos:width="$float:widthTab"/> 
  16.  
  17.     <Text 
  18.         ohos:id="$+id:bottom_tab_button_text" 
  19.         ohos:height="match_content" 
  20.         ohos:width="match_parent" 
  21.         ohos:text_alignment="top|horizontal_center" 
  22.         ohos:text_color="$color:colorTabTextNormal" 
  23.         ohos:text_size="$float:textSizeTab" 
  24.         ohos:top_margin="2vp"/> 
  25.  
  26. </DirectionalLayout> 

8.title_bar.xml #标题组件

两个Text 加上一个Image

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DependentLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     ohos:height="$float:defaultHeight" 
  5.     ohos:width="match_parent" 
  6.     ohos:background_element="$color:colorSubBackground"
  7.  
  8.     <Text 
  9.         ohos:id="$+id:title_text" 
  10.         ohos:height="match_content" 
  11.         ohos:width="match_content" 
  12.         ohos:align_parent_bottom="true" 
  13.         ohos:bottom_padding="$float:defaultPadding" 
  14.         ohos:end_padding="$float:defaultPadding" 
  15.         ohos:multiple_lines="true" 
  16.         ohos:start_padding="$float:defaultPadding" 
  17.         ohos:text="$string:entry_MainAbility" 
  18.         ohos:text_color="$color:appbar_title_color" 
  19.         ohos:text_size="$float:appbar_title_text_size"/> 
  20.  
  21.     <Text 
  22.         ohos:id="$+id:describe_text" 
  23.         ohos:height="match_content" 
  24.         ohos:width="match_content" 
  25.         ohos:align_parent_bottom="true" 
  26.         ohos:bottom_padding="$float:defaultPadding" 
  27.         ohos:end_of="$id:title_text" 
  28.         ohos:multiple_lines="true" 
  29.         ohos:text="$string:describe" 
  30.         ohos:text_color="$color:appbar_subtitle_color" 
  31.         ohos:text_size="$float:appbar_text_size"/> 
  32.  
  33.     <Image 
  34.         ohos:height="match_content" 
  35.         ohos:width="match_content" 
  36.         ohos:align_parent_bottom="true" 
  37.         ohos:align_parent_end="true" 
  38.         ohos:bottom_padding="$float:defaultPadding" 
  39.         ohos:end_padding="$float:defaultPadding" 
  40.         ohos:image_src="$media:addIcon"/> 
  41.  
  42. </DependentLayout> 

业务逻辑

1.CategoryListProvider

部分关键代码

  1. @Override 
  2.     public Component getComponent(int index, Component component, ComponentContainer componentContainer) { 
  3.  
  4.  
  5.         Component itemComponent = component; 
  6.         CategoryListViewHolder viewHolder; 
  7.  
  8.         //获取布局组件 
  9.         if (itemComponent == null) { 
  10.             itemComponent = 
  11.                     LayoutScatter.getInstance(context) 
  12.                             .parse(ResourceTable.Layout_category_list_per, componentContainer, false); 
  13.         } 
  14.  
  15.         //初始化ViewHolder 
  16.         viewHolder = new CategoryListViewHolder(); 
  17.         viewHolder.text = (Text) itemComponent.findComponentById(ResourceTable.Id_categoryListPerText); 
  18.         viewHolder.text.setText(getItem(index)); 
  19.  
  20.         //对齐方式 
  21.         if (TextTool.isLayoutRightToLeft(Locale.getDefault())) { 
  22.             viewHolder.text.setTextAlignment(TextAlignment.VERTICAL_CENTER | TextAlignment.RIGHT); 
  23.         } else { 
  24.             viewHolder.text.setTextAlignment(TextAlignment.VERTICAL_CENTER | TextAlignment.LEFT); 
  25.         } 
  26.         //获取color.json中的颜色值,设置Text组件的颜色 
  27.         if (selectIndex == index) { 
  28.             viewHolder.text.setTextColor(new Color(ElementUtil.getColor(context, ResourceTable.Color_primary_color))); 
  29.         } else { 
  30.             viewHolder.text.setTextColor(new Color(ElementUtil.getColor(context, ResourceTable.Color_primary_default))); 
  31.         } 
  32.  
  33.         return itemComponent; 
  34.     } 
  35.  
  36.     /** 
  37.      * 定义视图持有者 
  38.      */ 
  39.     private static class CategoryListViewHolder { 
  40.         Text text; 
  41.     } 

2.ElementUtil

学习如何获取element color.json的颜色值,用java代码设置给组件。

  1. package com.buty.categoryabilityjava.utils; 
  2.  
  3. import ohos.agp.utils.Color; 
  4. import ohos.app.Context; 
  5. import ohos.global.resource.NotExistException; 
  6. import ohos.global.resource.WrongTypeException; 
  7.  
  8. import java.io.IOException; 
  9. import java.util.logging.Level
  10. import java.util.logging.Logger; 
  11.  
  12. /** 
  13.  * The ElementUtil 
  14.  */ 
  15. public class ElementUtil { 
  16.     /** 
  17.      * The getColor 
  18.      * 
  19.      * @param context    context 
  20.      * @param resColorId resColorId 
  21.      * @return color 
  22.      */ 
  23.     public static int getColor(Context context, int resColorId) { 
  24.         try { 
  25.             // 
  26.             String strColor = context.getResourceManager().getElement(resColorId).getString(); 
  27.  
  28.             if (strColor.length() == 7) { 
  29.                 //返回7位颜色值 
  30.                 return context.getResourceManager().getElement(resColorId).getColor(); 
  31.             } else if (strColor.length() == 9) { 
  32.                 //返回9位颜色值 
  33.                 return Color.getIntColor(strColor); 
  34.             } else { 
  35.                 return 0x000000; 
  36.             } 
  37.         } catch (WrongTypeException | NotExistException | IOException e) { 
  38.             Logger.getLogger(ElementUtil.class.getName()).log(Level.SEVERE, e.getMessage()); 
  39.         } 
  40.         return 0x000000; 
  41.     } 

3.GridAdapter

  1. package com.buty.categoryabilityjava.view
  2.  
  3. import com.buty.categoryabilityjava.utils.LogUtils; 
  4.  
  5. import ohos.agp.components.Component; 
  6. import ohos.agp.components.Image; 
  7. import ohos.agp.components.LayoutScatter; 
  8. import ohos.agp.components.Text; 
  9. import ohos.app.Context; 
  10.  
  11. import java.util.ArrayList; 
  12. import java.util.List; 
  13. import java.util.Map; 
  14. import java.util.stream.IntStream; 
  15.  
  16. /** 
  17.  * The GridAdapter, adapter of the gridView 
  18.  */ 
  19. public class GridAdapter { 
  20.     private final List<Component> componentList = new ArrayList<>(); 
  21.  
  22.     /** 
  23.      * The GridAdapter, adapter of the gridView 
  24.      * 
  25.      * @param context context 
  26.      * @param xmlId   xmlId, the xml layout of each item of gridView 
  27.      * @param data    data, the number of key-value also the number of item 
  28.      * @param from    from, the collection for the key in de data 
  29.      * @param to      to, the value from the data to the component target 
  30.      */ 
  31.     public GridAdapter(Context context, int xmlId, List<Map<String, Object>> data, String[] fromint[] to) { 
  32.         for (Map<String, Object> datum : data) { 
  33.             // get component for the xml 
  34.             Component layoutComponent = LayoutScatter.getInstance(context).parse(xmlId, nullfalse); 
  35.  
  36.             // create each itemComponent for the args:data、fromto 
  37.             IntStream.range(0, to.length) 
  38.                     .forEach( 
  39.                             index -> { 
  40.                                 Component itemComponent = layoutComponent.findComponentById(to[index]); 
  41.                                 if (itemComponent instanceof Image) { 
  42.                                     Image image = (Image) itemComponent; 
  43.                                     if (datum.get(from[index]) instanceof int[]) { 
  44.                                         try { 
  45.                                             image.setPixelMap(((int[]) datum.get(from[index]))[index]); 
  46.                                         } catch (IndexOutOfBoundsException e) { 
  47.                                             LogUtils.error("GridAdapter""IndexOutOfBoundsException"); 
  48.                                         } 
  49.                                     } 
  50.                                 } else { 
  51.                                     if (itemComponent instanceof Text) { 
  52.                                         Text text = (Text) itemComponent; 
  53.                                         if (datum.get(from[index]) instanceof String[]) { 
  54.                                             try { 
  55.                                                 text.setText(((String[]) datum.get(from[index]))[index]); 
  56.                                             } catch (IndexOutOfBoundsException e) { 
  57.                                                 LogUtils.error("GridAdapter""IndexOutOfBoundsException"); 
  58.                                                 text.setText("null"); 
  59.                                             } 
  60.                                         } else if (datum.get(from[index]) instanceof int[]) { 
  61.                                             try { 
  62.                                                 text.setText(((int[]) datum.get(from[index]))[index]); 
  63.                                             } catch (IndexOutOfBoundsException e) { 
  64.                                                 LogUtils.error("GridAdapter""IndexOutOfBoundsException"); 
  65.                                                 text.setText("null"); 
  66.                                             } 
  67.                                         } else { 
  68.                                             text.setText("null"); 
  69.                                         } 
  70.                                     } 
  71.                                 } 
  72.                             }); 
  73.  
  74.             componentList.add(layoutComponent); 
  75.         } 
  76.     } 
  77.  
  78.     /** 
  79.      * The getComponentList 
  80.      * 
  81.      * @return componentList 
  82.      */ 
  83.     List<Component> getComponentList() { 
  84.         return componentList; 
  85.     } 

4.GridView

  1. package com.buty.categoryabilityjava.view
  2.  
  3. import ohos.agp.components.AttrSet; 
  4. import ohos.agp.components.Component; 
  5. import ohos.agp.components.ComponentContainer; 
  6. import ohos.agp.components.TableLayout; 
  7. import ohos.agp.utils.TextTool; 
  8. import ohos.app.Context; 
  9.  
  10. import java.util.Locale; 
  11.  
  12. /** 
  13.  * The GridView, a custom component like grid 
  14.  */ 
  15. public class GridView extends TableLayout implements Component.LayoutRefreshedListener { 
  16.     private OnItemClickListener onItemClickListener; 
  17.     private OnRefreshedListener onRefreshedListener; 
  18.  
  19.     private GridAdapter adapter; 
  20.  
  21.     // custom Attr 
  22.     private int columnMargin; 
  23.     private int rowMargin; 
  24.  
  25.     //add custom attr 
  26.     private int rowPadding; 
  27.  
  28.     private boolean isOnRefreshed = false
  29.  
  30.     public GridView(Context context) { 
  31.         super(context); 
  32.         setLayoutRefreshedListener(this); 
  33.     } 
  34.  
  35.     public GridView(Context context, AttrSet attrSet) { 
  36.         super(context, attrSet); 
  37.         setLayoutRefreshedListener(this); 
  38.         //获取自定义属性的预设值 
  39.         columnMargin = 
  40.                 attrSet.getAttr("columnMargin").isPresent() 
  41.                         ? attrSet.getAttr("columnMargin").get().getDimensionValue() 
  42.                         : 0; 
  43.  
  44.         rowMargin = 
  45.                 attrSet.getAttr("rowMargin").isPresent() ? attrSet.getAttr("rowMargin").get().getDimensionValue() : 0; 
  46.     } 
  47.  
  48.     public GridView(Context context, AttrSet attrSet, String styleName) { 
  49.         super(context, attrSet, styleName); 
  50.         setLayoutRefreshedListener(this); 
  51.         columnMargin = 
  52.                 attrSet.getAttr("columnMargin").isPresent() 
  53.                         ? attrSet.getAttr("columnMargin").get().getDimensionValue() 
  54.                         : 0; 
  55.         rowMargin = 
  56.                 attrSet.getAttr("rowMargin").isPresent() ? attrSet.getAttr("rowMargin").get().getDimensionValue() : 0; 
  57.     } 
  58.  
  59.     @Override 
  60.     public void onRefreshed(Component component) { 
  61.         if (isOnRefreshed) { 
  62.             return
  63.         } 
  64.         isOnRefreshed = true
  65.  
  66.         layoutAdapter(); 
  67.         if (onRefreshedListener != null) { 
  68.             onRefreshedListener.onRefreshed(component); 
  69.         } 
  70.     } 
  71.  
  72.     /** 
  73.      * The setAdapter 
  74.      * 
  75.      * @param adapter adapter 
  76.      */ 
  77.     public void setAdapter(GridAdapter adapter) { 
  78.         this.adapter = adapter; 
  79.         isOnRefreshed = false
  80.     } 
  81.  
  82.     private void layoutAdapter() { 
  83.         removeAllComponents(); 
  84.  
  85.         for (int i = 0; i < adapter.getComponentList().size(); i++) { 
  86.             Component componentItem = adapter.getComponentList().get(i); 
  87.  
  88.             ComponentContainer.LayoutConfig configComponent = componentItem.getLayoutConfig(); 
  89.             int totalWidth = getWidth() - getPaddingStart() - getPaddingEnd(); 
  90.             int columnMarginTmp = columnMargin; 
  91.             if (columnMargin == 0) { 
  92.                 columnMarginTmp = (totalWidth - componentItem.getWidth() * getColumnCount()) / (getColumnCount() - 1); 
  93.             } else { 
  94.                 configComponent.width = (totalWidth - columnMargin * (getColumnCount() - 1)) / getColumnCount(); 
  95.                 componentItem.setLayoutConfig(configComponent); 
  96.             } 
  97.  
  98.             if (i % getColumnCount() != 0) { 
  99.                 if (TextTool.isLayoutRightToLeft(Locale.getDefault())) { 
  100.                     componentItem.setMarginRight(columnMarginTmp); 
  101.                 } else { 
  102.                     componentItem.setMarginLeft(columnMarginTmp); 
  103.                 } 
  104.             } 
  105.  
  106.             if (i / getColumnCount() != 0) { 
  107.                 componentItem.setMarginTop(rowMargin); 
  108.             } 
  109.  
  110.             final int index = i; 
  111.  
  112.             componentItem.setClickedListener( 
  113.                     component -> { 
  114.                         if (onItemClickListener != null) { 
  115.                             onItemClickListener.onclick(component, index); 
  116.                         } 
  117.                     }); 
  118.  
  119.             addComponent(componentItem); 
  120.         } 
  121.     } 
  122.  
  123.     /** 
  124.      * The setOnItemClickListener 
  125.      * 
  126.      * @param onItemClickListener onItemClickListener 
  127.      */ 
  128.     public void setOnItemClickListener(OnItemClickListener onItemClickListener) { 
  129.         this.onItemClickListener = onItemClickListener; 
  130.     } 
  131.  
  132.     /** 
  133.      * The setOnRefreshedListener 
  134.      * 
  135.      * @param onRefreshedListener onRefreshedListener 
  136.      */ 
  137.     public void setOnRefreshedListener(OnRefreshedListener onRefreshedListener) { 
  138.         this.onRefreshedListener = onRefreshedListener; 
  139.     } 
  140.  
  141.     /** 
  142.      * The OnItemClickListener 
  143.      */ 
  144.     public static class OnItemClickListener { 
  145.         /** 
  146.          * The onclick 
  147.          * 
  148.          * @param component component 
  149.          * @param index     index 
  150.          */ 
  151.         public void onclick(Component component, int index) { 
  152.         } 
  153.     } 
  154.  
  155.     /** 
  156.      * The onRefreshedListener 
  157.      */ 
  158.     public static class OnRefreshedListener { 
  159.         /** 
  160.          * The onRefreshed 
  161.          * 
  162.          * @param component component 
  163.          */ 
  164.         public void onRefreshed(Component component) { 
  165.         } 
  166.     } 

3.MainAbilitySlice

  1. package com.buty.categoryabilityjava.slice; 
  2.  
  3. import com.buty.categoryabilityjava.MainAbility; 
  4. import com.buty.categoryabilityjava.ResourceTable; 
  5. import com.buty.categoryabilityjava.data.CategoryData; 
  6. import com.buty.categoryabilityjava.model.Item; 
  7. import com.buty.categoryabilityjava.model.ItemChild; 
  8. import com.buty.categoryabilityjava.provider.CategoryListProvider; 
  9. import com.buty.categoryabilityjava.utils.ElementUtil; 
  10. import com.buty.categoryabilityjava.utils.Toast; 
  11. import com.buty.categoryabilityjava.view.GridAdapter; 
  12. import com.buty.categoryabilityjava.view.GridView; 
  13.  
  14. import ohos.aafwk.ability.AbilitySlice; 
  15. import ohos.aafwk.content.Intent; 
  16. import ohos.agp.components.Component; 
  17. import ohos.agp.components.DirectionalLayout; 
  18. import ohos.agp.components.Image; 
  19. import ohos.agp.components.LayoutScatter; 
  20. import ohos.agp.components.ListContainer; 
  21. import ohos.agp.components.ScrollView; 
  22. import ohos.agp.components.Text; 
  23. import ohos.agp.components.TextField; 
  24. import ohos.agp.utils.TextAlignment; 
  25. import ohos.agp.utils.TextTool; 
  26. import ohos.global.configuration.Configuration; 
  27. import ohos.multimodalinput.event.KeyEvent; 
  28.  
  29. import java.util.ArrayList; 
  30. import java.util.HashMap; 
  31. import java.util.List; 
  32. import java.util.Locale; 
  33. import java.util.Map; 
  34. import java.util.stream.IntStream; 
  35.  
  36. /** 
  37.  * The MainAbilitySlice, the first page of app 
  38.  */ 
  39. public class MainAbilitySlice extends AbilitySlice { 
  40.     // Button number on the bottom 
  41.     private static final int BOTTOM_TAB_BUTTON_NUM = 4; 
  42.  
  43.     private CategoryData categoryData; 
  44.  
  45.     private CategoryListProvider categoryListProvider; 
  46.     private TextField searchTextField; 
  47.     private ListContainer categoryList; 
  48.     private ScrollView itemListScroll; 
  49.     private GridView itemLayoutGrid; 
  50.     private DirectionalLayout itemChildLayout; 
  51.  
  52.     @Override 
  53.     public void onStart(Intent intent) { 
  54.         super.onStart(intent); 
  55.         setUIContent(ResourceTable.Layout_ability_main); 
  56.         this.getWindow().setStatusBarColor(ElementUtil.getColor(this, ResourceTable.Color_colorSubBackground)); 
  57.         this.getWindow().setNavigationBarColor(ElementUtil.getColor(this, ResourceTable.Color_colorSubBackground)); 
  58.  
  59.         categoryData = new CategoryData(this); 
  60.  
  61.         initView(); 
  62.         initListener(); 
  63.         initBottomTab(); 
  64.     } 
  65.  
  66.     /** 
  67.      * The initView, get component from xml 
  68.      */ 
  69.     private void initView() { 
  70.         // Init component 
  71.         searchTextField = (TextField) findComponentById(ResourceTable.Id_searchTextField); 
  72.  
  73.         //ListContainer组件 
  74.         categoryList = (ListContainer) findComponentById(ResourceTable.Id_categoryList); 
  75.         //ScrollView组件 
  76.         itemListScroll = (ScrollView) findComponentById(ResourceTable.Id_itemListScroll); 
  77.         //子项布局grid 
  78.         itemLayoutGrid = (GridView) findComponentById(ResourceTable.Id_itemLayoutGrid); 
  79.         //获取子项布局组件 
  80.         itemChildLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_itemChildLayout); 
  81.  
  82.         //设置样式 
  83.         searchTextField.setTextAlignment(TextAlignment.START | TextAlignment.VERTICAL_CENTER); 
  84.         if (TextTool.isLayoutRightToLeft(Locale.getDefault())) { 
  85.             searchTextField.setLayoutDirection(Component.LayoutDirection.RTL); 
  86.         } else { 
  87.             searchTextField.setLayoutDirection(Component.LayoutDirection.LTR); 
  88.         } 
  89.     } 
  90.  
  91.     private void initLocaleChange() { 
  92.         ((MainAbility) getAbility()) 
  93.  
  94.                 .setLocaleChangeListener( 
  95.                         //区域更改监听器 
  96.                         new MainAbility.LocaleChangeListener() { 
  97.                             @Override 
  98.                             public void onLocaleChange(Configuration configuration) { 
  99.                                 super.onLocaleChange(configuration); 
  100.                                 if (!configuration 
  101.                                         .getFirstLocale() 
  102.                                         .getLanguage() 
  103.                                         .equals(Locale.getDefault().getLanguage())) { 
  104.                                     categoryData = new CategoryData(MainAbilitySlice.this); 
  105.                                     int index = categoryListProvider.getSelectIndex(); 
  106.                                     categoryListProvider = 
  107.                                             new CategoryListProvider( 
  108.                                                     categoryData.getCategoryList().getListText(), 
  109.                                                     MainAbilitySlice.this); 
  110.                                     categoryList.setItemProvider(categoryListProvider); 
  111.                                     categoryListProvider.setSelectIndex(index); 
  112.  
  113.                                     refreshItemGrid( 
  114.                                             categoryData 
  115.                                                     .getItemList( 
  116.                                                             categoryData.getCategoryList().getListText().get(index)) 
  117.                                                     .getListItem()); 
  118.                                     initItemChild( 
  119.                                             categoryData 
  120.                                                     .getItemList( 
  121.                                                             categoryData.getCategoryList().getListText().get(index)) 
  122.                                                     .getListItemChild()); 
  123.  
  124.                                     categoryListProvider.notifyDataChanged(); 
  125.                                 } 
  126.                             } 
  127.                         }); 
  128.     } 
  129.  
  130.     /** 
  131.      * The initListener, set listener of component 
  132.      */ 
  133.     private void initListener() { 
  134.         initLocaleChange(); 
  135.  
  136.         searchTextField.setKeyEventListener( 
  137.                 (component, keyEvent) -> { 
  138.                     if (keyEvent.isKeyDown() && keyEvent.getKeyCode() == KeyEvent.KEY_ENTER) { 
  139.                         Toast.makeToast( 
  140.                                 MainAbilitySlice.this, 
  141.                                 getString(ResourceTable.String_you_search) + searchTextField.getText(), 
  142.                                 Toast.TOAST_SHORT) 
  143.                                 .show(); 
  144.                     } 
  145.                     return false
  146.                 }); 
  147.  
  148.         // Init categoryList 
  149.         categoryList.setItemClickedListener( 
  150.                 (listContainer, component, index, l1) -> { 
  151.                     if (categoryListProvider.getSelectIndex() == index) { 
  152.                         return
  153.                     } 
  154.  
  155.                     String categoryName = categoryData.getCategoryList().getListText().get(index); 
  156.                     categoryListProvider.setSelectIndex(index); 
  157.  
  158.                     refreshItemGrid(categoryData.getItemList(categoryName).getListItem()); 
  159.  
  160.                     initItemChild(categoryData.getItemList(categoryName).getListItemChild()); 
  161.  
  162.                     categoryListProvider.notifyDataChanged(); 
  163.  
  164.                     itemListScroll.fluentScrollYTo(0); 
  165.                 }); 
  166.  
  167.         categoryListProvider = new CategoryListProvider(categoryData.getCategoryList().getListText(), this); 
  168.         categoryList.setItemProvider(categoryListProvider); 
  169.  
  170.         // Init itemGrid 
  171.         itemLayoutGrid.setOnItemClickListener( 
  172.                 new GridView.OnItemClickListener() { 
  173.                     @Override 
  174.                     public void onclick(Component component, int index) { 
  175.                         String text = ((Text) component.findComponentById(ResourceTable.Id_itemGridPerText)).getText(); 
  176.                         Toast.makeToast( 
  177.                                 MainAbilitySlice.this, 
  178.                                 getString(ResourceTable.String_you_clicked) + text, 
  179.                                 Toast.TOAST_SHORT) 
  180.                                 .show(); 
  181.                     } 
  182.                 }); 
  183.  
  184.         refreshItemGrid(categoryData.getItemList(categoryData.getCategoryList().getListText().get(0)).getListItem()); 
  185.         initItemChild(categoryData.getItemList(categoryData.getCategoryList().getListText().get(0)).getListItemChild()); 
  186.     } 
  187.  
  188.     /** 
  189.      * The refreshItemGrid, refresh the itemGrid each time when select a category 
  190.      * 
  191.      * @param itemList itemList, the bean of itemGrid 
  192.      */ 
  193.     private void refreshItemGrid(List<Item> itemList) { 
  194.         List<Map<String, Object>> adapterData = new ArrayList<>(); 
  195.  
  196.         // Create adapterData 
  197.         IntStream.range(0, itemList.size()).forEach(index -> { 
  198.             Map<String, Object> showItem = new HashMap<>(); 
  199.             String[] itemText = new String[]{itemList.get(index).getItemText()}; 
  200.             showItem.put("itemGridPerText", itemText); 
  201.             adapterData.add(showItem); 
  202.         }); 
  203.  
  204.         // Create gridAdapter 
  205.         GridAdapter gridAdapter = 
  206.                 new GridAdapter( 
  207.                         this, 
  208.                         ResourceTable.Layout_item_grid_per, 
  209.                         adapterData, 
  210.                         new String[]{"itemGridPerText"}, 
  211.                         new int[]{ResourceTable.Id_itemGridPerText}); 
  212.  
  213.         // Set adapter 
  214.         itemLayoutGrid.setAdapter(gridAdapter); 
  215.     } 
  216.  
  217.     /** 
  218.      * The initItemChild, init the itemChild each time when select a category 
  219.      * 
  220.      * @param itemChildList itemChildList, the bean of itemChild 
  221.      */ 
  222.     private void initItemChild(List<ItemChild> itemChildList) { 
  223.  
  224.         //清空组件 
  225.         itemChildLayout.removeAllComponents(); 
  226.         itemChildList.add(new ItemChild()); 
  227.         // Create itemChild 
  228.         for (ItemChild itemChild : itemChildList) { 
  229.             Component childComponent = 
  230.                     LayoutScatter.getInstance(this).parse(ResourceTable.Layout_item_child_per, nullfalse); 
  231.  
  232.             Text text = (Text) childComponent.findComponentById(ResourceTable.Id_itemChildPerText); 
  233.             Text more = (Text) childComponent.findComponentById(ResourceTable.Id_itemChildPerMore); 
  234.             GridView gridView = (GridView) childComponent.findComponentById(ResourceTable.Id_itemChildPerGrid); 
  235.  
  236.             gridView.setOnItemClickListener( 
  237.                     new GridView.OnItemClickListener() { 
  238.                         @Override 
  239.                         public void onclick(Component component, int index) { 
  240.                             String text = 
  241.                                     ((Text) component.findComponentById(ResourceTable.Id_itemChildPerGridPerText)) 
  242.                                             .getText(); 
  243.                             Toast.makeToast( 
  244.                                     MainAbilitySlice.this, 
  245.                                     getString(ResourceTable.String_you_clicked) + text, 
  246.                                     Toast.TOAST_SHORT) 
  247.                                     .show(); 
  248.                         } 
  249.                     }); 
  250.  
  251.             gridView.setOnRefreshedListener( 
  252.                     new GridView.OnRefreshedListener() { 
  253.                         @Override 
  254.                         public void onRefreshed(Component component) { 
  255.                             text.setText(itemChild.getItemChildText()); 
  256.                             more.setVisibility(Component.VISIBLE); 
  257.                         } 
  258.                     }); 
  259.  
  260.             List<Map<String, Object>> adapterData = new ArrayList<>(); 
  261.  
  262.             // Create adapterData 
  263.             for (int j = 0; j < itemChild.getListItem().size(); j++) { 
  264.                 Map<String, Object> showitem = new HashMap<>(); 
  265.                 String[] itemText = new String[]{itemChild.getListItem().get(j).getItemText()}; 
  266.                 showitem.put("itemChildPerGridPerText", itemText); 
  267.                 adapterData.add(showitem); 
  268.             } 
  269.  
  270.             // Create gridAdapter 
  271.             GridAdapter gridAdapter = 
  272.                     new GridAdapter( 
  273.                             this, 
  274.                             ResourceTable.Layout_item_child_per_grid_per, 
  275.                             adapterData, 
  276.                             new String[]{"itemChildPerGridPerText"}, 
  277.                             new int[]{ResourceTable.Id_itemChildPerGridPerText}); 
  278.  
  279.             // set adapter 
  280.             gridView.setAdapter(gridAdapter); 
  281.  
  282.             itemChildLayout.addComponent(childComponent); 
  283.         } 
  284.     } 
  285.  
  286.     /** 
  287.      * The initBottomTab, init the bottomTab 
  288.      */ 
  289.     private void initBottomTab() { 
  290.         DirectionalLayout bottomTab = (DirectionalLayout) findComponentById(ResourceTable.Id_bottom_tabMenu); 
  291.         List<DirectionalLayout> tabList = new ArrayList<>(); 
  292.         //遍历创建tab 按钮 
  293.         IntStream.range(0, BOTTOM_TAB_BUTTON_NUM).forEach(count -> { 
  294.  
  295.             // Use LayoutScatter to convert xml file into Component instance 
  296.             DirectionalLayout tab = 
  297.                     (DirectionalLayout) 
  298.                             LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_tab, bottomTab, false); 
  299.  
  300.             //按钮icon 
  301.             Image buttonImage = (Image) tab.findComponentById(ResourceTable.Id_bottom_tab_button_image); 
  302.             if (buttonImage != null) { 
  303.                 buttonImage.setScaleMode(Image.ScaleMode.STRETCH); 
  304.                 if (count == BOTTOM_TAB_BUTTON_NUM - 1) { 
  305.                     buttonImage.setPixelMap(ResourceTable.Media_icon_actived); 
  306.                 } else { 
  307.                     buttonImage.setPixelMap(ResourceTable.Media_icon_normal); 
  308.                 } 
  309.             } 
  310.             //按钮文本 
  311.             Text buttonText = (Text) tab.findComponentById(ResourceTable.Id_bottom_tab_button_text); 
  312.             if (buttonText != null) { 
  313.                 //string.json 获取value的方法 
  314.                 buttonText.setText(getString(ResourceTable.String_tab)); 
  315.             } 
  316.             //点击事件 
  317.             tab.setClickedListener( 
  318.                     component -> { 
  319.                         // Deselect all tabs in tab menu 
  320.                         for (DirectionalLayout btn : tabList) { 
  321.                             ((Image) btn.findComponentById(ResourceTable.Id_bottom_tab_button_image)) 
  322.                                     .setPixelMap(ResourceTable.Media_icon_normal); 
  323.                         } 
  324.  
  325.                         // Set seleted state on the clicked tab 
  326.                         ((Image) component.findComponentById(ResourceTable.Id_bottom_tab_button_image)) 
  327.                                 .setPixelMap(ResourceTable.Media_icon_actived); 
  328.                     }); 
  329.             //初始化好的tab,添加道tab 列表中 
  330.             tabList.add(tab); 
  331.             //添加道主页片的布局中 
  332.             bottomTab.addComponent(tab); 
  333.         }); 
  334.     } 
  335.  
  336.     @Override 
  337.     public void onActive() { 
  338.         super.onActive(); 
  339.     } 
  340.  
  341.     @Override 
  342.     public void onForeground(Intent intent) { 
  343.         super.onForeground(intent); 
  344.     } 

去掉页面顶部标题的方法

config.json文件中在abilities后面增加metaData代码:

  1. ,"metaData":{ 
  2.      "customizeData": [ 
  3.        { 
  4.          "name""hwc-theme"
  5.          "value""androidhwext:style/Theme.Emui.Light.NoTitleBar"
  6.          "extra""" 
  7.        } 
  8.      ] 
  9.    } 

文章相关附件可以点击下面的原文链接前往下载

原文链接:https://harmonyos.51cto.com/posts/4776

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-07-01 09:19:56

鸿蒙HarmonyOS应用

2021-06-28 14:41:36

鸿蒙HarmonyOS应用

2021-05-28 17:01:49

鸿蒙HarmonyOS应用

2021-08-30 18:34:35

鸿蒙HarmonyOS应用

2023-03-08 08:33:44

Javajavac命令

2020-12-30 11:08:50

鸿蒙HarmonyOShelloWorld

2022-02-17 21:05:26

AbilityJS FAJava PA

2021-09-18 14:40:37

鸿蒙HarmonyOS应用

2021-01-06 10:59:14

鸿蒙HarmonyOSPage Abilit

2021-10-18 10:14:26

鸿蒙HarmonyOS应用

2020-11-17 11:48:44

HarmonyOS

2011-07-07 13:48:35

Smarty

2011-07-29 15:09:48

iPhone Category

2013-02-25 09:49:05

jQueryJavaScriptWeb

2021-03-05 15:55:10

鸿蒙HarmonyOS应用开发

2015-04-22 10:57:22

androidSwipeRefres

2020-11-25 12:02:02

TableLayout

2012-06-15 09:47:48

Objective-CCategory

2023-12-13 10:51:49

C++函数模板编程

2020-12-28 11:19:06

鸿蒙HarmonyOSPage Abilit
点赞
收藏

51CTO技术栈公众号