Android: add loop in slider
This commit is contained in:
parent
c44c3e5353
commit
4bb9df4dbb
@ -71,7 +71,11 @@ class SlideAdapter extends RecyclerView.Adapter<SlideAdapter.DoricViewHolder> {
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return itemCount;
|
||||
if (loop) {
|
||||
return itemCount + 2;
|
||||
} else {
|
||||
return itemCount;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -86,11 +90,24 @@ class SlideAdapter extends RecyclerView.Adapter<SlideAdapter.DoricViewHolder> {
|
||||
}
|
||||
|
||||
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<JSDecoder> asyncResult = sliderNode.callJSResponse(
|
||||
"renderBunchedItems",
|
||||
position,
|
||||
index,
|
||||
batchCount);
|
||||
try {
|
||||
JSDecoder jsDecoder = asyncResult.synchronous().get();
|
||||
@ -100,10 +117,10 @@ class SlideAdapter extends RecyclerView.Adapter<SlideAdapter.DoricViewHolder> {
|
||||
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();
|
||||
|
@ -65,12 +65,23 @@ public class SliderNode extends SuperNode<RecyclerView> {
|
||||
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<RecyclerView> {
|
||||
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);
|
||||
|
@ -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,
|
||||
|
Reference in New Issue
Block a user