Problem Description
The nextMargin and prevMargin parameters are set to display three items on each page. After an application is exited and then returned to, the items on the left and right sides are not displayed.
Background Knowledge
The onAreaChange callback is triggered when the component area changes, and can be used to obtain the component's width and height..
Swiper is a slider view container that enables the child components to be displayed in a carousel manner. For details about the size attributes of Swiper, see Layout and constraints.
- displayCount Sets the number of elements displayed in the Swiper view.
- nextMargin Set the bottom margin to reveal a small portion of the next item.
- prevMargin Set the top margin to reveal a small portion of the previous item.
PrevMargin and nextMargin usage restrictions: When the main axis direction is set to horizontal or vertical, if either nextMargin or prevMargin is greater than the width or height of the child component, neither nextMargin nor prevMargin will be displayed.
Solution
- In Swiper, if you do not use displayCount to set the number of items to be displayed, the width of each page that the Swiper component slides is the width of the Swiper component by default. That is, the width of the child component is the same as that of the parent Swiper component.
- When prevMargin/nextMargin is used to set the display of the previous and next items, the width of the child component is reduced. For example, if 100 vp is set for the previous and next items, the width of the child component is the width of the Swiper minus 200 vp.
- Use prevMargin/nextMargin to display three items in the Swiper. To prevent the set value from being greater than the width and height of the child component and causing the setting to become invalid, you can use onAreaChange to obtain the width and height of the parent component Swiper, and accurately control the part where the previous and next items are displayed based on the width and height of the Swiper.
The following is an example code: Obtain the width of the Swiper swiperWidth, and set prevMargin and nextMargin to one third of swiperWidth. In this case, the width of the child component is also one third of the Swiper.
import { common } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
@Entry
@Component
struct SwiperMargin {
private swiperController: SwiperController = new SwiperController();
@State swiperHeight: number = 0;
@State swiperWidth: number = 0;
private data: number[] = [];
@State currentIndex: number = 1;
aboutToAppear(): void {
for (let i = 1; i <= 10; i++) {
this.data.push(i);
}
}
onPageShow(): void {
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
window.getLastWindow(context).then((lastWindow) => {
lastWindow.setPreferredOrientation(window.Orientation.LANDSCAPE);
});
const routerParams = this.getUIContext().getRouter().getParams() as Record<string, number>;
if (routerParams !== undefined && routerParams !== null) {
console.info(`test ${routerParams.data2}`);
this.swiperController.changeIndex(routerParams.data2);
}
}
build() {
Column() {
Row({ space: 12 }) {
Text(`Currently on page ${this.currentIndex + 1}, out of ${this.data.length} pages.`)
.margin({top: 24, left: 48, right: 48})
}
.onClick(() => {
this.getUIContext().getRouter().pushUrl({
url: 'pages/Page', params: {
data1: this.currentIndex + 1
}
});
});
Swiper(this.swiperController) {
ForEach(this.data, (item: string) => {
Text(item.toString())
.margin({ top: 10, bottom: 10})
.height('25%')
.backgroundColor(0xAFEEEE)
.textAlign(TextAlign.Center)
.fontSize(30);
}, (item: string) => item);
}
.vertical(true)
.width('80%')
.height('90%')
.loop(false)
.index($$this.currentIndex)
.indicator(true)
.loop(false)
.duration(1000)
.itemSpace(0)
.onChange((number) => {
this.currentIndex = number;
})
.onAreaChange((_: Area, newValue: Area) => {
this.swiperHeight = newValue.height as number;
this.swiperWidth = newValue.width as number;
})
.nextMargin(this.swiperHeight / 3)
.prevMargin(this.swiperHeight / 3);
}
.justifyContent(FlexAlign.Center)
.width('100%')
}
}
import { window } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct Page {
message: string = 'Hello World';
@State parm: number = 0;
aboutToAppear(): void {
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
window.getLastWindow(context).then((lastWindow) => {
lastWindow.setPreferredOrientation(window.Orientation.PORTRAIT);
});
const routerParams = this.getUIContext().getRouter().getParams() as Record<string, number>;
if (routerParams !== undefined && routerParams !== null) {
this.parm = routerParams.data1;
} else {
this.parm = -1;
}
}
build() {
RelativeContainer() {
Text(`${this.message}${this.parm}`)
.id('PageHelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(() => {
this.getUIContext().getRouter().back({
url: 'pages/SwiperMargin',
params: {
data2: this.parm - 1
}
});
});
}
.height('100%')
.width('100%');
}
}
Verification Result
Q: Why do the prevMargin ('10%') and nextMargin ('10%') settings for Swiper not take effect?
A: The top and bottom margins cannot be set to percentages.

Top comments (0)