Skip to content

Commit 46397b6

Browse files
m-absPeterStaev
authored andcommitted
Implements #7: Scroll Horizontally (#24)
* chor: start implementing horizontal scroll * fix: tslint * chor: follow up on PR-review
1 parent 76f347b commit 46397b6

File tree

6 files changed

+98
-20
lines changed

6 files changed

+98
-20
lines changed

demo-ng/app/item/items.component.html

+10-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,17 @@
2323
core theme, such as p-20, btn, h2, and list-group. You can view a full list of the
2424
class names available for styling your app at https://docs.nativescript.org/ui/theme.
2525
-->
26-
<GridLayout class="page">
27-
<GridView [items]="items" colWidth="30%" rowHeight="100">
26+
<GridLayout class="page" rows="*, *">
27+
<GridView row="0" [items]="items" colWidth="33%" rowHeight="100" orientation="vertical">
2828
<ng-template let-item="item" let-odd="odd">
29-
<StackLayout margin="10" [nsRouterLink]="['/item', item.id]" borderColor="blue" borderWidth="2" borderRadius="5" verticalAlignment="stretch" class="list-group-item" [class.odd]="odd">
29+
<StackLayout [nsRouterLink]="['/item', item.id]" borderColor="blue" borderWidth="2" borderRadius="5" verticalAlignment="stretch" class="list-group-item" [class.odd]="odd">
30+
<Label verticalAlignment="center" [text]="item.name" class="list-group-item-text" textWrap="true"></Label>
31+
</StackLayout>
32+
</ng-template>
33+
</GridView>
34+
<GridView row="1" [items]="items" colWidth="33%" rowHeight="100" orientation="horizontal">
35+
<ng-template let-item="item" let-odd="odd">
36+
<StackLayout [nsRouterLink]="['/item', item.id]" borderColor="blue" borderWidth="2" borderRadius="5" verticalAlignment="stretch" class="list-group-item" [class.odd]="odd">
3037
<Label verticalAlignment="center" [text]="item.name" class="list-group-item-text" textWrap="true"></Label>
3138
</StackLayout>
3239
</ng-template>

demo-ng/package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,27 @@
2222
"nativescript-theme-core": "^1.0.4",
2323
"reflect-metadata": "~0.1.8",
2424
"rxjs": "~5.4.0",
25-
"tns-core-modules": "~3.1.0",
25+
"tns-core-modules": "^3.1.0",
2626
"zone.js": "~0.8.2"
2727
},
2828
"devDependencies": {
2929
"@angular/compiler-cli": "~4.1.0",
30-
"@ngtools/webpack": "~1.4.0",
30+
"@ngtools/webpack": "~1.5.0",
3131
"babel-traverse": "6.25.0",
3232
"babel-types": "6.25.0",
3333
"babylon": "6.17.4",
3434
"copy-webpack-plugin": "~4.0.1",
35-
"extract-text-webpack-plugin": "~2.1.0",
35+
"extract-text-webpack-plugin": "~3.0.0",
3636
"lazy": "1.0.11",
3737
"nativescript-css-loader": "~0.26.0",
3838
"nativescript-dev-sass": "^1.2.0",
3939
"nativescript-dev-typescript": "~0.5.0",
4040
"nativescript-dev-webpack": "^0.7.2",
4141
"raw-loader": "~0.5.1",
42-
"resolve-url-loader": "~2.0.2",
42+
"resolve-url-loader": "~2.1.0",
4343
"tns-platform-declarations": "^3.1.0",
44-
"typescript": "~2.3.0",
45-
"webpack": "~2.6.0",
44+
"typescript": "~2.3.4",
45+
"webpack": "~3.2.0",
4646
"webpack-bundle-analyzer": "^2.8.2",
4747
"webpack-sources": "~1.0.1"
4848
},

grid-view-common.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ limitations under the License.
1616

1717
import { ObservableArray } from "data/observable-array";
1818
import { parse } from "ui/builder";
19+
import { makeParser, makeValidator } from "ui/content-view";
1920
import { CoercibleProperty, Length, PercentLength, Property, Template, View } from "ui/core/view";
2021
import { addWeakEventListener, removeWeakEventListener } from "ui/core/weak-event-listener";
2122
import { ItemsSource } from "ui/list-view";
22-
import { GridView as GridViewDefinition } from ".";
23+
import { GridView as GridViewDefinition, Orientation } from ".";
2324

