> 文档中心 > HarmonyOS应用开发--基于TabList和PageSlider的自制平行视界MyParallelView[我的平行视界][API V6]

HarmonyOS应用开发--基于TabList和PageSlider的自制平行视界MyParallelView[我的平行视界][API V6]

HarmonyOS应用开发--基于TabList和PageSlider的自制平行视界MyParallelView[我的平行视界][API V6]

  • 1. 名称
  • 2. app实现关键技巧
  • 3. 源代码
    •   3.1 Java源代码
      •    3.1.1 PSProvider.java
      •    3.1.2 DetailSlice.java
      •    3.1.3 MainAbilitySlice.java
      •    3.1.4 MainAbility.java
      •    3.1.5 MyApplication.java
    •   3.2 XML源代码
      •    3.2.1 UI背景XML
        •     3.2.1.1 background_ability_main.xml
      •    3.2.2 主页面与子布局XML
        •     3.2.2.1 ability_main.xml
        •     3.2.2.2 english_detailpage.xml
        •     3.2.2.3 pageslider_page1.xml
        •     3.2.2.4 pageslider_page2.xml
  • 4.config.json
  • 5.app图标(放在media文件夹中)
  • 6.三个element文件夹中的json
    •   6.3.1 element中的json
    •   6.3.1 en.element中的json
    •   6.3.1 zh.element中的json
  • 7. app运行视频(远程模拟器运行)

1. 名称

本次项目将TabList和Tab用作PageSlider的页面指示器,并且通过判段屏幕是否横屏开启自制平行视界功能。
将本次项目命名为:我的平行视界,MyParallelView。
项目已经放在Gitee仓库中:MyParallelView

2. app实现关键技巧

  • TabList和Tab是鸿蒙api提供的页签功能,即常见的类别标签选择功能。PageSlider是鸿蒙api提供的多页面切换功能组件。而本次项目,将TabList和Tab作为PageSlier的页面指示器。
  • 即有:点击某个页签,则会切换至某个页面;滑动到某个页面,则会选中某个页签。

PageSlier每页显示不同组件内容----实现技巧:

  • 第一种方法:首先写好几个需要的页面XML,使用动态装载XML的手段,然后将装载返回的DirectionalLayout变量按照页面顺序,放在ArrayList pageslist = new ArrayList()中,最后将此列表设置为Provider的数据源。
  • 第二种方法:通过java代码创建相应的组件,将组件的布局容器放入pageslist列表中。

TabList与PageSlider双向指示----实现技巧:

  • 给TabList设置一个addTabSelectedListener,当某个页签从未选中状态变换到选中状态时,使用tablist.getSelectedTabIndex()得到选中的是其第i个页签,然后通过pageslider.setCurrentPage(i)将对应的第i个页面设置为当前显示页面。【由TabList控制PageSlider
  • 给PageSlider设置一个addPageChangedListener,当某个页面处于选中时即处于当前显示状态,则使用tablist.selectTabAt(i)选中对应的页签。【由PageSlider控制TabList
  • 由上述的的两个单向控制组合,即可实现双向控制与指示!

自制平行视界----实现技巧:

  • 将页面划分为左右两部分,其中右半部分的DirectionalLayout默认设置为HIDE,当PageSlider某个页面通过点击需要显示详情的时候,判断此时Ability是横屏还是竖屏,如果是横屏则使得右半部分的DirectionalLayout默认设置为VISIBLE,然后将详情页的XML动态的装载进去,当点击“取消”按钮时,则会将其移除且设置右半部分的DirectionalLayout默认设置为HIDE。

在这里插入图片描述
在这里插入图片描述

3. 源代码

  3.1 Java源代码

   3.1.1 PSProvider.java

