DUICUO

HarmonyOS オープンソースのサードパーティコンポーネント - ViewPagerIndicator_ohos ページスクロールコンポーネント

[[420479]]

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHarmonyOSテクノロジーコミュニティ。

https://harmonyos..com

序文

Android プラットフォームに基づくページ スクロール コンポーネントである ViewPagerIndicator (https://github.com/LuckyJayce/ViewPagerIndicator) が HarmonyOS に移行され、リファクタリングされました。

背景

ViewPagerIndicator_ohosは、ニュースやショッピング情報などの複雑な情報を表示するのに適した情報表示コンポーネントです。従来のページレイアウトでコンテンツを表示する場合、同じ種類の情報が同一ページに表示されます。ViewPagerIndicator_ohosコンポーネントを使用すると、同じ種類の情報を複数のページに表示でき、ユーザーは画面をスワイプすることでページを切り替えることができます。2つの効果の比較を図1に示します。

図 1. ViewPagerIndicator_ohos コンポーネントと従来のページでのコンテンツの表示の違い。

コンポーネント効果表示

コンポーネントアプリケーションのメインインターフェースには3つのボタンがあります。「ホーム」ボタンと「マイ」ボタンはコンポーネントの部分的な効果を表示し、「コミュニティ」ボタンはコンポーネント全体の効果を表示します。ここでは部分的な効果については詳しく説明しませんが、全体的な効果については直接説明します。他の2つのボタンの機能にご興味のある方は、ソースコードをダウンロードして詳細をご確認ください。

ユーザーがアプリケーションの下部ナビゲーションバーにある「コミュニティ」タブをクリックすると、コンポーネントは複数のページに分散された「コミュニティ」セクションのコンテンツを表示します。アプリケーションの上部にはページインジケーターがあり、ユーザーは2つの方法でページを切り替えることができます。1) 画面をスワイプするとページが切り替わり、ページインジケーターは常に現在表示されているページを指します。2) ページインジケーターをクリックすると、図2に示すように、選択したインジケーターが示すページに切り替わります。

図 2. インジケーターが現在のページを表示しているときにページをスワイプする機能。

サンプル分析

Sampleセクションは主に表示レイアウトの構築に使用されます。MainAbilitySliceファイルはアプリケーションのメインインターフェースレイアウトの構築を担当し、CommunityFractionファイルはページとページインジケータのレイアウトの構築を担当します。CommunityFractionによって生成されたUIは、Fractionの形式でメインインターフェースレイアウトに埋め込まれます。

1. MainAbilitySliceファイル

MainAbilitySliceファイルは、コンポーネントアプリケーションのメインインターフェースレイアウトを構築する役割を担います。レイアウト構築の具体的な手順は以下のとおりです。

ステップ 1: コンポーネント アプリケーションのレイアウト ファイルを設定します。

コンポーネントのメインUIレイアウトは`ability_main.xml`で定義されています。UIには、「ホーム」、「マイ」、「コミュニティ」ボタンを表す3つのボタンと、コンテンツ表示ページを表すStackLayoutが含まれています。`ability_main.xml`ファイルは、`setUIContent()`メソッドを使用して、コンポーネントアプリケーションのメインUIレイアウトとして設定されています。

  1. super.setUIContent(ResourceTable.Layout_ability_main);

ステップ2: ボタンの配置

MainAbilitySlice ファイルの OnStart() メソッドでは、手順 1 の「Community」ボタンが findComponentById() メソッドを使用して検索されます。

  1. // 「ホーム」、「マイ」、「コミュニティ」ボタン
  2. プライベートボタン basebtn、mybtn、communitybtn;
  3. ……
  4. //「コミュニティ」ボタンを見つける
  5. communitybtn= (ボタン) findComponentById(ResourceTable.Id_main_community_btn);

ステップ3: ボタンリスナー