2425
const autoEffectiveRowHeight = 100;
2526
const autoEffectiveColWidth = 100;
@@ -36,6 +37,7 @@ export abstract class GridViewBase extends View implements GridViewDefinition {
3637
public static itemTapEvent = "itemTap";
3738
public static loadMoreItemsEvent = "loadMoreItems";
3839

40+
public orientation: Orientation;
3941
public itemTemplate: string | Template;
4042
public items: any[] | ItemsSource;
4143
public isItemsSourceIn: boolean;
@@ -53,10 +55,10 @@ export abstract class GridViewBase extends View implements GridViewDefinition {
5355
public onLayout(left: number, top: number, right: number, bottom: number) {
5456
super.onLayout(left, top, right, bottom);
5557

56-
this._innerWidth = right - this.effectivePaddingLeft - this.effectivePaddingRight;
58+
this._innerWidth = right - left - this.effectivePaddingLeft - this.effectivePaddingRight;
5759
this._effectiveColWidth = PercentLength.toDevicePixels(this.colWidth, autoEffectiveColWidth, this._innerWidth); // We cannot use 0 for auto as it throws for android.
5860

59-
this._innerHeight = bottom - this.effectivePaddingTop - this.effectivePaddingBottom;
61+
this._innerHeight = bottom - top - this.effectivePaddingTop - this.effectivePaddingBottom;
6062
this._effectiveRowHeight = PercentLength.toDevicePixels(this.rowHeight, autoEffectiveRowHeight, this._innerHeight);
6163
}
6264

@@ -141,4 +143,13 @@ export const colWidthProperty = new CoercibleProperty<GridViewBase, PercentLengt
141143
target.refresh();
142144
}
143145
});
144-
colWidthProperty.register(GridViewBase);
146+
colWidthProperty.register(GridViewBase);
147+
148+
const converter = makeParser<Orientation>(makeValidator("horizontal", "vertical"));
149+
export const orientationProperty = new Property<GridViewBase, Orientation>({
150+
name: "orientation", defaultValue: "vertical", affectsLayout: true,
151+
valueChanged: (target: GridViewBase, oldValue: Orientation, newValue: Orientation) => {
152+
target.refresh();
153+
},
154+
valueConverter: converter
155+
});

grid-view.android.ts

+45-4
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ import * as utils from "utils/utils";
2020
import {
2121
GridViewBase,
2222
colWidthProperty,
23+
orientationProperty,
2324
paddingBottomProperty,
2425
paddingLeftProperty,
2526
paddingRightProperty,
2627
paddingTopProperty,
2728
rowHeightProperty,
2829
} from "./grid-view-common";
2930

30-
import { GridItemEventData } from ".";
31+
import { GridItemEventData, Orientation } from ".";
3132

3233
export * from "./grid-view-common";
3334