package com.tdtxdcxm.myparallelview.provider;import ohos.agp.components.Component;import ohos.agp.components.ComponentContainer;import ohos.agp.components.DirectionalLayout;import ohos.agp.components.PageSliderProvider;import java.util.ArrayList;public class PSProvider extends PageSliderProvider {    ArrayList<DirectionalLayout> pageslist = new ArrayList<>();    public PSProvider(ArrayList<DirectionalLayout> pageslist) { this.pageslist = pageslist;    }    @Override    public int getCount() { return pageslist.size();    }    @Override    public Object createPageInContainer(ComponentContainer componentContainer, int i) { DirectionalLayout directionalLayout = pageslist.get(i); componentContainer.addComponent(directionalLayout); return directionalLayout;    }    @Override    public void destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) { componentContainer.removeComponent((Component) o);    }    @Override    public boolean isPageMatchToObject(Component component, Object o) { return true;    }}

   3.1.2 DetailSlice.java

package com.tdtxdcxm.myparallelview.slice;import com.tdtxdcxm.myparallelview.ResourceTable;import ohos.aafwk.ability.AbilitySlice;import ohos.aafwk.content.Intent;import ohos.agp.components.Button;import ohos.agp.components.Component;import ohos.agp.components.DirectionalLayout;import ohos.agp.components.webengine.WebAgent;import ohos.agp.components.webengine.WebView;public class DetailSlice extends AbilitySlice {    private DirectionalLayout englishdetail_rootdl;    private Button englishdetail_backbut;    private WebView englishdetail_webview;    public void initDetailSliceComponents(){ englishdetail_rootdl = (DirectionalLayout) findComponentById(ResourceTable.Id_englishdetail_rootdl); englishdetail_backbut = (Button) findComponentById(ResourceTable.Id_englishdetail_backbut); englishdetail_webview = (WebView) findComponentById(ResourceTable.Id_englishdetail_webview); englishdetail_backbut.setClickedListener(new Component.ClickedListener() {     @Override     public void onClick(Component component) {  terminate();     } }); englishdetail_webview.getWebConfig().setJavaScriptPermit(true); englishdetail_webview.setWebAgent(new WebAgent()); englishdetail_webview.load("https:www.csdn.net/");    }    @Override    public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_english_detailpage); initDetailSliceComponents();    }    @Override    public void onActive() { super.onActive();    }    @Override    public void onInactive() { super.onInactive();    }    @Override    public void onForeground(Intent intent) { super.onForeground(intent);    }    @Override    public void onBackground() { super.onBackground();    }    @Override    public void onStop() { super.onStop();    }}

   3.1.3 MainAbilitySlice.java

