From 23a39f20fc6855d5b84dc0638ed1032583a7b7b6 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Tue, 8 Jun 2021 16:52:39 +0800 Subject: [PATCH] android:fix list item set action cannot respond to click --- .../pub/doric/shader/list/ListAdapter.java | 35 +++++++++++++++++++ .../pub/doric/shader/list/ListItemNode.java | 24 ------------- .../java/pub/doric/shader/list/ListNode.java | 27 +++++++++++++- doric-demo/src/ListDemo.ts | 31 ++++++++-------- 4 files changed, 78 insertions(+), 39 deletions(-) diff --git a/doric-android/doric/src/main/java/pub/doric/shader/list/ListAdapter.java b/doric-android/doric/src/main/java/pub/doric/shader/list/ListAdapter.java index 04d06946..a6448275 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/list/ListAdapter.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/list/ListAdapter.java @@ -15,6 +15,8 @@ */ package pub.doric.shader.list; +import android.app.AlertDialog; +import android.content.DialogInterface; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; @@ -150,6 +152,39 @@ class ListAdapter extends RecyclerView.Adapter { } } + public void onItemLongClick(int position, View childView) { + JSValue jsValue = getItemModel(position); + if (jsValue != null && jsValue.isObject()) { + JSObject jsObject = jsValue.asObject(); + String id = jsObject.getProperty("id").asString().value(); + final ViewNode itemNode = this.listNode.getSubNodeById(id); + JSObject props = jsObject.getProperty("props").asObject(); + JSValue prop = props.getProperty("actions"); + if (itemNode != null && prop.isArray()) { + JSArray actions = prop.asArray(); + if (actions != null && actions.size() > 0) { + String[] items = new String[actions.size()]; + final String[] callbacks = new String[actions.size()]; + for (int i = 0; i < actions.size(); i++) { + JSObject action = actions.get(i).asObject(); + String title = action.getProperty("title").asString().value(); + String callback = action.getProperty("callback").asString().value(); + items[i] = title; + callbacks[i] = callback; + } + new AlertDialog.Builder(childView.getContext()) + .setItems(items, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + itemNode.callJSResponse(callbacks[which]); + dialog.dismiss(); + } + }).show(); + } + } + } + } + static class DoricViewHolder extends RecyclerView.ViewHolder { ListItemNode listItemNode; diff --git a/doric-android/doric/src/main/java/pub/doric/shader/list/ListItemNode.java b/doric-android/doric/src/main/java/pub/doric/shader/list/ListItemNode.java index c358300f..941d94fc 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/list/ListItemNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/list/ListItemNode.java @@ -26,9 +26,7 @@ import com.github.pengfeizhou.jscore.JSValue; import pub.doric.DoricContext; import pub.doric.extension.bridge.DoricPlugin; -import pub.doric.shader.GroupNode; import pub.doric.shader.StackNode; -import pub.doric.shader.ViewNode; /** * @Description: com.github.penfeizhou.doric.widget @@ -48,9 +46,6 @@ public class ListItemNode extends StackNode { @Override protected void blend(FrameLayout view, String name, JSValue prop) { if ("actions".equals(name)) { - if (prop.isArray()) { - this.actions = prop.asArray(); - } } else if ("identifier".equals(name)) { this.identifier = prop.asString().value(); } else { @@ -90,25 +85,6 @@ public class ListItemNode extends StackNode { return true; } }); - - recursiveHandleLongClick(this); - } - } - - private void recursiveHandleLongClick(GroupNode groupNode) { - for (int i = 0; i != groupNode.getChildNodes().size(); i++) { - ViewNode node = (ViewNode) groupNode.getChildNodes().get(i); - node.getView().setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - getView().performLongClick(); - return false; - } - }); - - if (node instanceof GroupNode) { - recursiveHandleLongClick((GroupNode) node); - } } } } diff --git a/doric-android/doric/src/main/java/pub/doric/shader/list/ListNode.java b/doric-android/doric/src/main/java/pub/doric/shader/list/ListNode.java index 3ad4f96b..86e6daeb 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/list/ListNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/list/ListNode.java @@ -17,6 +17,8 @@ package pub.doric.shader.list; import android.text.TextUtils; import android.util.SparseArray; +import android.view.GestureDetector; +import android.view.MotionEvent; import android.view.View; import androidx.annotation.NonNull; @@ -87,7 +89,7 @@ public class ListNode extends SuperNode implements IDoricScrollabl @Override protected RecyclerView build() { - RecyclerView recyclerView = new RecyclerView(getContext()); + final RecyclerView recyclerView = new RecyclerView(getContext()); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()) { @Override public boolean canScrollVertically() { @@ -136,6 +138,29 @@ public class ListNode extends SuperNode implements IDoricScrollabl } } }); + final GestureDetector gestureDetector = new GestureDetector( + getContext(), + new GestureDetector.SimpleOnGestureListener() { + @Override + public void onLongPress(MotionEvent e) { + super.onLongPress(e); + View childView = recyclerView.findChildViewUnder(e.getX(), e.getY()); + if (childView != null) { + int position = recyclerView.getChildLayoutPosition(childView); + listAdapter.onItemLongClick(position, childView); + } + } + }); + + recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() { + @Override + public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { + if (gestureDetector.onTouchEvent(e)) { + return true; + } + return false; + } + }); return recyclerView; } diff --git a/doric-demo/src/ListDemo.ts b/doric-demo/src/ListDemo.ts index cd3e3d33..969a5132 100644 --- a/doric-demo/src/ListDemo.ts +++ b/doric-demo/src/ListDemo.ts @@ -1,4 +1,4 @@ -import { Group, Panel, List, text, gravity, Color, LayoutSpec, list, listItem, log, vlayout, Gravity, hlayout, Text, refreshable, Refreshable, ListItem, layoutConfig, ViewHolder, ViewModel, VMPanel, loge, modal } from "doric"; +import { Group, Panel, List, text, gravity, Color, LayoutSpec, list, listItem, log, vlayout, Gravity, hlayout, Text, refreshable, Refreshable, ListItem, layoutConfig, ViewHolder, ViewModel, VMPanel, loge, modal, stack } from "doric"; interface ItemModel { text: string @@ -67,34 +67,37 @@ class ListVM extends ViewModel { vh.list.apply({ renderItem: (index) => { const data = state.data[index] - return listItem(text({ - text: data.text, - textSize: 20, - layoutConfig: { - widthSpec: LayoutSpec.MOST, - heightSpec: LayoutSpec.JUST, - }, - height: 50, - onClick: () => {modal(context).alert(data.text)} - }), { + return listItem(stack([ + text({ + text: data.text, + textSize: 20, + layoutConfig: { + widthSpec: LayoutSpec.FIT, + heightSpec: LayoutSpec.JUST, + }, + height: 50, + onClick: () => { modal(context).alert(data.text) } + }) + ]), { layoutConfig: { widthSpec: LayoutSpec.MOST, heightSpec: LayoutSpec.FIT, - } + }, + //onClick: () => { modal(context).alert("Item Clicked " + index) } }).apply({ actions: [ { title: "First", backgroundColor: Color.RED, callback: () => { - modal(context).alert("First action") + modal(context).alert("First action " + index) } }, { title: "Second", backgroundColor: Color.BLUE, callback: () => { - modal(context).alert("Second action") + modal(context).alert("Second action " + index) } } ]