基于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 pageslist = new ArrayList<>();
    public PSProvider(ArrayList 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 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

<?xml version="1.0" encoding="UTF-8" ?>

    

   3.2.2 主页面与子布局XML

    3.2.2.1 ability_main.xml

<?xml version="1.0" encoding="utf-8"?>

    
        
        
        
        
    
    
    


    3.2.2.2 english_detailpage.xml

<?xml version="1.0" encoding="utf-8"?>

    
    
    


    3.2.2.3 pageslider_page1.xml

<?xml version="1.0" encoding="utf-8"?>

    
    


    3.2.2.4 pageslider_page2.xml

<?xml version="1.0" encoding="utf-8"?>

    
    

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的自制平行视界MyParallelView[我的平行视界][API V6]