feat:scroller add onScroll and onScrollEnd property

This commit is contained in:
pengfei.zhou 2020-03-03 15:51:20 +08:00 committed by osborn
parent 0fa121e54f
commit 021fdab35f
16 changed files with 141 additions and 3 deletions

View File

@ -15,6 +15,10 @@
*/ */
package pub.doric.shader; package pub.doric.shader;
import android.text.TextUtils;
import android.util.Log;
import com.github.pengfeizhou.jscore.JSONBuilder;
import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSObject;
import com.github.pengfeizhou.jscore.JSValue; import com.github.pengfeizhou.jscore.JSValue;
@ -36,6 +40,9 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
private String mChildViewId; private String mChildViewId;
private ViewNode mChildNode; private ViewNode mChildNode;
private DoricScrollChangeListener doricScrollChangeListener; private DoricScrollChangeListener doricScrollChangeListener;
private String onScrollFuncId;
private String onScrollEndFuncId;
public ScrollerNode(DoricContext doricContext) { public ScrollerNode(DoricContext doricContext) {
super(doricContext); super(doricContext);
@ -57,11 +64,30 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
protected HVScrollView build() { protected HVScrollView build() {
HVScrollView hvScrollView = new HVScrollView(getContext()); HVScrollView hvScrollView = new HVScrollView(getContext());
hvScrollView.setOnScrollChangeListener(new HVScrollView.OnScrollChangeListener() { hvScrollView.setOnScrollChangeListener(new HVScrollView.OnScrollChangeListener() {
@Override @Override
public void onScrollChange(HVScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { public void onScrollChange(HVScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (doricScrollChangeListener != null) { if (doricScrollChangeListener != null) {
doricScrollChangeListener.onScrollChange(v, scrollX, scrollY, oldScrollX, oldScrollY); doricScrollChangeListener.onScrollChange(v, scrollX, scrollY, oldScrollX, oldScrollY);
} }
if (!TextUtils.isEmpty(onScrollFuncId)) {
callJSResponse(onScrollFuncId, new JSONBuilder()
.put("x", DoricUtils.px2dp(scrollX))
.put("y", DoricUtils.px2dp(scrollY))
.toJSONObject());
}
}
@Override
public void onScrollEnd(HVScrollView v, int scrollX, int scrollY) {
if (!TextUtils.isEmpty(onScrollEndFuncId)) {
callJSResponse(
onScrollEndFuncId,
new JSONBuilder()
.put("x", DoricUtils.px2dp(scrollX))
.put("y", DoricUtils.px2dp(scrollY))
.toJSONObject());
}
} }
}); });
return hvScrollView; return hvScrollView;
@ -71,6 +97,10 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
protected void blend(HVScrollView view, String name, JSValue prop) { protected void blend(HVScrollView view, String name, JSValue prop) {
if ("content".equals(name)) { if ("content".equals(name)) {
mChildViewId = prop.asString().value(); mChildViewId = prop.asString().value();
} else if ("onScroll".equals(name)) {
onScrollFuncId = prop.asString().value();
} else if ("onScrollEnd".equals(name)) {
onScrollEndFuncId = prop.asString().value();
} else { } else {
super.blend(view, name, prop); super.blend(view, name, prop);
} }

View File

@ -89,6 +89,8 @@ public class HVScrollView extends FrameLayout implements NestedScrollingParent,
*/ */
void onScrollChange(HVScrollView v, int scrollX, int scrollY, void onScrollChange(HVScrollView v, int scrollX, int scrollY,
int oldScrollX, int oldScrollY); int oldScrollX, int oldScrollY);
void onScrollEnd(HVScrollView v, int scrollX, int scrollY);
} }
private long mLastScroll; private long mLastScroll;
@ -690,6 +692,9 @@ public class HVScrollView extends FrameLayout implements NestedScrollingParent,
return; return;
} }
mScrollState = state; mScrollState = state;
if (state == SCROLL_STATE_IDLE && mOnScrollChangeListener != null) {
mOnScrollChangeListener.onScrollEnd(this, getScrollX(), getScrollY());
}
} }
private void cancelTouch() { private void cancelTouch() {

View File

@ -134,10 +134,17 @@ class MovieVH extends ViewHolder {
class MovieVM extends ViewModel<MovieModel, MovieVH>{ class MovieVM extends ViewModel<MovieModel, MovieVH>{
onAttached() { onAttached(state: MovieModel, vh: MovieVH) {
network(context).get("https://douban.uieee.com/v2/movie/top250").then(ret => { network(context).get("https://douban.uieee.com/v2/movie/top250").then(ret => {
this.updateState(state => state.doubanModel = JSON.parse(ret.data) as DoubanModel) this.updateState(state => state.doubanModel = JSON.parse(ret.data) as DoubanModel)
}) })
vh.scrolled.onScroll = (offset) => {
const centerX = offset.x + Environment.screenWidth / 2
const idx = Math.floor(centerX / (270 / 2 * 1.5))
if (state.selectedIdx != idx) {
this.updateState(state => state.selectedIdx = idx)
}
}
} }
onBind(state: MovieModel, vh: MovieVH) { onBind(state: MovieModel, vh: MovieVH) {
@ -156,7 +163,6 @@ class MovieVM extends ViewModel<MovieModel, MovieVH>{
scaleX: state.selectedIdx == idx ? 1.5 : 1, scaleX: state.selectedIdx == idx ? 1.5 : 1,
scaleY: state.selectedIdx == idx ? 1.5 : 1, scaleY: state.selectedIdx == idx ? 1.5 : 1,
onClick: function () { onClick: function () {
vm.updateState(state => state.selectedIdx = idx)
const v = (this as Image).superview const v = (this as Image).superview
if (v == undefined) { if (v == undefined) {
return return

View File

@ -51,6 +51,8 @@ - (void)layoutSelf:(CGSize)targetSize {
@interface DoricScrollerNode () <UIScrollViewDelegate> @interface DoricScrollerNode () <UIScrollViewDelegate>
@property(nonatomic, strong) DoricViewNode *childNode; @property(nonatomic, strong) DoricViewNode *childNode;
@property(nonatomic, copy) NSString *childViewId; @property(nonatomic, copy) NSString *childViewId;
@property(nonatomic, copy) NSString *onScrollFuncId;
@property(nonatomic, copy) NSString *onScrollEndFuncId;
@end @end
@implementation DoricScrollerNode @implementation DoricScrollerNode
@ -116,6 +118,10 @@ - (void)blend:(NSDictionary *)props {
- (void)blendView:(DoricScrollView *)view forPropName:(NSString *)name propValue:(id)prop { - (void)blendView:(DoricScrollView *)view forPropName:(NSString *)name propValue:(id)prop {
if ([@"content" isEqualToString:name]) { if ([@"content" isEqualToString:name]) {
self.childViewId = prop; self.childViewId = prop;
} else if ([@"onScroll" isEqualToString:name]) {
self.onScrollFuncId = prop;
} else if ([@"onScrollEnd" isEqualToString:name]) {
self.onScrollEndFuncId = prop;
} else { } else {
[super blendView:view forPropName:name propValue:prop]; [super blendView:view forPropName:name propValue:prop];
} }
@ -136,6 +142,14 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (self.didScrollListener) { if (self.didScrollListener) {
self.didScrollListener(scrollView); self.didScrollListener(scrollView);
} }
if (self.onScrollFuncId) {
[self callJSResponse:self.onScrollFuncId,
@{
@"x": @(self.view.contentOffset.x),
@"y": @(self.view.contentOffset.y),
},
nil];
}
} }
- (void)scrollTo:(NSDictionary *)params { - (void)scrollTo:(NSDictionary *)params {

View File

@ -2029,6 +2029,14 @@ var Scroller = /** @class */ (function (_super) {
Property, Property,
__metadata$7("design:type", Object) __metadata$7("design:type", Object)
], Scroller.prototype, "contentOffset", void 0); ], Scroller.prototype, "contentOffset", void 0);
__decorate$7([
Property,
__metadata$7("design:type", Function)
], Scroller.prototype, "onScroll", void 0);
__decorate$7([
Property,
__metadata$7("design:type", Function)
], Scroller.prototype, "onScrollEnd", void 0);
return Scroller; return Scroller;
}(Superview)); }(Superview));
@ -3040,6 +3048,9 @@ var ViewModel = /** @class */ (function () {
ViewModel.prototype.getState = function () { ViewModel.prototype.getState = function () {
return this.state; return this.state;
}; };
ViewModel.prototype.getViewHolder = function () {
return this.viewHolder;
};
ViewModel.prototype.updateState = function (setter) { ViewModel.prototype.updateState = function (setter) {
setter(this.state); setter(this.state);
this.onBind(this.state, this.viewHolder); this.onBind(this.state, this.viewHolder);

View File

@ -1510,6 +1510,14 @@ __decorate$7([
Property, Property,
__metadata$7("design:type", Object) __metadata$7("design:type", Object)
], Scroller.prototype, "contentOffset", void 0); ], Scroller.prototype, "contentOffset", void 0);
__decorate$7([
Property,
__metadata$7("design:type", Function)
], Scroller.prototype, "onScroll", void 0);
__decorate$7([
Property,
__metadata$7("design:type", Function)
], Scroller.prototype, "onScrollEnd", void 0);
var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) { var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@ -2258,6 +2266,9 @@ class ViewModel {
getState() { getState() {
return this.state; return this.state;
} }
getViewHolder() {
return this.viewHolder;
}
updateState(setter) { updateState(setter) {
setter(this.state); setter(this.state);
this.onBind(this.state, this.viewHolder); this.onBind(this.state, this.viewHolder);

View File

@ -2969,6 +2969,14 @@ __decorate$7([
Property, Property,
__metadata$7("design:type", Object) __metadata$7("design:type", Object)
], Scroller.prototype, "contentOffset", void 0); ], Scroller.prototype, "contentOffset", void 0);
__decorate$7([
Property,
__metadata$7("design:type", Function)
], Scroller.prototype, "onScroll", void 0);
__decorate$7([
Property,
__metadata$7("design:type", Function)
], Scroller.prototype, "onScrollEnd", void 0);
var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) { var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@ -3717,6 +3725,9 @@ class ViewModel {
getState() { getState() {
return this.state; return this.state;
} }
getViewHolder() {
return this.viewHolder;
}
updateState(setter) { updateState(setter) {
setter(this.state); setter(this.state);
this.onBind(this.state, this.viewHolder); this.onBind(this.state, this.viewHolder);

9
doric-js/index.d.ts vendored
View File

@ -587,6 +587,14 @@ declare module 'doric/lib/src/widget/scroller' {
x: number; x: number;
y: number; y: number;
}; };
onScroll?: (offset: {
x: number;
y: number;
}) => void;
onScrollEnd?: (offset: {
x: number;
y: number;
}) => void;
allSubviews(): View[]; allSubviews(): View[];
toModel(): NativeViewModel; toModel(): NativeViewModel;
scrollTo(context: BridgeContext, offset: { scrollTo(context: BridgeContext, offset: {
@ -1139,6 +1147,7 @@ declare module 'doric/lib/src/pattern/mvvm' {
export abstract class ViewModel<M extends Object, V extends ViewHolder> { export abstract class ViewModel<M extends Object, V extends ViewHolder> {
constructor(obj: M, v: V); constructor(obj: M, v: V);
getState(): M; getState(): M;
getViewHolder(): V;
updateState(setter: Setter<M>): void; updateState(setter: Setter<M>): void;
attach(view: Group): void; attach(view: Group): void;
abstract onAttached(state: M, vh: V): void; abstract onAttached(state: M, vh: V): void;

View File

@ -9,6 +9,7 @@ export declare abstract class ViewModel<M extends Object, V extends ViewHolder>
private viewHolder; private viewHolder;
constructor(obj: M, v: V); constructor(obj: M, v: V);
getState(): M; getState(): M;
getViewHolder(): V;
updateState(setter: Setter<M>): void; updateState(setter: Setter<M>): void;
attach(view: Group): void; attach(view: Group): void;
abstract onAttached(state: M, vh: V): void; abstract onAttached(state: M, vh: V): void;

View File

@ -9,6 +9,9 @@ export class ViewModel {
getState() { getState() {
return this.state; return this.state;
} }
getViewHolder() {
return this.viewHolder;
}
updateState(setter) { updateState(setter) {
setter(this.state); setter(this.state);
this.onBind(this.state, this.viewHolder); this.onBind(this.state, this.viewHolder);

View File

@ -14,6 +14,14 @@ export declare class Scroller extends Superview implements IScroller {
x: number; x: number;
y: number; y: number;
}; };
onScroll?: (offset: {
x: number;
y: number;
}) => void;
onScrollEnd?: (offset: {
x: number;
y: number;
}) => void;
allSubviews(): View[]; allSubviews(): View[];
toModel(): NativeViewModel; toModel(): NativeViewModel;
scrollTo(context: BridgeContext, offset: { scrollTo(context: BridgeContext, offset: {

View File

@ -54,3 +54,11 @@ __decorate([
Property, Property,
__metadata("design:type", Object) __metadata("design:type", Object)
], Scroller.prototype, "contentOffset", void 0); ], Scroller.prototype, "contentOffset", void 0);
__decorate([
Property,
__metadata("design:type", Function)
], Scroller.prototype, "onScroll", void 0);
__decorate([
Property,
__metadata("design:type", Function)
], Scroller.prototype, "onScrollEnd", void 0);

View File

@ -35,6 +35,10 @@ export abstract class ViewModel<M extends Object, V extends ViewHolder> {
return this.state return this.state
} }
getViewHolder() {
return this.viewHolder;
}
updateState(setter: Setter<M>) { updateState(setter: Setter<M>) {
setter(this.state) setter(this.state)
this.onBind(this.state, this.viewHolder) this.onBind(this.state, this.viewHolder)

View File

@ -40,6 +40,12 @@ export class Scroller extends Superview implements IScroller {
@Property @Property
contentOffset?: { x: number, y: number } contentOffset?: { x: number, y: number }
@Property
onScroll?: (offset: { x: number, y: number }) => void
@Property
onScrollEnd?: (offset: { x: number, y: number }) => void
allSubviews() { allSubviews() {
return [this.content] return [this.content]
} }

View File

@ -3027,6 +3027,14 @@ __decorate$7([
Property, Property,
__metadata$7("design:type", Object) __metadata$7("design:type", Object)
], Scroller.prototype, "contentOffset", void 0); ], Scroller.prototype, "contentOffset", void 0);
__decorate$7([
Property,
__metadata$7("design:type", Function)
], Scroller.prototype, "onScroll", void 0);
__decorate$7([
Property,
__metadata$7("design:type", Function)
], Scroller.prototype, "onScrollEnd", void 0);
var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) { var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@ -3775,6 +3783,9 @@ class ViewModel {
getState() { getState() {
return this.state; return this.state;
} }
getViewHolder() {
return this.viewHolder;
}
updateState(setter) { updateState(setter) {
setter(this.state); setter(this.state);
this.onBind(this.state, this.viewHolder); this.onBind(this.state, this.viewHolder);

File diff suppressed because one or more lines are too long