HarmonyOS 鸿蒙Next中如何实现按钮拖拽

HarmonyOS 鸿蒙Next中如何实现按钮拖拽 按钮拖拽功能实现方式

3 回复

窗管级悬浮窗请参考:TYPE_FLOAT9+ 悬浮窗

参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-window-0000001820880785#ZH-CN_TOPIC_0000001820880785__windowtype7

悬浮图标请您参考这个简单的demo适当修改:

import { window } from '@kit.ArkUI';

@Entry
@Component
struct Page3 {
    @State message: string = 'Hello World';

    build() {
        Row() {
            Column() {
                Text(this.message)
                    .fontSize(50)
                    .fontWeight(FontWeight.Bold)
                    .onClick(() => {
                        let windowStage = AppStorage.get("windowStage") as window.WindowStage;
                        windowStage.createSubWindow("test", (err, win) => {
                            win.setUIContent("pages/Page2");
                            win.resize(500, 500);
                            win.moveWindowTo(200, 200);
                            win.showWindow();
                        });
                    });
            }
            .width('100%');
        }
        .height('100%')
        .backgroundColor(Color.Pink);
    }
}
import window from '@ohos.window';
import { BusinessError } from '@ohos.base';
import router from '@ohos.router';

@Entry
@Component
struct FloatWindow {
    // 定义windowClass变量,用来接收创建的悬浮窗
    // 自定义创建悬浮窗方法
    createFloatWindow() {
        // 窗口类型设置为window.WindowType.TYPE_FLOAT
        let windowStage = AppStorage.get("windowStage") as window.WindowStage;

        // 创建悬浮窗
        windowStage.createSubWindow("floatWindow", (err, win) => {
            if (err.code) {
                console.error('Failed to create the floatWindow. Cause: ' + JSON.stringify(err));
                return;
            }
            console.info('Succeeded in creating the floatWindow. Data: ' + JSON.stringify(win));

            // 设置悬浮窗位置
            win.moveWindowTo(300, 300, (err) => {
                if (err.code) {
                    console.error('Failed to move the window. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in moving the window.');
            });

            // 设置悬浮窗大小
            win.resize(500, 500, (err) => {
                if (err.code) {
                    console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
                    return;
                }
                console.info('Succeeded in changing the window size.');
            });

            // 为悬浮窗加载页面内容,这里可以设置在main_pages.json中配置的页面
            win.setUIContent("pages/FloatContent", (err: BusinessError) => {
                if (err.code) {
                    console.error('Failed to load the content. Cause:' + JSON.stringify(err));
                    return;
                }
                win.setWindowBackgroundColor("#00000000");
                console.info('Succeeded in loading the content.');

                // 显示悬浮窗
                win.showWindow((err: BusinessError) => {
                    if (err.code) {
                        console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
                        return;
                    }
                    console.info('Succeeded in showing the window.');
                });
            });
        });
    }
}
// 自定义销毁悬浮窗方法
destroyFloatWindow() {
    // 用windowClass调用destroyWindow销毁悬浮窗
    window.findWindow("floatWindow").destroyWindow((err) => {
        if (err.code) {
            console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err));
            return;
        }
        console.info('Succeeded in destroying the window.');
    });
}

build() {
    Row() {
        Column() {
            TextInput()
            Button('创建悬浮窗')
                .backgroundColor('#F9C449')
                .onClick(() => {
                    // 点击按钮调用创建悬浮窗方法
                    this.createFloatWindow();
                });

            Button('销毁悬浮窗')
                .margin({ top: 20 })
                .backgroundColor('#F9C449')
                .onClick(() => {
                    // 点击按钮调用销毁悬浮窗方法
                    this.destroyFloatWindow();
                });

            Button('跳转下一页')
                .margin({ top: 20 })
                .backgroundColor('#F9C449')
                .onClick(() => {
                    // 点击按钮调用跳转下一页方法
                    router.pushUrl({
                        url: 'pages/Index'
                    });
                });
        }
        .width('100%');
    }
    .height('100%');
}
//FloatContent.ets
import window from '@ohos.window';