「コミュニティ」ボタンのクリックイベントを設定します。ボタンがクリックされたら、コミュニティコンテンツを表す CommunityFraction を手順1の StackLayout に埋め込み、「コミュニティ」ボタンをクリックした後の表示効果を実現します。

  1. //ボタンリスナーを設定する
  2. communitybtn.setClickedListener(これ);
  3. ……
  4. @オーバーライド
  5. public void onClick(Component component) { // クリックイベント
  6. スイッチ (component.getId()){
  7. ……
  8. ケースResourceTable.Id_main_community_btn:
  9. displayCommunityFraction(); // CommunityFractionをメインインターフェースレイアウトに埋め込む
  10. 壊す
  11. デフォルト
  12. 壊す
  13. }
  14. }

2. CommunityFractionファイル

CommunityFraction クラスは Fraction クラスを継承し、MainAbility に全体の表示レイアウトの一部として埋め込まれています。単独で使用することはできません。CommunityFraction ファイルは、ページとページインジケーターのレイアウトを構築する役割を担っています。ここでは、ViewPager オブジェクトを使用してページ切り替えを管理し、TabList を使用してページインジケーターを作成しています。ViewPager 内のページは、コンポーネント効果のデモで説明されている効果を実現するために、TabList 内のタブに順番にバインドされます。具体的な実装手順は以下のとおりです。

ステップ1: CommunityFractionファイルのレイアウトを作成する

fraction_community.xml は CommunityFraction のレイアウトファイルで、ViewPager と TabList が含まれています。LayoutScatter クラスオブジェクトの parse() メソッドを使用して、fraction_community.xml を後で使用するための Component オブジェクトに変換します。

  1. コンポーネント コンポーネント = scatter.parse(ResourceTable.Layout_fraction_community, container, false )

ステップ2: 関連するクラスをインポートし、オブジェクトを宣言する

CommunityFraction ファイルに ViewPager クラスと PagerAdapter クラスをインポートします。ViewPager クラスは PageSlider クラスを継承し、画面のスワイプに応じてページを切り替えます。Pag​​erAdapter クラスは PageSliderProvider クラスを継承し、ページアイテムの管理機能を提供します。

ページ インジケーターを作成するための TabList クラスや、TabList のリスナーとスタイルを設定するための FixedIndicatorView クラスなど、ohos.agp.components の下にあるすべてのクラスをインポートします。

  1. com.shizhefei.view.indicator.CommunityTabListenerをインポートします
  2. com.shizhefei.view.indicator.FixedIndicatorViewをインポートします
  3. com.shizhefei.view.viewpager.PagerAdapterをインポートします
  4. com.shizhefei.view.viewpager.ViewPagerをインポートします
  5. パブリッククラス CommunityFraction は Fraction を拡張します {
  6. ……
  7. プライベート ViewPager viewPager;
  8. プライベート PagerAdapter アダプター。
  9. プライベートコンポーネントコンポーネント;
  10. プライベート TabList tabList;
  11. ...
  12. }

ステップ3: 異なるページを作成する

CommunityFraction クラスは Fraction クラスを継承しているため、onComponentAttached() メソッドをオーバーライドする必要があります。このメソッドは、CommunityFraction がメインインターフェースレイアウトに追加されたときに呼び出されます。onComponentAttached() メソッドでは、XML を使用して「Page 1」、「Page 2」、「Page 3」という 3 つの異なる表示ページが作成されます。

  1. @オーバーライド
  2. 保護されたコンポーネント onComponentAttached(LayoutScatter スキャッター、ComponentContainer コンテナ、Intent インテント) {
  3. ……
  4. DirectionalLayout directionalLayout1 = (DirectionalLayout) scatter.parse(ResourceTable.Layout_page1, null , false ); // ページ 1
  5. DirectionalLayout directionalLayout2 = (DirectionalLayout) scatter.parse(ResourceTable.Layout_page2, null , false ); // ページ 2
  6. DirectionalLayout directionalLayout3 = (DirectionalLayout) scatter.parse(ResourceTable.Layout_page3, null , false ); //ページ3
  7. ……
  8. }

