DUICUO

HarmonyOS オープンソースサードパーティコンポーネント - ProgressWheel

[[384269]]

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

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

https://harmonyos..com

序文

Android版ProgressWheelコンポーネント(https://github.com/Alford087/ProgressWheel)がHarmonyOSに移行およびリファクタリングされました。コードは(https://gitee.com/isrc_ohos/progress-wheel_ohos)でオープンソース化されています。ダウンロード、ご利用、そして貴重なフィードバックをお待ちしております。

背景

プログレスホイールは一般的なUIコンポーネントで、読み込み状況、ダウンロードの進行状況、Webページの更新など、時間のかかる操作の完了率を表示するためによく使用されます。プログレスホイールは操作の進行状況を動的に表示できるため、プログラムが応答を停止したとユーザーが誤解するのを防ぎ、ユーザーインターフェースのユーザビリティを向上させます。

コンポーネント機能のデモンストレーション

HarmonyOSシステムをベースに、コントロールプロパティをカスタマイズすることでプログレスホイールコンポーネントを実装しました。このコンポーネントは、プログレスホイールの回転と進捗の増加という2つの機能をサポートしています。

1. 回転

「回転開始」ボタンをクリックすると、プログレスホイールの回転が開始されます。回転中は、「回転開始」が「回転停止」に変わります。「回転停止」をクリックすると、図1に示すように、ユーザーはいつでも回転を停止できます。プログレスホイールの回転機能は、主にサーバーのデータ読み込み状況を表示するもので、AVLoadingIndicatorView読み込みアニメーションライブラリの機能に似ています。

図1. プログレスホイールの回転

2. 進捗が増加

「増加」ボタンをクリックすると、進行状況ホイールが一定量増加し、図 2 に示すように、進行状況ホイールの中央に進行状況の値がリアルタイムで表示されます。進行状況増加機能は、主にサーバーのデータ読み込みの進行状況を表示するために使用されます。

図 2. ボタン制御により進行が速くなります。

サンプル分析

サンプルでは、​​(1) プログレスホイールの回転、(2) ボタン操作による進行状況の増加、(3) ネイティブプログレスバー操作による進行状況の増加、(4) 背景の変更、(5) スタイルの変更という5つのシナリオが提供されています。シナリオ(1)と(2)は比較的単純で、どちらもボタン操作によって実行され、`ProgressWheel`クラスの`start rotation`メソッドと`progress increase`メソッドを呼び出すことで実現できます。これらのメソッドについては、ライブラリ解析のセクションで詳しく説明します。本セクションでは、シナリオ(3)、(4)、(5)に焦点を当てます。

1. ネイティブの進行状況バーは進行状況の増加を制御します。

図 3 は、進行状況の増加を制御するネイティブ プログレス バーを示しています。

ネイティブプログレスバーとは、HarmonyOSシステムの基本コンポーネントであるスライダーを指します。コンテンツの読み込みや操作処理の進行状況を表示するためにも使用できます。ここでは、ネイティブプログレスバーをドラッグして進行状況の値を変更し、進行状況をリアルタイムで表示します。その効果は図3に示されており、コード実装は次のとおりです。

  1. @オーバーライド
  2. パブリックvoid onProgressUpdated(スライダーシークバー、 int i、boolean b){
  3. //ネイティブ プログレス バーとプログレス ホイール間の変換: 100 はネイティブ プログレス バーの最大進行値を表し、360 はプログレス ホイールの最大進行値を表します。
  4. ダブルプログレス = 360.0 * (seekBar.getProgress() / 100.0);
  5. // プログレスホイールの進行状況設定
  6. wheel.setProgress(( int ) 進行状況);
  7. }

2. 背景が変更されました

図4: プログレスホイールの背景の変化

`Random`クラスは乱数を生成するために使用され、生成された乱数は処理されて背景ピクセルとして使用されます。「Random bg」ボタンをクリックすると、背景ピクセルが表示され、プログレスホイールの背景がランダムに変化します。その効果は図4に示されています。コードは次のとおりです。

  1. //背景が変更されました
  2. プライベート静的void randomBg(ProgressWheelホイール) {
  3. // 背景要素をランダムに生成する
  4. ランダム random = new Random();
  5. int firstColour = random.nextInt(); // 乱数を取得する
  6. int secondColour = random.nextInt();
  7. int patternSize = (1 + random.nextInt(3)) * 8; // 乱数処理
  8. intパターン変更 = (1 + random.nextInt(3)) * 8;
  9. int [] ピクセル = 新しいint [パターンサイズ];
  10. for ( int i = 0; i < パターンサイズ; i++) {
  11. pixels[i] = (i > patternChange) ? firstColour : secondColour; // ピクセルポイントを取得する
  12. }
  13. PixelMap.InitializationOptions オプション = 新しい PixelMap.InitializationOptions();
  14. options.size =新しいサイズ(1,パターンサイズ);
  15. options.pixelFormat=PixelFormat.ARGB_8888;
  16. //背景要素を設定する
  17. wheel.setRimShader(新しいPixelMapShader(
  18. 新しい PixelMapHolder( PixelMap.create (ピクセル, オプション))、
  19. Shader.TileMode.REPEAT_TILEMODE、
  20. Shader.TileMode.REPEAT_TILEMODE)、Paint.ShaderType.RADIAL_SHADER);
  21. }

3. スタイルの変更

図5. プログレスホイールのスタイルの変更

プログレスホイールの長さ、幅、背景をカスタマイズすることで、様々なスタイルをデザインできます。「別のスタイル」ボタンをクリックすると、図5に示すようにスタイルが変更されます。コードは次のとおりです。

  1. //スタイルの変更
  2. プライベート静的void styleRandom(ProgressWheel ホイール、コンテキストctx) {
  3. wheel.setRimShader( null 、 Paint.ShaderType.RADIAL_SHADER);
  4. ホイールのリムカラーを設定します(0xFFFFFFFF);
  5. wheel.setCircleColor(0x00000000); // 内側の円の色
  6. wheel.setBarColor(0xFF000000); // プログレスホイールの色
  7. wheel.setContourColor(0xFFFFFFFF); // 外側の円の色
  8. wheel.setBarWidth(pxFromDp(ctx, 8));//幅
  9. wheel.setBarLength(pxFromDp(ctx, 100));//長さ
  10. wheel.setSpinSpeed(2); // 回転速度
  11. wheel.setDelayMillis(3); // 間隔時間
  12. }

ライブラリ分析

1. 機能実装

(1)進行ホイールを描きます。

この機能は ProgressWheel クラスを使用して実装されています。このクラスはまず setupBounds() メソッドと setupPaints() メソッドを宣言し、次にキャンバスを使用してプログレスホイールを描画し、内側の円、外側の円、ストライプ、テキストなどのプロパティを設定します。テキストは、現在の進行状況だけでなく、プログレスホイールのプロパティ値を表示するためにも使用されます。

  1. パブリックProgressWheel(コンテキスト コンテキスト) {
  2. super(コンテキスト);
  3. DrawTask タスク = (コンポーネント、キャンバス) -> {
  4. // 要素の境界を初期化する
  5. セットアップ境界();
  6. // 描画プロパティを初期化する
  7. セットアップペイント();
  8. //内側の円を描く
  9. キャンバスに円弧を描画します(innerCircleBounds、新しい Arc(360, 360, false )、circlePaint);
  10. //外側の円を描く
  11. キャンバスに円弧を描画します(circleBounds、新しいArc(360, 360, false )、rimPaint);
  12. キャンバスに円弧を描画します(circleOuterContour、新しいArc(360, 360, false )、contourPaint);
  13. //ストライプを描く
  14. if (isSpinning) {
  15. キャンバスに円弧を描画します(circleBounds、新しいArc(progress - 90、barLength、 false )、barPaint);
  16. }それ以外{
  17. キャンバスに円弧を描画します(circleBounds、新しい円弧(-90、進行状況、 false )、barPaint);
  18. }
  19. //円の中心に表示されるテキストを設定します
  20. フロートtextHeight = textPaint.descent() - textPaint.ascent();
  21. float verticalTextOffset = (textHeight / 2) - textPaint.descent();
  22. for (文字列行: splitText) {
  23. 水平方向のfloatTextOffset = textPaint.measureText(line) / 2;
  24. キャンバス.drawText(
  25. テキストペイント、
  26. ライン、
  27. ( float ) component.getWidth() / 2 - 水平テキストオフセット、
  28. ( float ) component.getHeight() / 2 + verticalTextOffset);
  29. }
  30. //回転中に異なる位置にプログレスバーを描画する
  31. if (isSpinning) {
  32. スケジュール再描画();
  33. }
  34. };
  35. タスクを描画タスクとして追加します。
  36. }

(2)プログレスホイールの回転

この機能は、ユーザーに進行状況ホイールの回転の表示のみを提供し、現在のスレッドの進行状況を定量的に提供しません。

1) 回転を開始します。プログレスホイールが回転モードに入ると、回転効果を実現するために、一定の間隔で進行状況を再描画するための新しいスレッドを作成する必要があります。

  1. パブリックvoid startSpinning() {
  2. isSpinning = true ; // 現在の状態をスピンに設定します。
  3. pinHandler.sendEvent(0); // 進捗状況を更新
  4. }

