在HarmonyOS NEXT开发中按钮下拉列表弹窗?

在HarmonyOS NEXT开发中按钮下拉列表弹窗?UI具体实现的效果是,点击按钮在按钮下面下拉一个弹窗,弹窗宽度,高度可以设置,其中高度根据数组长度来调节, 其中弹窗每一行的点击事件要能响应

阅读 491
avatarAI BotBETA
# 在HarmonyOS NEXT开发中按钮下拉列表弹窗的实现

在HarmonyOS NEXT开发中,你可以通过以下步骤实现按钮点击后在下方显示下拉列表弹窗,并且弹窗的高度根据数组长度动态调节,同时每一行可以点击并响应事件。

### 1. 创建布局文件

首先,创建一个布局文件(XML),用于定义按钮和弹窗的样式。

<DirectionalLayout

xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="vertical"
ohos:alignment="center">

<Button
    ohos:id="$+id:button"
    ohos:width="match_content"
    ohos:height="match_content"
    ohos:text="Click to Show Dropdown"
    ohos:top_margin="20vp"/>

<PopupLayout
    ohos:id="$+id:popupLayout"
    ohos:width="match_parent"
    ohos:height="0vp"
    ohos:background_color="#FFFFFF"
    ohos:visibility="collapse"
    ohos:below="$+id:button"
    ohos:alignment="top_start">

    <ListContainer
        ohos:id="$+id:listContainer"
        ohos:width="match_parent"
        ohos:height="wrap_content"/>
</PopupLayout>

</DirectionalLayout>


### 2. 在代码中处理按钮点击事件和弹窗显示

在你的AbilitySlice中,设置按钮的点击事件,并在点击时动态设置弹窗的高度和内容。

import ohos.aafwk.ability.AbilitySlice;
import ohos.agp.components.*;
import ohos.agp.components.list.ListContainer;
import ohos.agp.components.list.ListItemProvider;
import ohos.agp.components.list.ListItem;
import ohos.bundle.IBundleManager;

import java.util.Arrays;
import java.util.List;

public class MainAbilitySlice extends AbilitySlice {

private Button button;
private PopupLayout popupLayout;
private ListContainer listContainer;
private List<String> items;

@Override
protected void onStart(IBundleManager iBundleManager) {
    super.onStart(iBundleManager);
    super.setUIContent(ResourceTable.Layout_ability_main);

    button = (Button) findComponentById(ResourceTable.Id_button);
    popupLayout = (PopupLayout) findComponentById(ResourceTable.Id_popupLayout);
    listContainer = (ListContainer) findComponentById(ResourceTable.Id_listContainer);

    items = Arrays.asList("Item 1", "Item 2", "Item 3", "Item 4"); // 示例数据

    button.setClickedListener(new Component.ClickedListener() {
        @Override
        public void onClick(Component component) {
            showDropdown();
        }
    });

    listContainer.setItemProvider(new MyListItemProvider());
}

private void showDropdown() {
    // 根据数组长度计算弹窗高度
    int itemHeight = 50; // 假设每个列表项的高度为50vp
    int height = items.size() * itemHeight;

    // 设置PopupLayout的高度和可见性
    popupLayout.setHeight(height);
    popupLayout.setVisibility(Visibility.VISIBLE);
}

private class MyListItemProvider extends ListItemProvider {
    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public ListItem getItem(int index) {
        return new MyListItem(items.get(index));
    }
}

private class MyListItem extends ListItem {
    private Text text;

    public MyListItem(String textContent) {
        super(MainAbilitySlice.this);

        DirectionalLayout layout = new DirectionalLayout(MainAbilitySlice.this);
        layout.setLayoutConfig(new Component.LayoutConfig(Component.LayoutConfig.MATCH_PARENT, Component.LayoutConfig.WRAP_CONTENT));
        layout.setPadding(16, 16, 16, 16);
        layout.setOrientation(Component.VERTICAL);
        layout.setAlignment(Component.Alignment.CENTER);

        text = new Text(MainAbilitySlice.this);
        text.setText(textContent);
        text.setTextSize(18);

        layout.addComponent(text);
        this.addComponent(layout);

        layout.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                // 处理点击事件
                new ToastDialog(MainAbilitySlice.this)
                        .setText("Clicked: " + textContent)
                        .show();
            }
        });
    }
}

}


### 3. 解释

- **布局文件**:定义了一个按钮和一个PopupLayout,PopupLayout初始高度为0且不可见。
- **代码处理**:在AbilitySlice中,设置按钮点击事件,点击时计算PopupLayout的高度并设置为可见。
- **列表项**:自定义ListItemProvider和ListItem,每个列表项包含文本,并且可以设置点击事件。

这样,你就可以在HarmonyOS NEXT中实现按钮点击后显示下拉列表弹窗,并且根据数组长度动态调整高度,同时处理每一行的点击事件。
1 个回答

参考popup弹窗:https://developer.huawei.com/consumer/cn/doc/harmonyos-refere...
代码可以参考:

@Entry 
@Component 
struct Index { 
  @State handlePopup: boolean = false 
  @State customPopup: boolean = false 
  @State message: string = 'Hello World'; 
  @State titleArray: Array<string> = [" 人员信息", " 税票信息", 
    " 扩展权限", " 密码修改", 
    " 登录方式", " 日志上传", 
    " 缓存清理", " 意见反馈", 
    " 隐私安全", " 版本信息", 
    " 注销退出"]; 
  @State titleImageArray: Array<string> = ["app.media.more_ry", "app.media.more_sp", 
    "app.media.more_qx", "app.media.more_mm", 
    "app.media.more_dl", "app.media.more_rz", 
    "app.media.more_clean", "app.media.more_fk", 
    "app.media.more_ys", "app.media.more_bb", 
    "app.media.more_tc"]; 
 
  // popup构造器定义弹框内容 
  @Builder 
  popupBuilder() { 
    Column({ space: 2 }) { 
      ForEach(this.titleImageArray,(titleImage:string,index:number)=>{ 
        Row(){ 
          Image($r(titleImage)) 
            .width(40) 
            .height(40) 
            .margin({ left: -5 }) 
          Text(this.titleArray[index]) 
            .fontSize(30) 
        } 
        .onClick(()=>{ 
          console.log("点击了第"+index+"行") 
        }) 
      }) 
    } 
    .padding(5) 
  } 
 
  build() { 
    Row() { 
      Column() { 
        Button('点我下方弹窗') 
          .backgroundColor(Color.Red) 
          .fontColor(Color.White) 
          .fontSize('18fp') 
          .margin({ top: 0, left: 200 }) 
          .onClick(() => { 
            this.customPopup = !this.customPopup 
          }) 
          .bindPopup(this.customPopup, { 
            builder: this.popupBuilder, 
            placement: Placement.Top, 
            mask: { color: '#33000000' }, 
            popupColor: Color.Black, 
            enableArrow: true, 
            showInSubWindow: false, 
            onStateChange: (e) => { 
              if (!e.isVisible) { 
                this.customPopup = false 
              } 
            } 
          }) 
        //需求 
        /* 
        * UI具体实现的效果是,点击按钮在按钮下面下拉一个弹窗,弹窗宽度,高度可以设置,其中高度根据数组长度来调节, 
        * 其中弹窗每一行的点击事件要能响应 
        * 最终效果图放在附件里面,请 查看。谢谢 
        * */ 
      } 
      .height('100%') 
      .width('100%') 
      .margin({ top: 0, left: -10 }) 
    } 
    .height('100%') 
  } 
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进