| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- import curves from '@ohos.curves'
- import { AddFormMenuItem } from '@kit.ArkUI'
- import { formBindingData } from '@kit.FormKit'
- import { getCount, IBestToast } from 'basic'
- @Component
- export struct MainView {
- @Prop displayArr: getCount[] = []
- columnsTemplate: string = '1fr 1fr'
- @BuilderParam item: () => void
- private columnsCount: number = 0
- @State private dragItemId: number = -1
- @State private scaleItemId: number = -1
- @State private offsetX: number = 0
- @State private offsetY: number = 0
- private dragRefOffsetx: number = 0
- private dragRefOffsety: number = 0
- private FIX_VP_X: number = 108
- private FIX_VP_Y: number = 120
- aboutToAppear() {
- const temArr: number[] = Array.from({ length: 11 })
- temArr.forEach((item, index) => {
- this.displayArr.push({ id: index })
- })
- this.columnsCount = this.columnsTemplate.split(' ').length
- }
- itemMove(index: number, newIndex: number): void {
- if (!this.isDraggable(newIndex)) {
- return;
- }
- // 创建临时数组
- const newNumbers = [...this.displayArr];
- const movedItem = newNumbers.splice(index, 1)[0]; // 直接获取数组第一个元素
- newNumbers.splice(newIndex, 0, movedItem);
- this.displayArr = newNumbers;
- }
- //向下滑
- down(index: number): void {
- // 指定固定GridItem不响应事件
- if (!this.isDraggable(index + this.columnsCount)) {
- return
- }
- this.offsetY -= this.FIX_VP_Y
- this.dragRefOffsety += this.FIX_VP_Y
- this.itemMove(index, index + this.columnsCount)
- }
- //向下滑(右下角为空)
- // down2(index: number): void {
- // if (!this.isDraggable(index + this.columnsCount)) {
- // return
- // }
- // this.offsetY -= this.FIX_VP_Y
- // this.dragRefOffsety += this.FIX_VP_Y
- // this.itemMove(index, index + this.columnsCount)
- // }
- //向上滑
- up(index: number): void {
- if (!this.isDraggable(index - this.columnsCount)) {
- return
- }
- this.offsetY += this.FIX_VP_Y
- this.dragRefOffsety -= this.FIX_VP_Y
- this.itemMove(index, index - this.columnsCount)
- }
- //向左滑
- left(index: number): void {
- if (!this.isDraggable(index - 1)) {
- return
- }
- this.offsetX += this.FIX_VP_X
- this.dragRefOffsetx -= this.FIX_VP_X
- this.itemMove(index, index - 1)
- }
- //向右滑
- right(index: number): void {
- if (!this.isDraggable(index + 1)) {
- return
- }
- this.offsetX -= this.FIX_VP_X
- this.dragRefOffsetx += this.FIX_VP_X
- this.itemMove(index, index + 1)
- }
- //向右下滑
- lowerRight(index: number): void {
- if (!this.isDraggable(index + this.columnsCount + 1)) {
- return
- }
- this.offsetX -= this.FIX_VP_X
- this.dragRefOffsetx += this.FIX_VP_X
- this.offsetY -= this.FIX_VP_Y
- this.dragRefOffsety += this.FIX_VP_Y
- this.itemMove(index, index + this.columnsCount + 1)
- }
- //向右上滑
- upperRight(index: number): void {
- if (!this.isDraggable(index - this.columnsCount + 1)) {
- return
- }
- this.offsetX -= this.FIX_VP_X
- this.dragRefOffsetx += this.FIX_VP_X
- this.offsetY += this.FIX_VP_Y
- this.dragRefOffsety -= this.FIX_VP_Y
- this.itemMove(index, index - this.columnsCount + 1)
- }
- //向左下滑
- lowerLeft(index: number): void {
- if (!this.isDraggable(index + 2)) {
- return
- }
- this.offsetX += this.FIX_VP_X
- this.dragRefOffsetx -= this.FIX_VP_X
- this.offsetY -= this.FIX_VP_Y
- this.dragRefOffsety += this.FIX_VP_Y
- this.itemMove(index, index + this.columnsCount - 1)
- }
- //向左上滑
- upperLeft(index: number): void {
- if (!this.isDraggable(index - this.columnsCount - 1)) {
- return
- }
- this.offsetX += this.FIX_VP_X
- this.dragRefOffsetx -= this.FIX_VP_X
- this.offsetY += this.FIX_VP_Y
- this.dragRefOffsety -= this.FIX_VP_Y
- this.itemMove(index, index - this.columnsCount - 1)
- }
- isDraggable(index: number): boolean {
- return index >= 0 && index < this.displayArr.length
- }
- build() {
- Column() {
- Grid() {
- ForEach(this.displayArr, (item: getCount, index) => {
- GridItem() {
- Text(item + '')
- .fontSize(16)
- .width('100%')
- .height('100%')
- .bindContextMenu(
- this.menu_4,
- ResponseType.LongPress, {
- placement: Placement.TopLeft,
- })
- .textAlign(TextAlign.Center)
- .borderRadius(10)
- .backgroundColor(0xF9CF93)
- .shadow(this.scaleItemId == item.id ? {
- radius: 70,
- color: '#15000000',
- offsetX: 0,
- offsetY: 0
- } :
- {
- radius: 0,
- color: '#15000000',
- offsetX: 0,
- offsetY: 0
- })
- .animation({ curve: Curve.Sharp, duration: 300 })
- // this.item()
- }
- .aspectRatio(1)
- // 指定固定GridItem不响应事件
- .hitTestBehavior(this.isDraggable(this.displayArr.indexOf(item)) ? HitTestMode.Default : HitTestMode.None)
- .scale({ x: this.scaleItemId == item.id ? 1.05 : 1, y: this.scaleItemId == item.id ? 1.05 : 1 })
- .zIndex(this.dragItemId === item.id ? 1 : 0)
- .translate(this.dragItemId === item.id ? { x: this.offsetX, y: this.offsetY } : { x: 0, y: 0 })
- .onAreaChange((_, newArea) => {
- if (index == 0) {
- this.FIX_VP_X = newArea.width as number
- this.FIX_VP_Y = newArea.height as number
- }
- })
- .gesture(
- // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件
- GestureGroup(GestureMode.Sequence,
- LongPressGesture({ repeat: true })
- .onAction((event?: GestureEvent) => {
- animateTo({ curve: Curve.Friction, duration: 300 }, () => {
- this.scaleItemId = item.id
- })
- })
- .onActionEnd(() => {
- animateTo({ curve: Curve.Friction, duration: 300 }, () => {
- this.scaleItemId = -1
- })
- }),
- PanGesture({ fingers: 1, direction: null, distance: 0 })
- .onActionStart(() => {
- this.dragItemId = item.id
- this.dragRefOffsetx = 0
- this.dragRefOffsety = 0
- })
- .onActionUpdate((event: GestureEvent) => {
- this.offsetY = event.offsetY - this.dragRefOffsety
- this.offsetX = event.offsetX - this.dragRefOffsetx
- let index = this.displayArr.findIndex(item => item.id == this.dragItemId)
- if (this.offsetY >= this.FIX_VP_Y / 2 && (this.offsetX <= 44 && this.offsetX >= -44) &&
- !this.isLastRow(index)) {
- //向下滑
- this.down(index)
- } else if (this.offsetY <= -this.FIX_VP_Y / 2 && (this.offsetX <= 44 && this.offsetX >= -44) &&
- !this.isFirstRow(index)) {
- //向上滑
- this.up(index)
- } else if (this.offsetX >= this.FIX_VP_X / 2 && (this.offsetY <= 50 && this.offsetY >= -50) &&
- !this.isLastColumn(index)) {
- //向右滑
- this.right(index)
- } else if (this.offsetX <= -this.FIX_VP_X / 2 && (this.offsetY <= 50 && this.offsetY >= -50) &&
- !this.isFirstColumn(index)) {
- //向左滑
- this.left(index)
- } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2 &&
- !this.isLastRow(index) && !this.isLastColumn(index)) {
- //向右下滑
- this.lowerRight(index)
- } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY <= -this.FIX_VP_Y / 2 &&
- !this.isFirstRow(index) && !this.isLastColumn(index)) {
- //向右上滑
- this.upperRight(index)
- } else if (this.offsetX <= -this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2 &&
- !this.isLastRow(index) && !this.isFirstColumn(index)) {
- //向左下滑
- this.lowerLeft(index)
- } else if (this.offsetX <= -this.FIX_VP_X / 2 && this.offsetY <= -this.FIX_VP_Y / 2 &&
- !this.isFirstRow(index) && !this.isFirstColumn(index)) {
- //向左上滑
- this.upperLeft(index)
- } else if (this.offsetX >= this.FIX_VP_X / 2 && this.offsetY >= this.FIX_VP_Y / 2 &&
- this.isLastRow(index) && this.isFirstColumn(index)) {
- //右下角为空的情况
- this.down(index)
- }
- })
- .onActionEnd(() => {
- animateTo({ curve: Curve.Linear, duration: 150 }, () => { // 缩短时间并简化曲线
- this.dragItemId = -1;
- });
- })
- )
- .onCancel(() => {
- animateTo({ curve: curves.interpolatingSpring(0, 1, 400, 38) }, () => {
- this.dragItemId = -1;
- })
- animateTo({
- curve: curves.interpolatingSpring(14, 1, 170, 17)
- }, () => {
- this.scaleItemId = -1
- })
- })
- )
- })
- }
- .width('100%')
- .editMode(true)
- .columnsGap(20)
- .rowsGap(20)
- .scrollBar(BarState.Off)
- .columnsTemplate(this.columnsTemplate)
- }.width('100%').height('100%').backgroundColor('#0D182431').padding({ top: 5 })
- }
- @Builder
- menu_4() {
- this.basicMenu('card_4', 4, 'fuWidget')
- }
- @Builder
- basicMenu(compId: string, form_dimension: number, form_name: string) {
- Menu() {
- AddFormMenuItem(
- {
- bundleName: 'com.ytpm.xjlrl', // 包名
- abilityName: 'EntryFormAbility', // 模块ability名称
- parameters: {
- 'ohos.extra.param.key.form_dimension': form_dimension, // 卡片尺寸,1代表1*2卡片,2代表2*2卡片,3代表2*4卡片,4代表4*4卡片,7代表6*4卡片,6代表1*1卡片
- 'ohos.extra.param.key.form_name': form_name, // 卡片名称
- 'ohos.extra.param.key.module_name': 'entry' // 卡片所属的模块名称
- },
- },
- compId,
- {
- formBindingData: formBindingData.createFormBindingData({ data: 'share' }),
- // formBindingData: formBindingData.createFormBindingData({ data: 'share' }),
- callback: (error, formId) => {
- if (!error) {
- IBestToast.show("添加成功")
- }
- },
- style: {
- options: {
- // startIcon: $r("app.media.icon"), // 菜单图标,可以自己提供。系统默认采用"sys.media.ic_public_add"
- content: "添加到桌面", // 菜单内容,可以自己提供。默认使用"sys.string.ohos_add_form_to_desktop"
- // endIcon: $r("app.media.icon") // 菜单图标,可以自己提供
- }
- }
- }
- )
- }
- }
- // 新增辅助方法:检查当前项是否在最后一行
- private isLastRow(index: number): boolean {
- const rowIndex = Math.floor(index / this.columnsCount);
- const totalRows = Math.ceil(this.displayArr.length / this.columnsCount);
- return rowIndex === totalRows - 1;
- }
- // 检查是否在第一行
- private isFirstRow(index: number): boolean {
- return Math.floor(index / this.columnsCount) === 0;
- }
- // 检查是否在最后一列
- private isLastColumn(index: number): boolean {
- return index % this.columnsCount === this.columnsCount - 1;
- }
- // 检查是否在第一列
- private isFirstColumn(index: number): boolean {
- return index % this.columnsCount === 0;
- }
- }
|