2) 回転を停止します。プログレスホイールの回転が停止すると、プログレス値はゼロに設定されます。

  1. パブリックvoid stopSpinning() {
  2. isSpinning = false ; // 現在の状態を停止に設定します。
  3. progress = 0; // 進捗状況をゼロにクリアする
  4. 無効化();
  5. }

(3)進歩が加速

この機能では、事前に増分を設定する必要があり、毎回一定の進捗量が追加されます。進捗量の最大値は360に設定されており、最大値を超えると進捗量は0にリセットされます。このモードでは、回転中に現在の進捗状況を定量化して表示するため、ユーザーは現在のスレッドの進捗状況を明確に把握でき、よりユーザーフレンドリーなインタラクションモードとなります。

  1. パブリックvoid incrementProgress( int量) {
  2. isSpinning = false ; // 進行状況を増やすときに進行状況ホイールは回転しません。
  3. 進捗 += 量; // 量的増加
  4. (進捗状況 > 360)の場合{
  5. progress % = 360; // 360を超えると自動的にリセットされます
  6. }
  7. 無効化();
  8. }

2. 移植方法

このコンポーネントは移植時に主にAPIの置き換えを行っており、いくつかのメソッドはオーバーライドが必要です。例えば、プログレスホイールの回転を処理する場合、`spinHandler()`メソッドをオーバーライドする必要があります。このメソッドは、プログレスホイールの回転に応じて、異なるピクセル位置にプログレスバーを描画します。位置が360度以上移動すると、0度にリセットされ、回転が再開されます。コードは次のとおりです。

  1. //各描画で移動するピクセル数
  2. プライベートフロートスピンスピード = 2f;
  3. //描画処理の時間間隔
  4. プライベートint遅延ミリス = 100;
  5. プライベートイベントハンドラー spinHandler = 新しいイベントハンドラー(EventRunner.getMainEventRunner())
  6. {
  7. @オーバーライド
  8. public void processEvent(InnerEvent msg)
  9. {
  10. 無効化();
  11. if (isSpinning)
  12. {
  13. //描画の進行位置を更新する
  14. 進行状況 += スピン速度;
  15. // 移動するピクセル数が 360 を超える場合はリセットします。
  16. (進捗 > 360)の場合
  17. {
  18. 進捗 = 0;
  19. }
  20. spinHandler.sendEvent(0, delayMillis);
  21. }
  22. super.processEvent(メッセージ);
  23. }
  24. };

プロジェクト貢献者

リウ・レイ、ジェン・センウェン、ジュー・ウェイ、チェン・メイルー、チャン・シンシン

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

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

https://harmonyos..com