同時に、要素タイプが Component である ArrayList を作成し、上記で作成した 3 つのページを順番に ArrayList に追加します。

  1. // 配列リストを作成する
  2. pages = 新しいArrayList<Component>();
  3. // ページをArrayListに読み込む
  4. pages = 新しいArrayList<Component>();
  5. pages.add (directionalLayout1);
  6. pages.add (方向レイアウト2);
  7. pages.add (directionalLayout3);

ステップ4: ページインジケーターを作成する

まず、文字列配列を定義します。配列の長さによってページインジケーターの数が決まり、配列の要素によってページインジケーターの内容が決まります。

次に、TabList オブジェクトを作成し、findComponentById() メソッドを使用して fraction_community.xml 内の TabList を見つけます。

最後に、 for ループを使用して、配列の内容を TabList 内の各タブのテキストに設定します。

  1. private String[] str = { "ホームページ 1" , "ホームページ 2" , "ホームページ 3" };
  2. ……
  3. this.tabList = タブリスト;
  4. if(this.tabList!= null ){
  5. for ( int i=0;i<str.length;i++){ //ページ数は、以前に設定されたタブ数よりも少なくなっています。
  6. TabList.Tab タブ = this.tabList.new Tab(getContext());
  7. tab.setText(str[i]);
  8. tabList.addTab(タブ);
  9. }
  10. }
  11. //tabList はデフォルトで最初のタブを選択して初期化されます。
  12. this.tabList.selectTabAt(0);

ステップ5: ViewPagerがページを読み込む

まず、ViewPager オブジェクトをインスタンス化し、fraction_community.xml で ViewPager を見つけます。次に、PagerAdapter オブジェクトをインスタンス化して、ページ管理アダプタを作成します。次に、setPages() メソッドを使用して、手順 3 で取得した 3 つのページを含む ArrayList をアダプタに渡します。最後に、アダプタを ViewPager オブジェクトにバインドして、画面をスワイプしたときに複数のページが切り替わる効果を実現します。

  1. viewPager = (ViewPager)mcomponent.findComponentById(ResourceTable.Id_pageslider_community); //ViewPager を見つける
  2. adapter = new PagerAdapter(); // PagerAdapterクラスオブジェクトをインスタンス化する
  3. adapter.setPages(pages); // 3ページを含むArrayListを渡します
  4. viewPager.setProvider(アダプタ);

ステップ6: ページ遷移に合わせて変化するTabListを実装する

ViewPager にページスワイプリスナーを追加します。ページが変更されると、対応する操作が実行され、TabList がページに合わせて変化する効果が得られます。onPageChosen() メソッドは、ページが選択されたときに実行する操作を設定するために使用します。このメソッドをオーバーライドする場合は、現在選択されている(表示されている)ページの番号 i を渡し、tabList 内の対応する番号のタブを選択状態に設定する必要があります。

  1. viewPager.addPageChangedListener(新しいPageSlider.PageChangedListener() {
  2. // ページスクロール遷移中に呼び出されます
  3. ……
  4. @オーバーライド
  5. public void onPageChosen( int i) { // iはページ番号を表す
  6. tabList.selectTabAt(i); // ページがスクロールされると tabIndicator が変化します。
  7. }
  8. });

ステップ 7: TabList をバインドし、固定サイズに従って均等に配置します。

`CommunityTabListener` クラスの `setViewPager()` メソッドは `ViewPager` を `TabList` にバインドできます。`FixedIndicatorView` クラスの `setFixedIndicator()` メソッドは `TabList` 内の各タブのサイズを固定し、均等間隔で均一な配置の効果を実現します。

  1. 固定インジケータビュー fixedIndicatorView = 新しい固定インジケータビュー(str、this.tabList);
  2. //CommunityTabListener は TabList.TabSelectedListener を実装します
  3. CommunityTabListener tabListener=新しい CommunityTabListener();
  4. tabListener.setViewPager(viewPager);
  5. //TabListリスナーを設定する
  6. 固定インジケータビュー。タブリストリスナーを設定します(タブリスナー);
  7. //TabList UI スタイルを設定する
  8. 固定インジケータービュー。インジケータースタイルを設定します(TabList.INDICATOR_BOTTOM_LINE);
  9. // TabList 内の各タブの長さを固定かつ均等に設定します。
  10. 固定インジケータービュー.setFixedIndicator( true );

