From 4bb9df4dbb6028d5b4dcfbb4242b157a6e6939d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8A=B2=E9=B9=8F?= Date: Fri, 10 Apr 2020 10:33:15 +0800 Subject: [PATCH] Android: add loop in slider --- .../pub/doric/shader/slider/SlideAdapter.java | 27 ++++++-- .../pub/doric/shader/slider/SliderNode.java | 27 ++++++-- doric-demo/src/SliderDemo.ts | 67 +++++++++++++------ 3 files changed, 91 insertions(+), 30 deletions(-) diff --git a/doric-android/doric/src/main/java/pub/doric/shader/slider/SlideAdapter.java b/doric-android/doric/src/main/java/pub/doric/shader/slider/SlideAdapter.java index 7a4233d3..8d68d8d4 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/slider/SlideAdapter.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/slider/SlideAdapter.java @@ -71,7 +71,11 @@ class SlideAdapter extends RecyclerView.Adapter { @Override public int getItemCount() { - return itemCount; + if (loop) { + return itemCount + 2; + } else { + return itemCount; + } } @Override @@ -86,11 +90,24 @@ class SlideAdapter extends RecyclerView.Adapter { } private JSValue getItemModel(final int position) { - String id = itemValues.get(position); + int index; + if (loop) { + if (position == 0) { + index = itemCount - 1; + } else if (position == itemCount + 1) { + index = 0; + } else { + index = position - 1; + } + } else { + index = position; + } + + String id = itemValues.get(index); if (TextUtils.isEmpty(id)) { AsyncResult asyncResult = sliderNode.callJSResponse( "renderBunchedItems", - position, + index, batchCount); try { JSDecoder jsDecoder = asyncResult.synchronous().get(); @@ -100,10 +117,10 @@ class SlideAdapter extends RecyclerView.Adapter { for (int i = 0; i < jsArray.size(); i++) { JSObject itemModel = jsArray.get(i).asObject(); String itemId = itemModel.getProperty("id").asString().value(); - itemValues.put(i + position, itemId); + itemValues.put(i + index, itemId); sliderNode.setSubModel(itemId, itemModel); } - return sliderNode.getSubModel(itemValues.get(position)); + return sliderNode.getSubModel(itemValues.get(index)); } } catch (Exception e) { e.printStackTrace(); diff --git a/doric-android/doric/src/main/java/pub/doric/shader/slider/SliderNode.java b/doric-android/doric/src/main/java/pub/doric/shader/slider/SliderNode.java index d65cc009..451d3311 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/slider/SliderNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/slider/SliderNode.java @@ -65,12 +65,23 @@ public class SliderNode extends SuperNode { public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { if (newState == RecyclerView.SCROLL_STATE_IDLE) { View view = snapHelper.findSnapView(layoutManager); - if (view != null && !TextUtils.isEmpty(onPageSlidedFuncId)) { + if (view != null) { int position = layoutManager.getPosition(view); - if (position != lastPosition) { - callJSResponse(onPageSlidedFuncId, position); + + if (slideAdapter.loop) { + if (position == 0) { + recyclerView.scrollToPosition(slideAdapter.itemCount); + } else if (position == slideAdapter.itemCount + 1) { + recyclerView.scrollToPosition(1); + } + } + + if (!TextUtils.isEmpty(onPageSlidedFuncId)) { + if (position != lastPosition) { + callJSResponse(onPageSlidedFuncId, position); + } + lastPosition = position; } - lastPosition = position; } } } @@ -154,6 +165,14 @@ public class SliderNode extends SuperNode { case "loop": boolean loop = prop.asBoolean().value(); slideAdapter.loop = loop; + if (loop) { + mView.post(new Runnable() { + @Override + public void run() { + mView.scrollToPosition(1); + } + }); + } break; default: super.blend(view, name, prop); diff --git a/doric-demo/src/SliderDemo.ts b/doric-demo/src/SliderDemo.ts index aa7764f8..912a2560 100644 --- a/doric-demo/src/SliderDemo.ts +++ b/doric-demo/src/SliderDemo.ts @@ -1,4 +1,4 @@ -import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, slider, slideItem, image, layoutConfig, ScaleType } from "doric"; +import { Group, Panel, text, gravity, Gravity, Color, LayoutSpec, vlayout, slider, slideItem, image, layoutConfig, ScaleType, switchView, hlayout } from "doric"; import { colors } from "./utils"; const imageUrls = [ @@ -15,6 +15,27 @@ const imageUrls = [ @Entry class SliderPanel extends Panel { build(rootView: Group): void { + let pager = slider({ + itemCount: imageUrls.length, + renderPage: (idx) => { + return slideItem(image({ + imageUrl: imageUrls[idx % imageUrls.length], + scaleType: ScaleType.ScaleAspectFit, + layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST).configHeight(LayoutSpec.MOST).configAlignment(gravity().center()), + })).also(it => { + let start = idx + it.onClick = () => { + it.backgroundColor = (colors[++start % colors.length]) + } + }) + }, + layoutConfig: { + widthSpec: LayoutSpec.MOST, + heightSpec: LayoutSpec.MOST, + weight: 1, + }, + }) + rootView.addChild(vlayout([ text({ text: "Gallery", @@ -28,27 +49,31 @@ class SliderPanel extends Panel { textAlignment: gravity().center(), height: 50, }), - slider({ - itemCount: 100, - loop: true, - renderPage: (idx) => { - return slideItem(image({ - imageUrl: imageUrls[idx % imageUrls.length], - scaleType: ScaleType.ScaleAspectFit, - layoutConfig: layoutConfig().configWidth(LayoutSpec.MOST).configHeight(LayoutSpec.MOST).configAlignment(gravity().center()), - })).also(it => { - let start = idx - it.onClick = () => { - it.backgroundColor = (colors[++start % colors.length]) - } - }) - }, - layoutConfig: { - widthSpec: LayoutSpec.MOST, - heightSpec: LayoutSpec.MOST, - weight: 1, - }, + hlayout([ + text({ + text: "Loop", + layoutConfig: { + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.JUST, + }, + textSize: 20, + textColor: Color.BLACK, + textAlignment: gravity().center(), + height: 50, + }), + switchView({ + state: false, + onSwitch: (state) => { + pager.loop = state + }, + }), + ], { + layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT), + gravity: gravity().center(), + space: 10, + backgroundColor: Color.RED, }), + pager, ]).also(it => { it.layoutConfig = { widthSpec: LayoutSpec.MOST,