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.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
import pub.doric.DoricScrollChangeListener;
|
||||
import pub.doric.IDoricScrollable;
|
||||
import pub.doric.async.AsyncResult;
|
||||
import pub.doric.extension.bridge.DoricMethod;
|
||||
import pub.doric.extension.bridge.DoricPlugin;
|
||||
import pub.doric.utils.DoricJSDispatcher;
|
||||
import pub.doric.utils.DoricUtils;
|
||||
import pub.doric.widget.HVScrollView;
|
||||
|
||||
@ -45,6 +48,7 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
|
||||
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
||||
private String onScrollFuncId;
|
||||
private String onScrollEndFuncId;
|
||||
private DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
|
||||
|
||||
|
||||
public ScrollerNode(DoricContext doricContext) {
|
||||
@ -69,15 +73,22 @@ public class ScrollerNode extends SuperNode<HVScrollView> implements IDoricScrol
|
||||
hvScrollView.setOnScrollChangeListener(new HVScrollView.OnScrollChangeListener() {
|
||||
|
||||
@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) {
|
||||
listener.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());
|
||||
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("y", DoricUtils.px2dp(scrollY))
|
||||
.toJSONObject());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,13 +30,16 @@ import com.github.pengfeizhou.jscore.JSValue;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
import pub.doric.DoricScrollChangeListener;
|
||||
import pub.doric.IDoricScrollable;
|
||||
import pub.doric.async.AsyncResult;
|
||||
import pub.doric.extension.bridge.DoricPlugin;
|
||||
import pub.doric.shader.SuperNode;
|
||||
import pub.doric.shader.ViewNode;
|
||||
import pub.doric.utils.DoricJSDispatcher;
|
||||
import pub.doric.utils.DoricUtils;
|
||||
|
||||
/**
|
||||
@ -84,6 +87,7 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
|
||||
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
||||
private String onScrollFuncId;
|
||||
private String onScrollEndFuncId;
|
||||
private DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
|
||||
|
||||
public FlowLayoutNode(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
@ -247,16 +251,21 @@ public class FlowLayoutNode extends SuperNode<RecyclerView> implements IDoricScr
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
int offsetX = recyclerView.computeHorizontalScrollOffset();
|
||||
int offsetY = recyclerView.computeVerticalScrollOffset();
|
||||
final int offsetX = recyclerView.computeHorizontalScrollOffset();
|
||||
final int offsetY = recyclerView.computeVerticalScrollOffset();
|
||||
for (DoricScrollChangeListener listener : listeners) {
|
||||
listener.onScrollChange(recyclerView, offsetX, offsetY, offsetX - dx, offsetY - dy);
|
||||
}
|
||||
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
||||
callJSResponse(onScrollFuncId, new JSONBuilder()
|
||||
.put("x", DoricUtils.px2dp(offsetX))
|
||||
.put("y", DoricUtils.px2dp(offsetY))
|
||||
.toJSONObject());
|
||||
jsDispatcher.dispatch(new Callable<AsyncResult>() {
|
||||
@Override
|
||||
public AsyncResult call() throws Exception {
|
||||
return callJSResponse(onScrollFuncId, new JSONBuilder()
|
||||
.put("x", DoricUtils.px2dp(offsetX))
|
||||
.put("y", DoricUtils.px2dp(offsetY))
|
||||
.toJSONObject());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,13 +30,16 @@ import com.github.pengfeizhou.jscore.JSValue;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
import pub.doric.DoricScrollChangeListener;
|
||||
import pub.doric.IDoricScrollable;
|
||||
import pub.doric.async.AsyncResult;
|
||||
import pub.doric.extension.bridge.DoricPlugin;
|
||||
import pub.doric.shader.SuperNode;
|
||||
import pub.doric.shader.ViewNode;
|
||||
import pub.doric.utils.DoricJSDispatcher;
|
||||
import pub.doric.utils.DoricUtils;
|
||||
|
||||
/**
|
||||
@ -57,6 +60,7 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
|
||||
private Set<DoricScrollChangeListener> listeners = new HashSet<>();
|
||||
private String onScrollFuncId;
|
||||
private String onScrollEndFuncId;
|
||||
private DoricJSDispatcher jsDispatcher = new DoricJSDispatcher();
|
||||
|
||||
public ListNode(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
@ -87,16 +91,21 @@ public class ListNode extends SuperNode<RecyclerView> implements IDoricScrollabl
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
||||
super.onScrolled(recyclerView, dx, dy);
|
||||
int offsetX = recyclerView.computeHorizontalScrollOffset();
|
||||
int offsetY = recyclerView.computeVerticalScrollOffset();
|
||||
final int offsetX = recyclerView.computeHorizontalScrollOffset();
|
||||
final int offsetY = recyclerView.computeVerticalScrollOffset();
|
||||
for (DoricScrollChangeListener listener : listeners) {
|
||||
listener.onScrollChange(recyclerView, offsetX, offsetY, offsetX - dx, offsetY - dy);
|
||||
}
|
||||
if (!TextUtils.isEmpty(onScrollFuncId)) {
|
||||
callJSResponse(onScrollFuncId, new JSONBuilder()
|
||||
.put("x", DoricUtils.px2dp(offsetX))
|
||||
.put("y", DoricUtils.px2dp(offsetY))
|
||||
.toJSONObject());
|
||||
jsDispatcher.dispatch(new Callable<AsyncResult>() {
|
||||
@Override
|
||||
public AsyncResult call() throws Exception {
|
||||
return callJSResponse(onScrollFuncId, new JSONBuilder()
|
||||
.put("x", DoricUtils.px2dp(offsetX))
|
||||
.put("y", DoricUtils.px2dp(offsetY))
|
||||
.toJSONObject());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
self.blocks = [@[block] mutableCopy];
|
||||
} else {
|
||||
while (self.blocks.count > 0) {
|
||||
[self.blocks removeLastObject];
|
||||
if (self.blocks.count > 0) {
|
||||
[self.blocks removeAllObjects];
|
||||
}
|
||||
[self.blocks insertObject:block atIndex:0];
|
||||
}
|
||||
|
Reference in New Issue
Block a user