ライブラリ分析

ViewPagerIndicator_ohosコンポーネントの主な機能は、ViewPagerページ切り替えとTabListページインジケータ切り替えです。ライブラリは、図3に示すように、これらの2つの機能に応じて、インジケータファイルとviewpagerファイルの2つのファイルに分かれています。

`indicator` フォルダには、`CommunityTabListener`、`FixedIndicatorView`、`TabListener`(「My」セクションで参照されているため、ここでは詳しく説明しません)が含まれています。`viewpager` フォルダには、`PagerAdapter` と `ViewPager` が含まれています。以下のセクションでは、これらのファイルについて詳しく説明します。

図3 図書館セクションのエンジニアリング構造

1. ページインジケータ機能の実装

(1)CommunityTabListenerの実装

ページインジケーターの各タブにはリスナーがあり、異なるタブをクリックすると異なるページに切り替わります。具体的な効果については図2をご覧ください。

上記の機能は、`TabList` クラスの `TabSelectedListener` インターフェースを実装する `CommunityTabListener` クラスによって実装されています。このインターフェースは主に `onSelected()`、`onUnSelected()`、`onReselected()` の3つの関数をオーバーライドします。これらの関数は、タブが選択されたとき、選択解除されたとき、そして放されたときの動作をそれぞれ設定します。ここでは、タブが選択されると、そのタブで指定されたページに切り替わるという設定になっています。

  1. パブリッククラス CommunityTabListener は TabList.TabSelectedListener を実装します {
  2. プライベート ViewPager mviewPager;
  3. @オーバーライド
  4. //このメソッドは、ページ インジケーターのタブが選択されたときに呼び出されます。
  5. パブリックvoid onSelected(TabList.Tab タブ) {
  6. int i = tab.getPosition(); // 現在のタブの位置を取得します。
  7. if(i>=0){//現在のタブ位置が0より大きい}
  8. mviewPager.setCurrentPage(i); // タブで示されたタブにページを切り替えます。
  9. }
  10. }
  11.  
  12. @オーバーライド
  13. //ページが選択されていない場合
  14. パブリックvoid onUnselected(TabList.Tab tab) {
  15. }
  16.  
  17. @オーバーライド
  18. //ページが再度選択されたとき
  19. パブリックvoid onReselected(TabList.Tab tab) {
  20. }
  21.  
  22. //ViewPagerが渡される
  23. パブリックvoid setViewPager(ViewPager viewPager) {
  24. this.mviewPager = viewPager;
  25. }
  26. }

(2)FixedIndicatorView機能の実装

FixedIndicatorView クラスは、TabList リスナーイベントと UI スタイルの設定に使用されます。setTabListListener() メソッドはインジケーターリスナーの設定に使用され、setFixedIndicator() メソッドは TabList 内の各タブのサイズと位置を固定し、すべてのタブが同じサイズで均等に配置されるようにします。

  1. //ページインジケータのリスナーを設定する
  2. パブリックvoid setTabListListener(TabList.TabSelectedListener tabSelectedListener){
  3. tabList.addTabSelectedListener(tabSelectedListener);
  4. }
  5.  
  6. //ページインジケーターのUIスタイルを設定する
  7. public void setIndicatorStyle( int style){
  8. this.tabList.setIndicatorType(style);
  9. }
  10.  
  11. //ページ インジケーターのタブ サイズを固定かつ均等に設定します。
  12. パブリックvoid setFixedIndicator(boolean b){
  13. tabList.setFixedMode(b);
  14. }

