DEV Community

Cover image for Feed Stream Image Sizing, List Component Extension, Custom Popups, Media Listening, List Item Swapping
kouwei qing
kouwei qing

Posted on

Feed Stream Image Sizing, List Component Extension, Custom Popups, Media Listening, List Item Swapping

[Daily HarmonyOS Next Knowledge] Feed Stream Image Sizing, List Component Extension, Custom Popups, Media Listening, List Item Swapping

1. How to set the height of an image component to 3/4 of its width in a HarmonyOS feed stream with fixed-width image content cards?

For feed stream image content cards with fixed-width images, how to set the height of the current image component to 3/4 of its width.

The onComplete callback of the Image component can obtain the component's width and height (componentWidth). The height can be calculated as 3/4 of the width.

API link: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-service-widget-basic-image-V5

This callback is triggered when image data is successfully loaded and decoded, returning the dimensions of the successfully loaded image. For adaptive components, the onAreaChange event is triggered when the component's display dimensions, position, etc., change (e.g., during initial rendering or subsequent updates). The parameter newValue contains the component's width and height. For specific usage, refer to the documentation:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-component-area-change-event-V5

2. Hoping to extend the List component with an onScrollIndex(event: (start: number, end: number, center10+: number) => void) event in HarmonyOS?

Hoping to extend the List component with an onScrollIndex(event: (start: number, end: number, center10+: number) => void) event. Currently, this event only triggers when a ListItemGroup (treated as a single index) changes. To associate the sticky ListItemGroup header with ListItem, a callback for scrolling to a specific ListItem is needed. Similar to how listScroller extends Scroller, the List component should provide a more granular callback with an indexInGroup parameter.

The new version of the List component can be bound to a ListScroller to scroll to a specified ListItem within a ListItemGroup using scrollToItemInGroup(index: number, indexInGroup: number, smooth?: boolean, align?: ScrollAlign): void.

Reference documentation: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-container-list-V5#scrolltoitemingroup11

The existing onScrollVisibleContentChange event:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-container-list-V5#onscrollvisiblecontentchange12

onScrollVisibleContentChange(handler: OnScrollVisibleContentChangeCallback)

Triggered when child components enter or exit the List's visible area. Each ListItem, ListItemGroup header, or footer is counted as a child component when calculating trigger conditions.

When the List has a spring edge effect, onScrollVisibleContentChange does not trigger during edge scrolling and rebound.

Trigger conditions: Fires once during list initialization and when the index of the first or last visible child component changes.

3. Issues with calling a custom HarmonyOS CustomDialog?

A custom popup component created using the @CustomDialog decorator is intended for use by the project team, but it fails to display properly in certain scenarios. For example, when calling the custom popup's display method in the callback of obtaining a Preferences instance after clicking a "Next" button in page-Index.ets, the popup does not display. However, calling the system component AlertDialog.show works. How can the custom popup component be improved to display normally like AlertDialog.show while retaining the original calling method (CustomDialogProvider.showDialog({ content: "我是内容" });)?

It is recommended to use the getPreferencesSync synchronous method of Preferences to avoid call failures.

4. Timing issues with mediaquery's on function in HarmonyOS?

When listening for landscape/portrait orientation using the mediaquery on function, listening at app initialization does not work. A 3-second setTimeout is required to receive messages.

Reference documentation: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-mediaquery-V5#ZH-CN_TOPIC_0000001930756753__on

5. List item swapping in HarmonyOS?

Needs to implement a UI interaction logic for list item swapping.

Recommended to use a Grid for item swapping. See the demo below:

@Entry
@Component
struct GridExample {
  @State numbers: string[] = [];
  scroller: Scroller = new Scroller();
  @State text: string = 'drag';

  @Builder pixelMapBuilder() { // Drag process styling
    Column() {
      Text(this.text)
        .fontSize(16)
        .backgroundColor(0xF9CF93)
        .width(80)
        .height(80)
        .textAlign(TextAlign.Center);
    }
  }

  aboutToAppear() {
    for (let i = 1; i <= 15; i++) {
      this.numbers.push(i + '');
    }
  }

  changeIndex(index1: number, index2: number) { // Swap array positions
    let temp: string;
    temp = this.numbers[index1];
    this.numbers[index1] = this.numbers[index2];
    this.numbers[index2] = temp;
  }

  build() {
    Column({ space: 5 }) {
      Grid(this.scroller) {
        ForEach(this.numbers, (day: string) => {
          GridItem() {
            Text(day)
              .fontSize(16)
              .backgroundColor(0xF9CF93)
              .width(80)
              .height(80)
              .textAlign(TextAlign.Center);
          }
        })
      }
      .columnsTemplate('1fr 1fr 1fr')
      .columnsGap(10)
      .rowsGap(10)
      .width('90%')
      .backgroundColor(0xFAEEE0)
      .height(300)
      .editMode(true) // Set whether the Grid enters edit mode (enables dragging GridItems)
      .onItemDragStart((event: ItemDragInfo, itemIndex: number) => { // Triggered when dragging this component for the first time
        this.text = this.numbers[itemIndex];
        return this.pixelMapBuilder(); // Set the displayed content during dragging
      })
      .onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => { // Triggered when dropping within this component
        if (!isSuccess || insertIndex >= this.numbers.length) {
          return;
        }
        console.info('tag' + itemIndex + '', insertIndex + ''); // itemIndex: Drag start position, insertIndex: Drag insertion position
        this.changeIndex(itemIndex, insertIndex);
      });
    }.width('100%').margin({ top: 5 });
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)