android:add JSDispatcher to optimize scrollchange callback
This commit is contained in:
parent
2b7ff95de6
commit
139a8775d4
@ -24,12 +24,15 @@ import com.github.pengfeizhou.jscore.JSValue;
|
|||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import pub.doric.DoricContext;
|
import pub.doric.DoricContext;
|
||||||
import pub.doric.DoricScrollChangeListener;
|
import pub.doric.DoricScrollChangeListener;
|
||||||
import pub.doric.IDoricScrollable;
|
import pub.doric.IDoricScrollable;
|
||||||
|
import pub.doric.async.AsyncResult;
|
||||||
import pub.doric.extension.bridge.DoricMethod;
|
import pub.doric.extension.bridge.DoricMethod;
|
||||||
import pub.doric.extension.bridge.DoricPlugin;
|
import pub.doric.extension.bridge.DoricPlugin;
|
||||||
|
import pub.doric.utils.DoricJSDispatcher;
|
||||||
import pub.doric.utils.DoricUtils;
|
import pub.doric.utils.DoricUtils;
|
||||||
import pub.doric.widget.HVScrollView;
|
import pub.doric.widget.HVScrollView;
|
||||||
|
|
||||||
@ -45,6 +48,7 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
|
|||||||
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
||||||
private String onScrollFuncId;
|
private String onScrollFuncId;
|
||||||
private String onScrollEndFuncId;
|
private String onScrollEndFuncId;
|
||||||
|
private DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
|
||||||
|
|
||||||
|
|
||||||
public ScrollerNode(DoricContext doricContext) {
|
public ScrollerNode(DoricContext doricContext) {
|
||||||
@ -69,16 +73,23 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
|
|||||||
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, final int scrollX, final int scrollY, int oldScrollX, int oldScrollY) {
|
||||||
for (DoricScrollChangeListener listener : listeners) {
|
for (DoricScrollChangeListener listener : listeners) {
|
||||||
listener.onScrollChange(v, scrollX, scrollY, oldScrollX, oldScrollY);
|
listener.onScrollChange(v, scrollX, scrollY, oldScrollX, oldScrollY);
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
||||||
callJSResponse(onScrollFuncId, new JSONBuilder()
|
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
||||||
|
jsDispatcher.dispatch(new Callable<AsyncResult>() {
|
||||||
|
@Override
|
||||||
|
public AsyncResult call() throws Exception {
|
||||||
|
return callJSResponse(onScrollFuncId, new JSONBuilder()
|
||||||
.put("x", DoricUtils.px2dp(scrollX))
|
.put("x", DoricUtils.px2dp(scrollX))
|
||||||
.put("y", DoricUtils.px2dp(scrollY))
|
.put("y", DoricUtils.px2dp(scrollY))
|
||||||
.toJSONObject());
|
.toJSONObject());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,13 +30,16 @@ import com.github.pengfeizhou.jscore.JSValue;
|
|||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import pub.doric.DoricContext;
|
import pub.doric.DoricContext;
|
||||||
import pub.doric.DoricScrollChangeListener;
|
import pub.doric.DoricScrollChangeListener;
|
||||||
import pub.doric.IDoricScrollable;
|
import pub.doric.IDoricScrollable;
|
||||||
|
import pub.doric.async.AsyncResult;
|
||||||
import pub.doric.extension.bridge.DoricPlugin;
|
import pub.doric.extension.bridge.DoricPlugin;
|
||||||
import pub.doric.shader.SuperNode;
|
import pub.doric.shader.SuperNode;
|
||||||
import pub.doric.shader.ViewNode;
|
import pub.doric.shader.ViewNode;
|
||||||
|
import pub.doric.utils.DoricJSDispatcher;
|
||||||
import pub.doric.utils.DoricUtils;
|
import pub.doric.utils.DoricUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,6 +87,7 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
|
|||||||
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
||||||
private String onScrollFuncId;
|
private String onScrollFuncId;
|
||||||
private String onScrollEndFuncId;
|
private String onScrollEndFuncId;
|
||||||
|
private DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
|
||||||
|
|
||||||
public FlowLayoutNode(DoricContext doricContext) {
|
public FlowLayoutNode(DoricContext doricContext) {
|
||||||
super(doricContext);
|
super(doricContext);
|
||||||
@ -247,17 +251,22 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
|
|||||||
@Override
|
@Override
|
||||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
super.onScrolled(recyclerView, dx, dy);
|
||||||
int offsetX = recyclerView.computeHorizontalScrollOffset();
|
final int offsetX = recyclerView.computeHorizontalScrollOffset();
|
||||||
int offsetY = recyclerView.computeVerticalScrollOffset();
|
final int offsetY = recyclerView.computeVerticalScrollOffset();
|
||||||
for (DoricScrollChangeListener listener : listeners) {
|
for (DoricScrollChangeListener listener : listeners) {
|
||||||
listener.onScrollChange(recyclerView, offsetX, offsetY, offsetX - dx, offsetY - dy);
|
listener.onScrollChange(recyclerView, offsetX, offsetY, offsetX - dx, offsetY - dy);
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
||||||
callJSResponse(onScrollFuncId, new JSONBuilder()
|
jsDispatcher.dispatch(new Callable<AsyncResult>() {
|
||||||
|
@Override
|
||||||
|
public AsyncResult call() throws Exception {
|
||||||
|
return callJSResponse(onScrollFuncId, new JSONBuilder()
|
||||||
.put("x", DoricUtils.px2dp(offsetX))
|
.put("x", DoricUtils.px2dp(offsetX))
|
||||||
.put("y", DoricUtils.px2dp(offsetY))
|
.put("y", DoricUtils.px2dp(offsetY))
|
||||||
.toJSONObject());
|
.toJSONObject());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,13 +30,16 @@ import com.github.pengfeizhou.jscore.JSValue;
|
|||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import pub.doric.DoricContext;
|
import pub.doric.DoricContext;
|
||||||
import pub.doric.DoricScrollChangeListener;
|
import pub.doric.DoricScrollChangeListener;
|
||||||
import pub.doric.IDoricScrollable;
|
import pub.doric.IDoricScrollable;
|
||||||
|
import pub.doric.async.AsyncResult;
|
||||||
import pub.doric.extension.bridge.DoricPlugin;
|
import pub.doric.extension.bridge.DoricPlugin;
|
||||||
import pub.doric.shader.SuperNode;
|
import pub.doric.shader.SuperNode;
|
||||||
import pub.doric.shader.ViewNode;
|
import pub.doric.shader.ViewNode;
|
||||||
|
import pub.doric.utils.DoricJSDispatcher;
|
||||||
import pub.doric.utils.DoricUtils;
|
import pub.doric.utils.DoricUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,6 +60,7 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
|
|||||||
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
||||||
private String onScrollFuncId;
|
private String onScrollFuncId;
|
||||||
private String onScrollEndFuncId;
|
private String onScrollEndFuncId;
|
||||||
|
private DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
|
||||||
|
|
||||||
public ListNode(DoricContext doricContext) {
|
public ListNode(DoricContext doricContext) {
|
||||||
super(doricContext);
|
super(doricContext);
|
||||||
@ -87,17 +91,22 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
|
|||||||
@Override
|
@Override
|
||||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
super.onScrolled(recyclerView, dx, dy);
|
||||||
int offsetX = recyclerView.computeHorizontalScrollOffset();
|
final int offsetX = recyclerView.computeHorizontalScrollOffset();
|
||||||
int offsetY = recyclerView.computeVerticalScrollOffset();
|
final int offsetY = recyclerView.computeVerticalScrollOffset();
|
||||||
for (DoricScrollChangeListener listener : listeners) {
|
for (DoricScrollChangeListener listener : listeners) {
|
||||||
listener.onScrollChange(recyclerView, offsetX, offsetY, offsetX - dx, offsetY - dy);
|
listener.onScrollChange(recyclerView, offsetX, offsetY, offsetX - dx, offsetY - dy);
|
||||||
}
|
}
|
||||||
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
||||||
callJSResponse(onScrollFuncId, new JSONBuilder()
|
jsDispatcher.dispatch(new Callable<AsyncResult>() {
|
||||||
|
@Override
|
||||||
|
public AsyncResult call() throws Exception {
|
||||||
|
return callJSResponse(onScrollFuncId, new JSONBuilder()
|
||||||
.put("x", DoricUtils.px2dp(offsetX))
|
.put("x", DoricUtils.px2dp(offsetX))
|
||||||
.put("y", DoricUtils.px2dp(offsetY))
|
.put("y", DoricUtils.px2dp(offsetY))
|
||||||
.toJSONObject());
|
.toJSONObject());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2019] [Doric.Pub]
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package pub.doric.utils;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import pub.doric.async.AsyncResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: pub.doric.utils
|
||||||
|
* @Author: pengfei.zhou
|
||||||
|
* @CreateDate: 2020-03-25
|
||||||
|
*/
|
||||||
|
public class DoricJSDispatcher implements AsyncResult.Callback {
|
||||||
|
private LinkedList<Callable<AsyncResult>> blocks = new LinkedList<>();
|
||||||
|
private boolean consuming = false;
|
||||||
|
private Handler mHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
public void dispatch(Callable<AsyncResult> block) {
|
||||||
|
if (blocks.size() > 0) {
|
||||||
|
blocks.clear();
|
||||||
|
}
|
||||||
|
blocks.push(block);
|
||||||
|
if (!consuming) {
|
||||||
|
consume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void consume() {
|
||||||
|
Callable<AsyncResult> block = blocks.pollLast();
|
||||||
|
if (block != null) {
|
||||||
|
consuming = true;
|
||||||
|
try {
|
||||||
|
AsyncResult result = block.call();
|
||||||
|
result.setCallback(this);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
consume();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
consuming = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(Object result) {
|
||||||
|
if (Looper.myLooper() == mHandler.getLooper()) {
|
||||||
|
consume();
|
||||||
|
} else {
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
consume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable t) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -29,8 +29,8 @@ - (void)dispatch:(DoricAsyncResult *(^)(void))block {
|
|||||||
if (!self.blocks) {
|
if (!self.blocks) {
|
||||||
self.blocks = [@[block] mutableCopy];
|
self.blocks = [@[block] mutableCopy];
|
||||||
} else {
|
} else {
|
||||||
while (self.blocks.count > 0) {
|
if (self.blocks.count > 0) {
|
||||||
[self.blocks removeLastObject];
|
[self.blocks removeAllObjects];
|
||||||
}
|
}
|
||||||
[self.blocks insertObject:block atIndex:0];
|
[self.blocks insertObject:block atIndex:0];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user