2. ページ管理機能の実装

(1) PagerAdapter関数の実装

ページ管理アダプターは PagerAdapter クラスによって実装されており、主に前述の ViewPager クラスオブジェクトへのバインドに使用されます。これにより、画面をスワイプすることで複数のページを切り替えたり、ページアイテムを管理したりできるようになります。

setPages() メソッドは、すでに作成されたページをアダプターに渡します。

`createPageInContainer()` メソッドは、特定の場所にページを追加するために使用されます。ViewPager が最初に読み込まれると、デフォルトで最初のページが表示され、`createPageInContainer()` が呼び出されてページが読み込まれます。最初のページが表示された後、ユーザーはすぐに画面をスワイプして隣接するページに切り替えることができます。スムーズなページ切り替えを実現するには、最初のページの表示と同時に、`createPageInContainer()` を使用して隣接するページも読み込む必要があります。そのため、ViewPager の読み込み時に `createPageInContainer()` が 2 回呼び出されます。

`destroyPageFromContainer()` メソッドは、特定のページを破棄するために使用されます。ViewPager は最大 3 ページを同時にキャッシュします。3 ページを超える表示ページを作成する場合は、アプリケーションのクラッシュを防ぐために、ViewPager 内で余分なページを破棄する必要があります。

  1. //ページ管理アダプタ
  2. パブリッククラス PagerAdapter は PageSliderProvider を拡張します {
  3. プライベート ArrayList<Component> ページ;
  4. // ページを作成するために必要なコンポーネント
  5. パブリックvoid setPages(ArrayList<Component> pages) {
  6. this.pages = ページ;
  7. }
  8. @オーバーライド
  9. //ページ数とサイズを取得する
  10. 公共 整数getCount() {
  11. pages.size ( )を返します
  12. }
  13. @オーバーライド
  14. // 特定の場所にページを作成する
  15. パブリックオブジェクト createPageInContainer(ComponentContainer componentContainer, int i) {
  16. コンポーネントコンテナにコンポーネントを追加します(pages.get(i));
  17. pages.get(i)を返します
  18. }
  19. @オーバーライド
  20. //特定のページを削除する
  21. パブリックvoid destroyPageFromContainer(ComponentContainer componentContainer, int i, Object o) {
  22. コンポーネントコンテナのコンポーネントを削除します(pages.get(i));
  23. }
  24. // 同じページかどうかを判定する
  25. @オーバーライド
  26. パブリックブール値isPageMatchToObject(コンポーネントコンポーネント、オブジェクトo) {
  27. コンポーネントをoで返します
  28. }
  29. }

(2)ViewPager機能の実装

ページスクロール機能は、PageSliderクラスを継承するViewPagerクラスによって実装されています。このクラスは主に、画面のスクロールに応じてページを切り替えるために使用されます。このクラスは、slideLock()、setCanSlide()、isCanScroll()という3つのインターフェースを提供しており、ユーザーはこれらのインターフェースを他の機能を開発する際に呼び出すことができます。isCanScroll()メソッドはページがスクロール可能かどうかを判定し、slideLock()メソッドはページをスクロール不可に設定し、setCanSlide()メソッドはページをスクロール可能に設定します。

  1. //インターフェース予約
  2. パブリッククラス ViewPager は PageSlider を拡張します {
  3. ……
  4. //ページをスクロール不可に設定する
  5. パブリックvoid スライドロック() {
  6. this.setSlidingPossible( false );
  7. }
  8. //設定ページはスクロールできます
  9. パブリックvoid setCanSlide() {
  10. this.setSlidingPossible( true );
  11. }
  12. //ページがスクロール可能かどうかを判定する
  13. パブリックブール値isCanScroll() {
  14. getSlidingPossible()を返します
  15. }
  16. }

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHarmonyOSテクノロジーコミュニティ。

https://harmonyos..com