private Boolean updateMarkers(ReadableArray markerArray) { try { // First clear all markers from the map for (Marker marker : mapMarkers) { marker.remove(); } mapMarkers.clear(); markerLookup.clear(); // All markers to map for (int i = 0; i < markerArray.size(); i++) { ReadableMap markerJson = markerArray.getMap(i); if (markerJson.hasKey("coordinates")) { Marker marker = map.addMarker(createMarker(markerJson)); if (markerJson.hasKey("id")) { // As we have to lookup it either way, switch it around markerLookup.put(marker.getId(), markerJson.getString("id")); markerLookup.put(markerJson.getString("id"), marker.getId().replace("m", "")); } mapMarkers.add(marker); } else break; } return true; } catch (Exception e) { e.printStackTrace(); return false; } }
@Override public void receiveCommand(ReactViewGroup root, int commandId, @Nullable ReadableArray args) { switch (commandId) { case CMD_HOTSPOT_UPDATE: { if (args == null || args.size() != 2) { throw new JSApplicationIllegalArgumentException( "Illegal number of arguments for 'updateHotspot' command"); } if (Build.VERSION.SDK_INT >= 21) { root.getLocationOnScreen(sLocationBuf); float x = PixelUtil.toPixelFromDIP(args.getDouble(0)) - sLocationBuf[0]; float y = PixelUtil.toPixelFromDIP(args.getDouble(1)) - sLocationBuf[1]; root.drawableHotspotChanged(x, y); } break; } case CMD_SET_PRESSED: { if (args == null || args.size() != 1) { throw new JSApplicationIllegalArgumentException( "Illegal number of arguments for 'setPressed' command"); } root.setPressed(args.getBoolean(0)); break; } } }
@ReactProp(name = "colors") public void setColors(ReactSwipeRefreshLayout view, @Nullable ReadableArray colors) { if (colors != null) { int[] colorValues = new int[colors.size()]; for (int i = 0; i < colors.size(); i++) { colorValues[i] = colors.getInt(i); } view.setColorSchemeColors(colorValues); } else { view.setColorSchemeColors(); } }
private MarkerOptions createMarker(ReadableMap markerJson) { MarkerOptions options = new MarkerOptions(); options.position( new LatLng( markerJson.getMap("coordinates").getDouble("lat"), markerJson.getMap("coordinates").getDouble("lng"))); if (markerJson.hasKey("title")) { options.title(markerJson.getString("title")); } if (markerJson.hasKey("color")) { options.icon(BitmapDescriptorFactory.defaultMarker((float) markerJson.getDouble("color"))); } if (markerJson.hasKey("snippet")) { options.snippet(markerJson.getString("snippet")); } if (markerJson.hasKey("icon")) { String varName = ""; ReadableType iconType = markerJson.getType("icon"); if (iconType.compareTo(ReadableType.Map) >= 0) { ReadableMap icon = markerJson.getMap("icon"); try { int resId = getResourceDrawableId(icon.getString("uri")); Bitmap image = BitmapFactory.decodeResource(reactContext.getResources(), resId); options.icon( BitmapDescriptorFactory.fromBitmap( Bitmap.createScaledBitmap( image, icon.getInt("width"), icon.getInt("height"), true))); } catch (Exception e) { varName = icon.getString("uri"); } } else if (iconType.compareTo(ReadableType.String) >= 0) { varName = markerJson.getString("icon"); } if (!varName.equals("")) { // Changing marker icon to use resource int resourceValue = getResourceDrawableId(varName); Log.i(REACT_CLASS, varName + markerJson.toString()); options.icon(BitmapDescriptorFactory.fromResource(resourceValue)); } } if (markerJson.hasKey("anchor")) { ReadableArray anchor = markerJson.getArray("anchor"); options.anchor((float) anchor.getDouble(0), (float) anchor.getDouble(1)); } return options; }
/** * Show a {@link PopupMenu}. * * @param reactTag the tag of the anchor view (the PopupMenu is displayed next to this view); this * needs to be the tag of a native view (shadow views can not be anchors) * @param items the menu items as an array of strings * @param success will be called with the position of the selected item as the first argument, or * no arguments if the menu is dismissed */ public void showPopupMenu(int reactTag, ReadableArray items, Callback success) { UiThreadUtil.assertOnUiThread(); View anchor = mTagsToViews.get(reactTag); if (anchor == null) { throw new JSApplicationIllegalArgumentException("Could not find view with tag " + reactTag); } PopupMenu popupMenu = new PopupMenu(getReactContextForView(reactTag), anchor); Menu menu = popupMenu.getMenu(); for (int i = 0; i < items.size(); i++) { menu.add(Menu.NONE, Menu.NONE, i, items.getString(i)); } PopupMenuCallbackHandler handler = new PopupMenuCallbackHandler(success); popupMenu.setOnMenuItemClickListener(handler); popupMenu.setOnDismissListener(handler); popupMenu.show(); }
public ShowOptions(@Nullable ReadableMap options) { if (options == null) { return; } if (options.hasKey(CLOSABLE_KEY)) { closable = options.getBoolean(CLOSABLE_KEY); Log.d(TAG, CLOSABLE_KEY + closable); } if (options.hasKey(USE_MAGIC_LINK_KEY)) { useMagicLink = options.getBoolean(USE_MAGIC_LINK_KEY); Log.d(TAG, USE_MAGIC_LINK_KEY + useMagicLink); } if (options.hasKey(AUTH_PARAMS_KEY)) { ReadableMap reactMap = options.getMap(AUTH_PARAMS_KEY); authParams = OptionsHelper.convertReadableMapToMap(reactMap); Log.d(TAG, AUTH_PARAMS_KEY + authParams); } if (options.hasKey(CONNECTIONS_KEY)) { ReadableArray connections = options.getArray(CONNECTIONS_KEY); List<String> list = new ArrayList<>(connections.size()); for (int i = 0; i < connections.size(); i++) { String connectionName = connections.getString(i); switch (connectionName) { case LockReactModule.CONNECTION_EMAIL: connectionType = LockReactModule.CONNECTION_EMAIL; break; case LockReactModule.CONNECTION_SMS: connectionType = LockReactModule.CONNECTION_SMS; break; } list.add(connectionName); } this.connections = new String[list.size()]; this.connections = list.toArray(this.connections); Log.d(TAG, CONNECTIONS_KEY + list); } }
public void updateDataSetOptions(DataSetClass dataSet, ReadableMap map) { if (map.hasKey("values")) { ReadableArray valueArray = map.getArray("values"); for (int j = 0; j < valueArray.size(); j++) { Entry entry; try { entry = entryConstructor.newInstance((float) valueArray.getDouble(j), j); } catch (Exception e) { throw new Error("Entry failed to instantiate"); } dataSet.addEntry(entry); } } if (map.hasKey("colors")) { ReadableArray colorsArray = map.getArray("colors"); ArrayList<Integer> colors = new ArrayList<>(); for (int c = 0; c < colorsArray.size(); c++) { colors.add(Color.parseColor(colorsArray.getString(c))); } dataSet.setColors(colors); } if (map.hasKey("drawValues")) { dataSet.setDrawValues(map.getBoolean("drawValues")); } // TODO: add other properties to dataSet here }
@ReactProp(name = "data") public void setData(ChartClass chart, ReadableMap map) { ChartData chartData; try { chartData = chartDataConstructor.newInstance(); } catch (Exception e) { throw new RuntimeException("ChartData failed to instantiate"); } if (map.hasKey("xValues")) { ReadableArray xValuesArray = map.getArray("xValues"); for (int k = 0; k < xValuesArray.size(); k++) { chartData.addXValue(xValuesArray.getString(k)); } } if (map.hasKey("dataSets")) { ReadableArray dataSetsArray = map.getArray("dataSets"); for (int i = 0; i < dataSetsArray.size(); i++) { ReadableMap dataSetMap = dataSetsArray.getMap(i); DataSetClass dataSet; try { dataSet = (DataSetClass) this.dataSetConstructor.newInstance(new ArrayList<>(), "Data Set " + i); } catch (Exception e) { throw new RuntimeException("DataSet failed to instantiate"); } updateDataSetOptions(dataSet, dataSetMap); chartData.addDataSet(dataSet); } chart.notifyDataSetChanged(); } // TODO: add other properties to data here chart.setData(chartData); chart.invalidate(); }
/** * Invoked when there is a mutation in a node tree. * * @param tag react tag of the node we want to manage * @param indicesToRemove ordered (asc) list of indicies at which view should be removed * @param viewsToAdd ordered (asc based on mIndex property) list of tag-index pairs that represent * a view which should be added at the specified index * @param tagsToDelete list of tags corresponding to views that should be removed */ public void manageChildren( int viewTag, @Nullable ReadableArray moveFrom, @Nullable ReadableArray moveTo, @Nullable ReadableArray addChildTags, @Nullable ReadableArray addAtIndices, @Nullable ReadableArray removeFrom) { ReactShadowNode cssNodeToManage = mShadowNodeRegistry.getNode(viewTag); int numToMove = moveFrom == null ? 0 : moveFrom.size(); int numToAdd = addChildTags == null ? 0 : addChildTags.size(); int numToRemove = removeFrom == null ? 0 : removeFrom.size(); if (numToMove != 0 && (moveTo == null || numToMove != moveTo.size())) { throw new IllegalViewOperationException("Size of moveFrom != size of moveTo!"); } if (numToAdd != 0 && (addAtIndices == null || numToAdd != addAtIndices.size())) { throw new IllegalViewOperationException("Size of addChildTags != size of addAtIndices!"); } // We treat moves as an add and a delete ViewAtIndex[] viewsToAdd = new ViewAtIndex[numToMove + numToAdd]; int[] indicesToRemove = new int[numToMove + numToRemove]; int[] tagsToRemove = new int[indicesToRemove.length]; int[] tagsToDelete = new int[numToRemove]; if (numToMove > 0) { Assertions.assertNotNull(moveFrom); Assertions.assertNotNull(moveTo); for (int i = 0; i < numToMove; i++) { int moveFromIndex = moveFrom.getInt(i); int tagToMove = cssNodeToManage.getChildAt(moveFromIndex).getReactTag(); viewsToAdd[i] = new ViewAtIndex(tagToMove, moveTo.getInt(i)); indicesToRemove[i] = moveFromIndex; tagsToRemove[i] = tagToMove; } } if (numToAdd > 0) { Assertions.assertNotNull(addChildTags); Assertions.assertNotNull(addAtIndices); for (int i = 0; i < numToAdd; i++) { int viewTagToAdd = addChildTags.getInt(i); int indexToAddAt = addAtIndices.getInt(i); viewsToAdd[numToMove + i] = new ViewAtIndex(viewTagToAdd, indexToAddAt); } } if (numToRemove > 0) { Assertions.assertNotNull(removeFrom); for (int i = 0; i < numToRemove; i++) { int indexToRemove = removeFrom.getInt(i); int tagToRemove = cssNodeToManage.getChildAt(indexToRemove).getReactTag(); indicesToRemove[numToMove + i] = indexToRemove; tagsToRemove[numToMove + i] = tagToRemove; tagsToDelete[i] = tagToRemove; } } // NB: moveFrom and removeFrom are both relative to the starting state of the View's children. // moveTo and addAt are both relative to the final state of the View's children. // // 1) Sort the views to add and indices to remove by index // 2) Iterate the indices being removed from high to low and remove them. Going high to low // makes sure we remove the correct index when there are multiple to remove. // 3) Iterate the views being added by index low to high and add them. Like the view removal, // iteration direction is important to preserve the correct index. Arrays.sort(viewsToAdd, ViewAtIndex.COMPARATOR); Arrays.sort(indicesToRemove); // Apply changes to CSSNode hierarchy int lastIndexRemoved = -1; for (int i = indicesToRemove.length - 1; i >= 0; i--) { int indexToRemove = indicesToRemove[i]; if (indexToRemove == lastIndexRemoved) { throw new IllegalViewOperationException( "Repeated indices in Removal list for view tag: " + viewTag); } cssNodeToManage.removeChildAt(indicesToRemove[i]); lastIndexRemoved = indicesToRemove[i]; } for (int i = 0; i < viewsToAdd.length; i++) { ViewAtIndex viewAtIndex = viewsToAdd[i]; ReactShadowNode cssNodeToAdd = mShadowNodeRegistry.getNode(viewAtIndex.mTag); if (cssNodeToAdd == null) { throw new IllegalViewOperationException( "Trying to add unknown view tag: " + viewAtIndex.mTag); } cssNodeToManage.addChildAt(cssNodeToAdd, viewAtIndex.mIndex); } if (!cssNodeToManage.isVirtual() && !cssNodeToManage.isVirtualAnchor()) { mNativeViewHierarchyOptimizer.handleManageChildren( cssNodeToManage, indicesToRemove, tagsToRemove, viewsToAdd, tagsToDelete); } for (int i = 0; i < tagsToDelete.length; i++) { removeShadowNode(mShadowNodeRegistry.getNode(tagsToDelete[i])); } }