interface Position {
    x: number;
    y: number;
}

@Entry
@Component
struct FloatContent {
    @State message: string = 'float window';
    private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All });

    // 创建位置变量,并使用@Watch监听,变量发生变化调用moveWindow方法移动窗口
    @State @Watch("moveWindow") windowPosition: Position = { x: 0, y: 0 };
    floatWindow: window.Window = window.findWindow("floatWindow");

    // 通过悬浮窗名称“floatWindow”获取到创建的悬浮窗
    aboutToAppear() {
        this.floatWindow = window.findWindow("floatWindow");
        this.floatWindow.setPreferredOrientation(window.Orientation.LANDSCAPE);
    }

    // 将悬浮窗移动到指定位置
    moveWindow() {
        this.floatWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
    }

    build() {
        Row() {
            Column() {
                Text(this.message)
                    .fontSize(30)
                    .fontColor(Color.White)
                    .fontWeight(FontWeight.Bold);
            }
            .width('100%');
        }
        .borderRadius(500)
        .height('100%')
        .gesture(
            // 绑定PanGesture事件,监听拖拽动作
            PanGesture(this.panOption)
                .onActionStart((event: GestureEvent) => {
                    console.info('Pan start');
                })
                // 发生拖拽时,获取到触摸点的位置,并将位置信息传递给windowPosition
                .onActionUpdate((event: GestureEvent) => {
                    this.windowPosition.x += event.offsetX;
                    this.windowPosition.y += event.offsetY;
                })
                .onActionEnd(() => {
                    console.info('Pan end');
                })
        )
        .border({
            style: BorderStyle.Dotted
        })
        .backgroundColor("#E8A49C");
    }
}

更多关于HarmonyOS 鸿蒙Next中如何实现按钮拖拽的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中实现按钮拖拽功能,可以通过使用ComponentTouchEvent事件和ComponentPosition属性来实现。具体步骤如下:

  1. 创建按钮组件:首先,在布局文件中定义一个按钮组件,例如Button

  2. 监听触摸事件:为按钮组件设置TouchEvent监听器,监听用户的触摸操作。

  3. 处理触摸事件:在TouchEvent的回调方法中,根据触摸事件的不同阶段(如按下、移动、抬起)来更新按钮的位置。

  4. 更新按钮位置:在触摸移动阶段,通过获取触摸点的坐标,并更新按钮的Position属性,使其跟随手指移动。

以下是一个简单的代码示例:

import { Button, TouchEvent, TouchType } from '@ohos.arkui';

let button = new Button();
button.width = 100;
button.height = 50;
button.text = "拖拽我";

button.onTouch((event: TouchEvent) => {
    if (event.type === TouchType.Move) {
        let touchX = event.touches[0].x;
        let touchY = event.touches[0].y;
        button.position = { x: touchX - button.width / 2, y: touchY - button.height / 2 };
    }
});

// 将按钮添加到布局中
// layout.addComponent(button);

在这个示例中,按钮的位置会根据用户的触摸移动而更新,从而实现拖拽效果。

在HarmonyOS鸿蒙Next中实现按钮拖拽,可以通过以下步骤:

  1. 事件监听:为按钮设置TouchEventListener,监听触摸事件。
  2. 坐标更新:在onTouchEvent回调中,根据触摸事件的坐标更新按钮的位置。
  3. 布局更新:使用setPositionsetLayout方法动态调整按钮的布局参数。

示例代码:

button.setTouchEventListener((view, event) -> {
    if (event.getAction() == TouchEvent.PRIMARY_POINT_DOWN || event.getAction() == TouchEvent.POINT_MOVE) {
        int newX = (int) event.getPointerPosition(0).getX();
        int newY = (int) event.getPointerPosition(0).getY();
        button.setPosition(newX, newY);
    }
    return true;
});
回到顶部