feat: update project & add viewModel demo
This commit is contained in:
parent
60f5ce120d
commit
c644945c76
|
@ -22,13 +22,13 @@
|
||||||
"name": "default",
|
"name": "default",
|
||||||
"type": "HarmonyOS",
|
"type": "HarmonyOS",
|
||||||
"material": {
|
"material": {
|
||||||
"certpath": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_panel_com.example.myapplication_70086000144137060.cer",
|
"certpath": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony-template_com.example.myapplication_70086000144137060.cer",
|
||||||
"storePassword": "0000001B767E7E8C6D3EBFB6061DAE0E0136D0BDF27E3115977950BFFF98B3355E9353160B972AA3C07C07",
|
"storePassword": "0000001A4E024BA063005297DAF51A4E6AC02DC4110DB0F9ECDE58FB011E8C50A5CC87E5863792EEDF4C",
|
||||||
"keyAlias": "debugKey",
|
"keyAlias": "debugKey",
|
||||||
"keyPassword": "0000001BBD05595914755974A2674C85F88396B4366BFBEE8893724421C4C36C138D1BC83330092A159397",
|
"keyPassword": "0000001A19D14859F9DF7CA863C1E9DBBFA175415654D0A40427DA68F389526520D09076BFCDEB369B0A",
|
||||||
"profile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_panel_com.example.myapplication_70086000144137060.p7b",
|
"profile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony-template_com.example.myapplication_70086000144137060.p7b",
|
||||||
"signAlg": "SHA256withECDSA",
|
"signAlg": "SHA256withECDSA",
|
||||||
"storeFile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_panel_com.example.myapplication_70086000144137060.p12"
|
"storeFile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony-template_com.example.myapplication_70086000144137060.p12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
Binary file not shown.
Binary file not shown.
BIN
dependencies/hvigor-ohos-plugin-3.0.4-s.tgz
vendored
BIN
dependencies/hvigor-ohos-plugin-3.0.4-s.tgz
vendored
Binary file not shown.
BIN
dependencies/hvigor-ohos-plugin-3.0.9-s.tgz
vendored
Normal file
BIN
dependencies/hvigor-ohos-plugin-3.0.9-s.tgz
vendored
Normal file
Binary file not shown.
|
@ -7,6 +7,7 @@ import window from '@ohos.window';
|
||||||
export default class EntryAbility extends UIAbility {
|
export default class EntryAbility extends UIAbility {
|
||||||
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
|
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
|
||||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy() {
|
onDestroy() {
|
||||||
|
@ -17,7 +18,7 @@ export default class EntryAbility extends UIAbility {
|
||||||
// Main window is created, set main page for this ability
|
// Main window is created, set main page for this ability
|
||||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||||
|
|
||||||
windowStage.loadContent('pages/Init', (err, data) => {
|
windowStage.loadContent('pages/Index', (err, data) => {
|
||||||
if (err.code) {
|
if (err.code) {
|
||||||
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||||
return;
|
return;
|
||||||
|
@ -34,6 +35,35 @@ export default class EntryAbility extends UIAbility {
|
||||||
onForeground() {
|
onForeground() {
|
||||||
// Ability has brought to foreground
|
// Ability has brought to foreground
|
||||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
|
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
|
||||||
|
AlertDialog.show(
|
||||||
|
{
|
||||||
|
title: 'title',
|
||||||
|
subtitle: 'subtitle',
|
||||||
|
message: 'text',
|
||||||
|
autoCancel: true,
|
||||||
|
alignment: DialogAlignment.Bottom,
|
||||||
|
gridCount: 4,
|
||||||
|
offset: { dx: 0, dy: -20 },
|
||||||
|
primaryButton: {
|
||||||
|
value: 'cancel',
|
||||||
|
action: () => {
|
||||||
|
console.info('Callback when the first button is clicked')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
secondaryButton: {
|
||||||
|
enabled: true,
|
||||||
|
defaultFocus: true,
|
||||||
|
style: DialogButtonStyle.HIGHLIGHT,
|
||||||
|
value: 'ok',
|
||||||
|
action: () => {
|
||||||
|
console.info('Callback when the second button is clicked')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel: () => {
|
||||||
|
console.info('Closed callbacks')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onBackground() {
|
onBackground() {
|
||||||
|
|
|
@ -3,120 +3,17 @@ import { CustomPanel } from '../components/CustomPanel';
|
||||||
import curves from '@ohos.curves';
|
import curves from '@ohos.curves';
|
||||||
import { InnerView } from '../views/InnerView'
|
import { InnerView } from '../views/InnerView'
|
||||||
|
|
||||||
// 方案1:panel
|
|
||||||
// 方案2:模态转场
|
|
||||||
@Preview
|
@Preview
|
||||||
@Entry
|
@Entry
|
||||||
@Component
|
@Component
|
||||||
struct Index {
|
struct Index {
|
||||||
private TAG: string = 'Index'
|
private TAG: string = 'Index'
|
||||||
private defaultWidth: number = 350
|
|
||||||
@State message: string = "This a Template Project"
|
|
||||||
@State showPanel: boolean = false;
|
|
||||||
// 模态转场控制变量
|
|
||||||
@State isPresent: boolean = false;
|
|
||||||
@State contentWidth: number | string = this.defaultWidth;
|
|
||||||
@State marginLeft: number = 0;
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
innerView() {
|
|
||||||
InnerView();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleClose() {
|
|
||||||
this.isPresent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sidebar控制变量
|
|
||||||
controlValue = {
|
|
||||||
beginX: 0,
|
|
||||||
endX: 0,
|
|
||||||
maxMoveRate: 0.12,
|
|
||||||
swipeDirection: 0, // 0 is left, 1 is right
|
|
||||||
leftMoveDistance: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
@Builder
|
|
||||||
SideBar() {
|
|
||||||
InnerView()
|
|
||||||
.margin({ left: -this.marginLeft })
|
|
||||||
.width(this.contentWidth)
|
|
||||||
.height('100%')
|
|
||||||
.transition(// 通过转场动画实现出现消失转场动画效果,transition需要加在builder下的第一个组件
|
|
||||||
TransitionEffect.translate({ x: '-' + this.contentWidth, y: 0, z: 0 })
|
|
||||||
.animation({ curve: curves.springMotion(0.6, 0.8) })
|
|
||||||
)
|
|
||||||
.onTouch(event => {
|
|
||||||
// 按下赋初始值
|
|
||||||
if (event.type === TouchType.Down) {
|
|
||||||
this.controlValue.beginX = event.touches[0].displayX;
|
|
||||||
this.controlValue.leftMoveDistance = 0;
|
|
||||||
}
|
|
||||||
// 移动改变移动宽度
|
|
||||||
if (event.type === TouchType.Move) {
|
|
||||||
this.controlValue.endX = event.touches[0].displayX; // 手指停止的位置
|
|
||||||
const moveDistance = this.controlValue.beginX - this.controlValue.endX; // 滑动的水平距离
|
|
||||||
|
|
||||||
// 判断水平滑动方向
|
|
||||||
if (this.controlValue.leftMoveDistance > 0) {
|
|
||||||
this.controlValue.swipeDirection = 0;
|
|
||||||
} else {
|
|
||||||
this.controlValue.swipeDirection = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新
|
|
||||||
this.marginLeft = (this.marginLeft + moveDistance) > 0 ? (this.marginLeft + moveDistance) : 0;
|
|
||||||
|
|
||||||
this.controlValue.beginX = this.controlValue.endX;
|
|
||||||
|
|
||||||
this.controlValue.leftMoveDistance += moveDistance
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.type === TouchType.Up) {
|
|
||||||
console.log(this.TAG, 'TouchType up' + this.controlValue.leftMoveDistance);
|
|
||||||
if (this.controlValue.leftMoveDistance > this.controlValue.maxMoveRate * +this.defaultWidth) {
|
|
||||||
this.isPresent = false;
|
|
||||||
}
|
|
||||||
this.marginLeft = 0;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.gesture(
|
|
||||||
SwipeGesture({ direction: SwipeDirection.Horizontal })
|
|
||||||
.onAction((event?: GestureEvent) => {
|
|
||||||
if (event && this.controlValue.swipeDirection == 0) {
|
|
||||||
this.isPresent = false;
|
|
||||||
this.marginLeft = 0;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
) // 快速滑动关闭
|
|
||||||
}
|
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Row() {
|
Column() {
|
||||||
Button('open panel')
|
InnerView()
|
||||||
.onClick(() => this.showPanel = true);
|
|
||||||
Button('模态转场')// 通过选定的模态接口,绑定模态展示界面,ModalTransition是内置的ContentCover转场动画类型,这里选择None代表系统不加默认动画
|
|
||||||
.bindContentCover(this.isPresent, this.SideBar, ModalTransition.NONE)
|
|
||||||
.onClick(() => {
|
|
||||||
if (this.isPresent) {
|
|
||||||
this.isPresent = false;
|
|
||||||
this.isPresent = true;
|
|
||||||
} else {
|
|
||||||
this.isPresent = true;
|
|
||||||
}
|
|
||||||
this.contentWidth = this.defaultWidth;
|
|
||||||
})
|
|
||||||
|
|
||||||
CustomPanel({
|
|
||||||
contentView: () => this.innerView(),
|
|
||||||
show: this.showPanel,
|
|
||||||
defaultHeight: 500,
|
|
||||||
showDragBar: true
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
.width('100%')
|
|
||||||
.height('100%')
|
.height('100%')
|
||||||
.justifyContent(FlexAlign.SpaceEvenly)
|
.width('100%')
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
entry/src/main/ets/utils/arrayUtil.ets
Normal file
17
entry/src/main/ets/utils/arrayUtil.ets
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
export function range(start: number, end: number) {
|
||||||
|
const length = end - start;
|
||||||
|
const arr: number[] = new Array(length).fill(0).map((_: number, idx: number) => idx)
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Observed
|
||||||
|
export class ObservedArray<T> extends Array<T> {
|
||||||
|
constructor(args?: T[]) {
|
||||||
|
if (args instanceof Array) {
|
||||||
|
super(...args)
|
||||||
|
} else {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
entry/src/main/ets/viewModels/InnerViewModel.ets
Normal file
32
entry/src/main/ets/viewModels/InnerViewModel.ets
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import { ObservedArray, range } from '../utils/arrayUtil'
|
||||||
|
|
||||||
|
@Observed
|
||||||
|
export class InnerViewModel {
|
||||||
|
dataList: number[];
|
||||||
|
title: string = "This is a Inner View";
|
||||||
|
constrain: (value: number) => boolean = () => true
|
||||||
|
|
||||||
|
constructor(size: number = 3) {
|
||||||
|
this.dataList = range(0, size).reverse()
|
||||||
|
}
|
||||||
|
|
||||||
|
getTitle() {
|
||||||
|
return this.title
|
||||||
|
}
|
||||||
|
|
||||||
|
setConstrain(constrain: (value: number) => boolean = () => true) {
|
||||||
|
this.constrain = constrain
|
||||||
|
}
|
||||||
|
|
||||||
|
getDataList() {
|
||||||
|
return this.dataList.filter(item => this.constrain(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
addData() {
|
||||||
|
this.dataList = [this.dataList.length, ...this.dataList]
|
||||||
|
}
|
||||||
|
|
||||||
|
rmData(data: number) {
|
||||||
|
this.dataList = this.dataList.filter(item => item == data)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,42 @@
|
||||||
// TODO: 请扫点距离返回动画
|
import { ObservedArray, range } from '../utils/arrayUtil';
|
||||||
|
import { InnerViewModel } from '../viewModels/InnerViewModel';
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Component
|
@Component
|
||||||
export struct InnerView {
|
export struct InnerView {
|
||||||
@State message: string = "This is a Inner View";
|
@State viewModel: InnerViewModel = new InnerViewModel(12)
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
Column() {
|
Column({ space: 10 }) {
|
||||||
Text(this.message)
|
Text(this.viewModel.title)
|
||||||
.margin({ top: 10, bottom: 10 })
|
|
||||||
Scroll() {
|
Search().onChange(value => {
|
||||||
Column() {
|
value.trim() ?
|
||||||
ForEach(Array.from({ length: 20 }).map((_, idx) => idx + 1), item => {
|
this.viewModel.setConstrain(it => value.includes(String(it))) :
|
||||||
|
this.viewModel.setConstrain()
|
||||||
|
})
|
||||||
|
|
||||||
|
Button('Add Data').onClick(() => {
|
||||||
|
this.viewModel.addData()
|
||||||
|
})
|
||||||
|
|
||||||
|
List({ space: 10 }) {
|
||||||
|
ForEach(this.viewModel.getDataList(), (item: number) => {
|
||||||
|
ListItem() {
|
||||||
Text(`item: ${item}`)
|
Text(`item: ${item}`)
|
||||||
.width('100%')
|
|
||||||
.backgroundColor('#FFFFFF')
|
.backgroundColor('#FFFFFF')
|
||||||
.height(60)
|
.height(60)
|
||||||
.margin({ bottom: 10 })
|
|
||||||
.borderRadius(8)
|
.borderRadius(8)
|
||||||
|
.width('100%')
|
||||||
.padding({ left: 16, right: 16 })
|
.padding({ left: 16, right: 16 })
|
||||||
})
|
}
|
||||||
}
|
}, (item: number) => String(item))
|
||||||
.width('100%')
|
|
||||||
.padding({ left: 16, right: 16 })
|
|
||||||
}
|
}
|
||||||
|
.scrollBar(BarState.Off)
|
||||||
|
.layoutWeight(1)
|
||||||
}
|
}
|
||||||
|
.padding({ left: 16, right: 16, top: 16, bottom: 16 })
|
||||||
|
.width('100%')
|
||||||
.backgroundColor('#E6E8EC')
|
.backgroundColor('#E6E8EC')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"hvigorVersion": "file:../dependencies/hvigor-3.0.4-s.tgz",
|
"hvigorVersion": "file:../dependencies/hvigor-3.0.9-s.tgz",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-3.0.4-s.tgz",
|
"@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-3.0.9-s.tgz",
|
||||||
"rollup": "file:../dependencies/rollup.tgz"
|
"rollup": "file:../dependencies/rollup.tgz"
|
||||||
},
|
},
|
||||||
"execution": {
|
"execution": {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user