@@ -43,8 +44,11 @@ export class GridView extends GridViewBase {
4344
recyclerView.setAdapter(adapter);
4445
(recyclerView as any).adapter = adapter;
4546

47+
const orientation = this._getLayoutManagarOrientation();
48+
4649
const layoutManager = new android.support.v7.widget.GridLayoutManager(this._context, 1);
4750
recyclerView.setLayoutManager(layoutManager);
51+
layoutManager.setOrientation(orientation);
4852
(recyclerView as any).layoutManager = layoutManager;
4953

5054
const scrollListener = new GridViewScrollListener(new WeakRef(this));
@@ -120,6 +124,23 @@ export class GridView extends GridViewBase {
120124
this._setPadding({ left: this.effectivePaddingLeft });
121125
}
122126

127+
public [orientationProperty.getDefault](): Orientation {
128+
const layoutManager = this.nativeView.getLayoutManager() as android.support.v7.widget.GridLayoutManager;
129+
if (layoutManager.getOrientation() === android.support.v7.widget.LinearLayoutManager.HORIZONTAL) {
130+
return "horizontal";
131+
}
132+
133+
return "vertical";
134+
}
135+
public [orientationProperty.setNative](value: Orientation) {
136+
const layoutManager = this.nativeView.getLayoutManager() as android.support.v7.widget.GridLayoutManager;
137+
if (value === "horizontal") {
138+
layoutManager.setOrientation(android.support.v7.widget.LinearLayoutManager.HORIZONTAL);
139+
} else {
140+
layoutManager.setOrientation(android.support.v7.widget.LinearLayoutManager.VERTICAL);
141+
}
142+
}
143+
123144
public eachChildView(callback: (child: View) => boolean): void {
124145
this._realizedItems.forEach((view, key) => {
125146
callback(view);
@@ -137,9 +158,16 @@ export class GridView extends GridViewBase {
137158
}
138159

139160
const layoutManager = this.nativeView.getLayoutManager() as android.support.v7.widget.GridLayoutManager;
140-
const spanCount = Math.max(Math.floor(this._innerWidth / this._effectiveColWidth), 1) || 1;
161+
let spanCount: number;
162+
163+
if (this.orientation === "horizontal") {
164+
spanCount = Math.max(Math.floor(this._innerHeight / this._effectiveRowHeight), 1) || 1;
165+
} else {
166+
spanCount = Math.max(Math.floor(this._innerWidth / this._effectiveColWidth), 1) || 1;
167+
}
141168

142169
layoutManager.setSpanCount(spanCount);
170+
143171
this.nativeView.getAdapter().notifyDataSetChanged();
144172
}
145173

@@ -163,6 +191,15 @@ export class GridView extends GridViewBase {
163191
const newValue = Object.assign(padding, newPadding);
164192
nativeView.setPadding(newValue.left, newValue.top, newValue.right, newValue.bottom);
165193
}
194+
195+
private _getLayoutManagarOrientation() {
196+
let orientation = android.support.v7.widget.LinearLayoutManager.VERTICAL;
197+
if (this.orientation === "horizontal") {
198+
orientation = android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
199+
}
200+
201+
return orientation;
202+
}
166203
}
167204

168205
class GridViewScrollListener extends android.support.v7.widget.RecyclerView.OnScrollListener {
@@ -258,8 +295,12 @@ class GridViewAdapter extends android.support.v7.widget.RecyclerView.Adapter {
258295
index,
259296
view: vh.view
260297
});
261-
262-
vh.view.height = utils.layout.toDeviceIndependentPixels(owner._effectiveRowHeight);
298+
299+
if (owner.orientation === "horizontal") {
300+
vh.view.width = utils.layout.toDeviceIndependentPixels(owner._effectiveColWidth);
301+
} else {
302+
vh.view.height = utils.layout.toDeviceIndependentPixels(owner._effectiveRowHeight);
303+
}
263304

264305
owner._prepareItem(vh.view, index);
265306
}

grid-view.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { PercentLength, Template, View } from "ui/core/view";
1818
import { ItemsSource } from "ui/list-view";
1919
import { EventData } from "data/observable";
2020

21+
export type Orientation = "horizontal" | "vertical"
22+
2123
export class GridView extends View {
2224
public static itemLoadingEvent: string;
2325
public static itemTapEvent: string;
@@ -27,6 +29,7 @@ export class GridView extends View {
2729
public itemTemplate: string | Template;
2830
public rowHeight: PercentLength;
2931
public colWidth: PercentLength;
32+
public orientation: Orientation;
3033

3134
public ios: any; /* UICollectionView */
3235
public android: any; /* android.support.v7.widget.RecyclerView */

grid-view.ios.ts

+19-3
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ import * as utils from "utils/utils";
2020

2121
import {
2222
GridViewBase,
23+
orientationProperty,
2324
paddingBottomProperty,
2425
paddingLeftProperty,
2526
paddingRightProperty,
26-
paddingTopProperty
27+
paddingTopProperty,
2728
} from "./grid-view-common";
2829

29-
import { GridItemEventData } from ".";
30+
import { GridItemEventData, Orientation } from ".";
3031

3132
export * from "./grid-view-common";
3233

@@ -108,6 +109,21 @@ export class GridView extends GridViewBase {
108109
this._setPadding({ left: utils.layout.toDeviceIndependentPixels(this.effectivePaddingLeft) });
109110
}
110111

112+
public [orientationProperty.getDefault](): Orientation {
113+
if (this._layout.scrollDirection === UICollectionViewScrollDirection.Horizontal) {
114+
return "horizontal";
115+
}
116+
117+
return "vertical";
118+
}
119+
public [orientationProperty.setNative](value: Orientation) {
120+
if (value === "horizontal") {
121+
this._layout.scrollDirection = UICollectionViewScrollDirection.Horizontal;
122+
} else {
123+
this._layout.scrollDirection = UICollectionViewScrollDirection.Vertical;
124+
}
125+
}
126+
111127
public eachChildView(callback: (child: View) => boolean): void {
112128
this._map.forEach((view, key) => {
113129
callback(view);
@@ -316,4 +332,4 @@ class UICollectionViewDelegateImpl extends NSObject implements UICollectionViewD
316332

317333
return indexPath;
318334
}
319-
}
335+
}

0 commit comments

Comments
 (0)