package com.tdtxdcxm.myparallelview.slice;import com.tdtxdcxm.myparallelview.ResourceTable;import com.tdtxdcxm.myparallelview.provider.PSProvider;import ohos.aafwk.ability.AbilitySlice;import ohos.aafwk.content.Intent;import ohos.agp.components.*;import ohos.agp.components.webengine.WebAgent;import ohos.agp.components.webengine.WebView;import ohos.agp.utils.TextAlignment;import ohos.bundle.AbilityInfo;import java.util.ArrayList;public class MainAbilitySlice extends AbilitySlice {    private DirectionalLayout main_one,main_two;    private TabList main_one_tablist;    private TabList.Tab tab1,tab2,tab3,tab4,tab5,tab6,tab7,tab8,tab9;    private PageSlider main_one_pageslider;    private ArrayList<DirectionalLayout> pageslist = new ArrayList<>();    private boolean islandscape = false;    public void fillPagesList(){ pageslist.clear(); /**<********************************************加载已经的不同页面到pageslider中******************************************/ DirectionalLayout directionalLayout = (DirectionalLayout) LayoutScatter.getInstance(this.getContext()).parse(ResourceTable.Layout_pageslider_page1,null,false); pageslist.add(directionalLayout); directionalLayout = (DirectionalLayout) LayoutScatter.getInstance(this.getContext()).parse(ResourceTable.Layout_pageslider_page2,null,false); pageslist.add(directionalLayout); /***********************************************加载已经的不同页面到pageslider中**************************************>*/ /**<******************************************根据java代码创建页面到pageslider中****************************************/ directionalLayout = new DirectionalLayout(this); Text text = new Text(this.getContext()); text.setTextAlignment(TextAlignment.CENTER); text.setText("点我查看详细内容"+"\n"+"竖屏-跳Slice,横屏-平行视界"); text.setTextSize(70); text.setMultipleLine(true); text.setClickedListener(new Component.ClickedListener() {     @Override     public void onClick(Component component) {  if(islandscape == true){      //如果此时是横屏状态,则详情内容打开在“自制平行视界”中      main_two.setVisibility(Component.VISIBLE);      DirectionalLayout englishdetail_rootdl = (DirectionalLayout) LayoutScatter.getInstance(MainAbilitySlice.this.getContext()).parse(ResourceTable.Layout_english_detailpage,null,false);      Button englishdetail_backbut = (Button) englishdetail_rootdl.findComponentById(ResourceTable.Id_englishdetail_backbut);      WebView englishdetail_webview = (WebView) englishdetail_rootdl.findComponentById(ResourceTable.Id_englishdetail_webview);      englishdetail_backbut.setClickedListener(new Component.ClickedListener() {   @Override   public void onClick(Component component) {main_two.removeComponentAt(0);main_two.setVisibility(Component.HIDE);   }      });      main_two.addComponent(englishdetail_rootdl);      englishdetail_webview.getWebConfig().setJavaScriptPermit(true);      englishdetail_webview.setWebAgent(new WebAgent());      englishdetail_webview.load("https:www.csdn.net/");  }  else{      main_two.setVisibility(Component.HIDE);      present(new DetailSlice(), new Intent());  }     } }); directionalLayout.addComponent(text); pageslist.add(directionalLayout); /*********************************************根据java代码创建页面到pageslider中**************************************>*/    }    public void initPageSlider(PageSlider pageslider){ if(pageslider == null){     return; } pageslider.setPageSwitchTime(50); pageslider.setSlidingPossible(true); pageslider.setReboundEffect(true); pageslider.addPageChangedListener(new PageSlider.PageChangedListener() {     @Override     public void onPageSliding(int i, float v, int i1) {     }     @Override     public void onPageSlideStateChanged(int i) {     }     @Override     public void onPageChosen(int i) {  main_one_tablist.selectTabAt(i);     } }); pageslider.setProvider(new PSProvider(pageslist));    }    public void initTabList(TabList tablist){ if(tablist == null){     return; } tablist.addTabSelectedListener(new TabList.TabSelectedListener() {     @Override     public void onSelected(TabList.Tab tab) {  int i = tablist.getSelectedTabIndex();  System.out.println("选中的TAB序号是:"+i);  main_one_pageslider.setCurrentPage(i);     }     @Override     public void onUnselected(TabList.Tab tab) {  return;     }     @Override     public void onReselected(TabList.Tab tab) {  return;     } }); tab1 = tablist.new Tab(this.getContext()); tab1.setText("语文"); tablist.addTab(tab1); tab2 = tablist.new Tab(this.getContext()); tab2.setText("数学"); tablist.addTab(tab2); tab3 = tablist.new Tab(this.getContext()); tab3.setText("英语"); tablist.addTab(tab3); tab4 = tablist.new Tab(this.getContext()); tab4.setText("物理"); tablist.addTab(tab4); tab5 = tablist.new Tab(this.getContext()); tab5.setText("化学"); tablist.addTab(tab5); tab6 = tablist.new Tab(this.getContext()); tab6.setText("生物"); tablist.addTab(tab6); tab7 = tablist.new Tab(this.getContext()); tab7.setText("地理"); tablist.addTab(tab7); tab8 = tablist.new Tab(this.getContext()); tab8.setText("历史"); tablist.addTab(tab8); tab9 = tablist.new Tab(this.getContext()); tab9.setText("政治"); tablist.addTab(tab9); tablist.selectTabAt(0);    }    public void initMASliceComponents(){ main_one = (DirectionalLayout) findComponentById(ResourceTable.Id_main_one); main_two = (DirectionalLayout) findComponentById(ResourceTable.Id_main_two); main_one_tablist = (TabList) findComponentById(ResourceTable.Id_main_one_tablist); main_one_pageslider = (PageSlider) findComponentById(ResourceTable.Id_main_one_pageslider);    }    @Override    protected void onOrientationChanged(AbilityInfo.DisplayOrientation displayOrientation) { System.out.println(displayOrientation); if(displayOrientation == AbilityInfo.DisplayOrientation.LANDSCAPE){     islandscape = true; } else{     islandscape = false;     if(main_two.getComponentAt(0) != null){  main_two.removeComponentAt(0);     }     main_two.setVisibility(Component.HIDE); }    }    @Override    public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main); initMASliceComponents(); initTabList(main_one_tablist); fillPagesList(); initPageSlider(main_one_pageslider);    }    @Override    public void onActive() { super.onActive();    }    @Override    public void onInactive() { super.onInactive();    }    @Override    public void onForeground(Intent intent) { super.onForeground(intent);    }    @Override    public void onBackground() { super.onBackground();    }    @Override    public void onStop() { super.onStop();    }}

   3.1.4 MainAbility.java

package com.tdtxdcxm.myparallelview;import com.tdtxdcxm.myparallelview.slice.MainAbilitySlice;import ohos.aafwk.ability.Ability;import ohos.aafwk.content.Intent;public class MainAbility extends Ability {    @Override    public void onStart(Intent intent) { super.onStart(intent); super.setMainRoute(MainAbilitySlice.class.getName());    }}

   3.1.5 MyApplication.java

package com.tdtxdcxm.myparallelview;import ohos.aafwk.ability.AbilityPackage;public class MyApplication extends AbilityPackage {    @Override    public void onInitialize() { super.onInitialize();    }}

  3.2 XML源代码

   3.2.1 UI背景XML

    3.2.1.1 background_ability_main.xml

<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:shape="rectangle">    <solid ohos:color="#FFFFFF"/></shape>

   3.2.2 主页面与子布局XML

    3.2.2.1 ability_main.xml

<DirectionalLayout    xmlns:ohos="http://schemas.huawei.com/res/ohos"    ohos:id="$+id:main"    ohos:height="match_parent"    ohos:width="match_parent"    ohos:alignment="vertical_center"    ohos:orientation="horizontal">    <DirectionalLayout ohos:id="$+id:main_one" ohos:height="match_parent" ohos:width="0" ohos:weight="1" ohos:alignment="horizontal_center" ohos:orientation="vertical"> <TabList     ohos:id="$+id:main_one_tablist"     ohos:height="0"     ohos:weight="1"     ohos:width="match_parent"     ohos:tab_margin="3vp"     ohos:normal_text_color="#FFD9CCBE"     ohos:selected_text_color="#FFAC56B5"     ohos:tab_indicator_type="bottom_line"     ohos:selected_tab_indicator_color="#FF348998"     ohos:selected_tab_indicator_height="3vp"     ohos:text_size="26vp"     ohos:text_alignment="center"     ohos:orientation="horizontal"     ohos:background_element="#FFF8F6F3"> </TabList> <PageSlider     ohos:id="$+id:main_one_pageslider"     ohos:height="0"     ohos:weight="9"     ohos:width="match_parent"     ohos:orientation="horizontal"     ohos:page_cache_size="4"     ohos:background_element="#FFF7FAF3"> </PageSlider>    </DirectionalLayout>    <DirectionalLayout ohos:id="$+id:main_two" ohos:height="match_parent" ohos:width="0" ohos:weight="1" ohos:visibility="hide" ohos:alignment="horizontal_center" ohos:orientation="vertical">    </DirectionalLayout></DirectionalLayout>

    3.2.2.2 english_detailpage.xml

<DirectionalLayout    xmlns:ohos="http://schemas.huawei.com/res/ohos"    ohos:id="$+id:englishdetail_rootdl"    ohos:height="match_parent"    ohos:width="match_parent"    ohos:orientation="vertical">    <Button ohos:id="$+id:englishdetail_backbut" ohos:height="40vp" ohos:width="match_parent" ohos:top_margin="10vp" ohos:text="取消" ohos:text_color="red" ohos:text_size="20vp" ohos:text_alignment="center" ohos:background_element="#FFD4FFF3">    </Button>    <ohos.agp.components.webengine.WebView ohos:id="$+id:englishdetail_webview" ohos:height="match_parent" ohos:width="match_parent">    </ohos.agp.components.webengine.WebView></DirectionalLayout>

    3.2.2.3 pageslider_page1.xml

<DirectionalLayout    xmlns:ohos="http://schemas.huawei.com/res/ohos"    ohos:id="$+id:page1"    ohos:height="match_parent"    ohos:width="match_parent"    ohos:alignment="vertical_center"    ohos:orientation="horizontal">    <TextField ohos:height="match_parent" ohos:width="match_parent" ohos:hint="请输入【语文】—最多10行..." ohos:hint_color="#FFBAADAD" ohos:multiple_lines="true" ohos:max_text_lines="10" ohos:text_size="25vp" ohos:text_alignment="start">    </TextField></DirectionalLayout>

    3.2.2.4 pageslider_page2.xml

<DirectionalLayout    xmlns:ohos="http://schemas.huawei.com/res/ohos"    ohos:id="$+id:page2"    ohos:height="match_parent"    ohos:width="match_parent"    ohos:alignment="vertical_center"    ohos:orientation="horizontal">    <Image ohos:height="match_parent" ohos:width="match_parent" ohos:image_src="$media:icon">    </Image></DirectionalLayout>

4.config.json

{  "app": {    "bundleName": "com.tdtxdcxm.myparallelview",    "vendor": "tdtxdcxm",    "version": {      "code": 1000000,      "name": "1.0.0"    }  },  "deviceConfig": {    "default": {      "network": { "cleartextTraffic": true      }    }  },  "module": {    "package": "com.tdtxdcxm.myparallelview",    "name": ".MyApplication",    "mainAbility": "com.tdtxdcxm.myparallelview.MainAbility",    "deviceType": [      "phone",      "tablet"    ],    "distro": {      "deliveryWithInstall": true,      "moduleName": "entry",      "moduleType": "entry",      "installationFree": false    },    "abilities": [      { "skills": [   {     "entities": ["entity.system.home"     ],     "actions": ["action.system.home"     ]   } ], "configChanges":["orientation"], "orientation": "unspecified", "visible": true, "name": "com.tdtxdcxm.myparallelview.MainAbility", "icon": "$media:myparallelview", "description": "$string:mainability_description", "label": "$string:entry_MainAbility", "type": "page", "launchType": "standard"      }    ],    "reqPermissions": [      { "name": "ohos.permission.GET_NETWORK_INFO"      },      { "name": "ohos.permission.INTERNET"      },      { "name": "ohos.permission.SET_NETWORK_INFO"      },      { "name": "ohos.permission.MANAGE_WIFI_CONNECTION"      },      { "name": "ohos.permission.SET_WIFI_INFO"      },      { "name": "ohos.permission.GET_WIFI_INFO"      }    ],    "metaData": {      "customizeData": [ {   "name": "hwc-theme",   "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar",   "extra": "" }      ]    }  }}

5.app图标(放在media文件夹中)

在这里插入图片描述
在这里插入图片描述

6.三个element文件夹中的json

  6.3.1 element中的json

{  "string": [    {      "name": "entry_MainAbility",      "value": "MyParallelView"    },    {      "name": "mainability_description",      "value": "Java_Empty Ability"    },    {      "name": "mainability_HelloWorld",      "value": "Hello World"    }  ]}

  6.3.1 en.element中的json

{  "string": [    {      "name": "entry_MainAbility",      "value": "MyParallelView"    },    {      "name": "mainability_description",      "value": "Java_Empty Ability"    },    {      "name": "mainability_HelloWorld",      "value": "Hello World"    }  ]}

  6.3.1 zh.element中的json

{  "string": [    {      "name": "entry_MainAbility",      "value": "我的平行视界"    },    {      "name": "mainability_description",      "value": "Java_Empty Ability"    },    {      "name": "mainability_HelloWorld",      "value": "你好,世界"    }  ]}

7. app运行视频(远程模拟器运行)

基于TabList和PageSlider的自制平行视界

松山湖人才网