mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
fix(listview): incorrect layout when scroll (#6656)
This commit is contained in:
31
apps/app/ui-tests-app/issues/issue-ng-repo-1626.ts
Normal file
31
apps/app/ui-tests-app/issues/issue-ng-repo-1626.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { fromObject } from "tns-core-modules/data/observable";
|
||||||
|
|
||||||
|
export function onLoaded(args) {
|
||||||
|
const page = args.object;
|
||||||
|
page.bindingContext = fromObject({
|
||||||
|
items: [
|
||||||
|
{ id: 1, name: "Ter Stegen", role: "Goalkeeper" },
|
||||||
|
{ id: 3, name: "Piqué", role: "Defender" },
|
||||||
|
{ id: 4, name: "I. Rakitic", role: "Midfielder" },
|
||||||
|
{ id: 5, name: "Sergio", role: "Midfielder" },
|
||||||
|
{ id: 6, name: "Denis Suárez", role: "Midfielder\nSecond line for the sake of testing" },
|
||||||
|
{ id: 7, name: "Arda", role: "Midfielder" },
|
||||||
|
{ id: 8, name: "A. Iniesta", role: "Midfielder" },
|
||||||
|
{ id: 9, name: "Suárez", role: "Forward" },
|
||||||
|
{ id: 10, name: "Messi", role: "Forward" },
|
||||||
|
{ id: 11, name: "Neymar", role: "Forward\nSecond line for the sake of testing" },
|
||||||
|
{ id: 12, name: "Rafinha", role: "Midfielder\nSecond line for the sake of testing" },
|
||||||
|
{ id: 13, name: "Cillessen", role: "Goalkeeper\nSecond line for the sake of testing" },
|
||||||
|
{ id: 14, name: "Mascherano", role: "Defender" },
|
||||||
|
{ id: 17, name: "Paco Alcácer", role: "Forward" },
|
||||||
|
{ id: 18, name: "Jordi Alba", role: "Defender\nSecond line for the sake of testing" },
|
||||||
|
{ id: 19, name: "Digne", role: "Defender" },
|
||||||
|
{ id: 20, name: "Sergi Roberto", role: "Midfielder\nSecond line for the sake of testing" },
|
||||||
|
{ id: 21, name: "André Gomes", role: "Midfielder\nSecond line for the sake of testing" },
|
||||||
|
{ id: 22, name: "Aleix Vidal", role: "Midfielder" },
|
||||||
|
{ id: 23, name: "Umtiti", role: "Defender" },
|
||||||
|
{ id: 24, name: "Mathieu", role: "Defender" },
|
||||||
|
{ id: 25, name: "Masip", role: "Goalkeeper" },
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
28
apps/app/ui-tests-app/issues/issue-ng-repo-1626.xml
Normal file
28
apps/app/ui-tests-app/issues/issue-ng-repo-1626.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<Page loaded="onLoaded">
|
||||||
|
<ActionBar title="issue-ng-repo-1626"></ActionBar>
|
||||||
|
|
||||||
|
<StackLayout backgroundColor="red">
|
||||||
|
<ListView items="{{ items }}" class="list-group">
|
||||||
|
<ListView.itemTemplate>
|
||||||
|
<StackLayout>
|
||||||
|
<StackLayout backgroundColor="gray">
|
||||||
|
<Label text="{{ name }}" class="list-group-item"></Label>
|
||||||
|
<Label text="{{ id }}" class="list-group-item"></Label>
|
||||||
|
</StackLayout>
|
||||||
|
<StackLayout backgroundColor="darkgray">
|
||||||
|
<StackLayout backgroundColor="darkblue">
|
||||||
|
<Label text="{{ role }}"></Label>
|
||||||
|
<Label text="id is odd" visibility="{{ id%2 == 1 ? 'visible' : 'collapsed' }}"></Label>
|
||||||
|
</StackLayout>
|
||||||
|
<StackLayout backgroundColor="darkred">
|
||||||
|
<Label text="{{ role }}"></Label>
|
||||||
|
<Label text="id is odd" visibility="{{ id%2 == 1 ? 'visible' : 'collapsed' }}"></Label>
|
||||||
|
</StackLayout>
|
||||||
|
<Label text="{{ role }}"></Label>
|
||||||
|
<Label text="id is odd" visibility="{{ id%2 == 1 ? 'visible' : 'collapsed' }}"></Label>
|
||||||
|
</StackLayout>
|
||||||
|
</StackLayout>
|
||||||
|
</ListView.itemTemplate>
|
||||||
|
</ListView>
|
||||||
|
</StackLayout>
|
||||||
|
</Page>
|
||||||
@@ -28,6 +28,7 @@ export function loadExamples() {
|
|||||||
examples.set("4450", "issues/issue-4450");
|
examples.set("4450", "issues/issue-4450");
|
||||||
examples.set("5274", "issues/issue-5274");
|
examples.set("5274", "issues/issue-5274");
|
||||||
examples.set("ng-repo-1599", "issues/issue-ng-repo-1599");
|
examples.set("ng-repo-1599", "issues/issue-ng-repo-1599");
|
||||||
|
examples.set("ng-repo-1626", "issues/issue-ng-repo-1626");
|
||||||
examples.set("6439", "issues/issue-6439");
|
examples.set("6439", "issues/issue-6439");
|
||||||
|
|
||||||
return examples;
|
return examples;
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
ViewBase, Property, booleanConverter, EventData, layout,
|
ViewBase, Property, booleanConverter, EventData, layout,
|
||||||
getEventOrGestureName, traceEnabled, traceWrite, traceCategories
|
getEventOrGestureName, traceEnabled, traceWrite, traceCategories,
|
||||||
|
InheritedProperty
|
||||||
} from "../view-base";
|
} from "../view-base";
|
||||||
|
|
||||||
import { HorizontalAlignment, VerticalAlignment, Visibility, Length, PercentLength } from "../../styling/style-properties";
|
import { HorizontalAlignment, VerticalAlignment, Visibility, Length, PercentLength } from "../../styling/style-properties";
|
||||||
@@ -588,6 +589,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
|||||||
public isEnabled: boolean;
|
public isEnabled: boolean;
|
||||||
public isUserInteractionEnabled: boolean;
|
public isUserInteractionEnabled: boolean;
|
||||||
public iosOverflowSafeArea: boolean;
|
public iosOverflowSafeArea: boolean;
|
||||||
|
public iosOverflowSafeAreaEnabled: boolean;
|
||||||
|
|
||||||
get isLayoutValid(): boolean {
|
get isLayoutValid(): boolean {
|
||||||
return this._isLayoutValid;
|
return this._isLayoutValid;
|
||||||
@@ -1031,3 +1033,6 @@ isUserInteractionEnabledProperty.register(ViewCommon);
|
|||||||
|
|
||||||
export const iosOverflowSafeAreaProperty = new Property<ViewCommon, boolean>({ name: "iosOverflowSafeArea", defaultValue: false, valueConverter: booleanConverter });
|
export const iosOverflowSafeAreaProperty = new Property<ViewCommon, boolean>({ name: "iosOverflowSafeArea", defaultValue: false, valueConverter: booleanConverter });
|
||||||
iosOverflowSafeAreaProperty.register(ViewCommon);
|
iosOverflowSafeAreaProperty.register(ViewCommon);
|
||||||
|
|
||||||
|
export const iosOverflowSafeAreaEnabledProperty = new InheritedProperty<ViewCommon, boolean>({ name: "iosOverflowSafeAreaEnabled", defaultValue: true, valueConverter: booleanConverter });
|
||||||
|
iosOverflowSafeAreaEnabledProperty.register(ViewCommon);
|
||||||
|
|||||||
8
tns-core-modules/ui/core/view/view.d.ts
vendored
8
tns-core-modules/ui/core/view/view.d.ts
vendored
@@ -3,7 +3,7 @@
|
|||||||
*/ /** */
|
*/ /** */
|
||||||
|
|
||||||
///<reference path="../../../tns-core-modules.d.ts" /> Include global typings
|
///<reference path="../../../tns-core-modules.d.ts" /> Include global typings
|
||||||
import { ViewBase, Property, EventData, Color } from "../view-base";
|
import { ViewBase, Property, InheritedProperty, EventData, Color } from "../view-base";
|
||||||
import { Animation, AnimationDefinition, AnimationPromise } from "../../animation";
|
import { Animation, AnimationDefinition, AnimationPromise } from "../../animation";
|
||||||
import { HorizontalAlignment, VerticalAlignment, Visibility, Length, PercentLength } from "../../styling/style-properties";
|
import { HorizontalAlignment, VerticalAlignment, Visibility, Length, PercentLength } from "../../styling/style-properties";
|
||||||
import { GestureTypes, GestureEventData, GesturesObserver } from "../../gestures";
|
import { GestureTypes, GestureEventData, GesturesObserver } from "../../gestures";
|
||||||
@@ -349,6 +349,11 @@ export abstract class View extends ViewBase {
|
|||||||
*/
|
*/
|
||||||
iosOverflowSafeArea: boolean;
|
iosOverflowSafeArea: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or disables the iosOverflowSafeArea property for all children. This property is iOS specific. Default value: true
|
||||||
|
*/
|
||||||
|
iosOverflowSafeAreaEnabled: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets is layout is valid. This is a read-only property.
|
* Gets is layout is valid. This is a read-only property.
|
||||||
*/
|
*/
|
||||||
@@ -797,6 +802,7 @@ export const originYProperty: Property<View, number>;
|
|||||||
export const isEnabledProperty: Property<View, boolean>;
|
export const isEnabledProperty: Property<View, boolean>;
|
||||||
export const isUserInteractionEnabledProperty: Property<View, boolean>;
|
export const isUserInteractionEnabledProperty: Property<View, boolean>;
|
||||||
export const iosOverflowSafeAreaProperty: Property<View, boolean>;
|
export const iosOverflowSafeAreaProperty: Property<View, boolean>;
|
||||||
|
export const iosOverflowSafeAreaEnabledProperty: InheritedProperty<View, boolean>;
|
||||||
|
|
||||||
export namespace ios {
|
export namespace ios {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ export class View extends ViewCommon {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.iosOverflowSafeArea) {
|
if (!this.iosOverflowSafeArea || !this.iosOverflowSafeAreaEnabled) {
|
||||||
return ios.shrinkToSafeArea(this, frame);
|
return ios.shrinkToSafeArea(this, frame);
|
||||||
} else if (this.nativeViewProtected && this.nativeViewProtected.window) {
|
} else if (this.nativeViewProtected && this.nativeViewProtected.window) {
|
||||||
return ios.expandBeyondSafeArea(this, frame);
|
return ios.expandBeyondSafeArea(this, frame);
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ class DataSource extends NSObject implements UITableViewDataSource {
|
|||||||
let width = layout.getMeasureSpecSize(owner.widthMeasureSpec);
|
let width = layout.getMeasureSpecSize(owner.widthMeasureSpec);
|
||||||
let rowHeight = owner._effectiveRowHeight;
|
let rowHeight = owner._effectiveRowHeight;
|
||||||
let cellHeight = rowHeight > 0 ? rowHeight : owner.getHeight(indexPath.row);
|
let cellHeight = rowHeight > 0 ? rowHeight : owner.getHeight(indexPath.row);
|
||||||
|
cellView.iosOverflowSafeAreaEnabled = false;
|
||||||
View.layoutChild(owner, cellView, 0, 0, width, cellHeight);
|
View.layoutChild(owner, cellView, 0, 0, width, cellHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -389,6 +390,7 @@ export class ListView extends ListViewBase {
|
|||||||
let cellHeight = rowHeight > 0 ? rowHeight : this.getHeight(childView._listViewItemIndex);
|
let cellHeight = rowHeight > 0 ? rowHeight : this.getHeight(childView._listViewItemIndex);
|
||||||
if (cellHeight) {
|
if (cellHeight) {
|
||||||
let width = layout.getMeasureSpecSize(this.widthMeasureSpec);
|
let width = layout.getMeasureSpecSize(this.widthMeasureSpec);
|
||||||
|
childView.iosOverflowSafeAreaEnabled = false;
|
||||||
View.layoutChild(this, childView, 0, 0, width, cellHeight);
|
View.layoutChild(this, childView, 0, 0, width, cellHeight);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user