From 00dcb459fbe0b1463140342e2236175c4146eef0 Mon Sep 17 00:00:00 2001 From: xwenliang Date: Wed, 10 Jan 2018 19:28:45 +0800 Subject: [PATCH] new feature pickerTextEllipsisLen and fix IndexOutOfBoundsException for Android --- README.md | 159 +++++++++--------- .../com/beefe/picker/PickerViewModule.java | 43 +++-- .../java/com/beefe/picker/view/LoopView.java | 52 +++++- .../beefe/picker/view/PickerViewAlone.java | 11 ++ .../beefe/picker/view/PickerViewLinkage.java | 31 ++++ example/PickerTest/PickerTest.js | 2 - index.js | 1 + package.json | 2 +- 8 files changed, 195 insertions(+), 106 deletions(-) diff --git a/README.md b/README.md index 62d09feb9..846bffc81 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ |Key | Type | Default| Support | Description | | --- | --- | ---- | ------ | ----------- | |isLoop | Boolean | false | Android | | +|pickerTextEllipsisLen | number | 6 | Android | | |pickerConfirmBtnText | string | confirm | iOS/Android | | |pickerCancelBtnText | string | cancel | iOS/Android | | |pickerTitleText | string | pls select | iOS/Android | | @@ -60,26 +61,26 @@ #### Step 3 - import and use in project ```javascript - import Picker from 'react-native-picker'; - let data = []; - for(var i=0;i<100;i++){ - data.push(i); +import Picker from 'react-native-picker'; +let data = []; +for(var i=0;i<100;i++){ + data.push(i); +} + +Picker.init({ + pickerData: data, + selectedValue: [59], + onPickerConfirm: data => { + console.log(data); + }, + onPickerCancel: data => { + console.log(data); + }, + onPickerSelect: data => { + console.log(data); } - - Picker.init({ - pickerData: data, - selectedValue: [59], - onPickerConfirm: data => { - console.log(data); - }, - onPickerCancel: data => { - console.log(data); - }, - onPickerSelect: data => { - console.log(data); - } - }); - Picker.show(); +}); +Picker.show(); ``` @@ -113,19 +114,19 @@ $ pod install - single wheel: ```javascript - pickerData = [1,2,3,4]; - selectedValue = 3; +pickerData = [1,2,3,4]; +selectedValue = 3; ``` - two or more wheel: ```javascript - pickerData = [ - [1,2,3,4], - [5,6,7,8], - ... - ]; - selectedValue = [1, 5]; +pickerData = [ + [1,2,3,4], + [5,6,7,8], + ... +]; +selectedValue = [1, 5]; ``` #### cascade: @@ -133,63 +134,63 @@ $ pod install - two wheel ```javascript - pickerData = [ - { - a: [1, 2, 3, 4] - }, - { - b: [5, 6, 7, 8] - }, - ... - ]; - selectedValue = ['a', 2]; +pickerData = [ + { + a: [1, 2, 3, 4] + }, + { + b: [5, 6, 7, 8] + }, + ... +]; +selectedValue = ['a', 2]; ``` - three wheel ```javascript - pickerData = [ - { - a: [ - { - a1: [1, 2, 3, 4] - }, - { - a2: [5, 6, 7, 8] - }, - { - a3: [9, 10, 11, 12] - } - ] - }, - { - b: [ - { - b1: [11, 22, 33, 44] - }, - { - b2: [55, 66, 77, 88] - }, - { - b3: [99, 1010, 1111, 1212] - } - ] - }, - { - c: [ - { - c1: ['a', 'b', 'c'] - }, - { - c2: ['aa', 'bb', 'cc'] - }, - { - c3: ['aaa', 'bbb', 'ccc'] - } - ] - }, - ... - ] +pickerData = [ + { + a: [ + { + a1: [1, 2, 3, 4] + }, + { + a2: [5, 6, 7, 8] + }, + { + a3: [9, 10, 11, 12] + } + ] + }, + { + b: [ + { + b1: [11, 22, 33, 44] + }, + { + b2: [55, 66, 77, 88] + }, + { + b3: [99, 1010, 1111, 1212] + } + ] + }, + { + c: [ + { + c1: ['a', 'b', 'c'] + }, + { + c2: ['aa', 'bb', 'cc'] + }, + { + c3: ['aaa', 'bbb', 'ccc'] + } + ] + }, + ... +] ``` ### For pure javascript version -> [v3.0.5](https://github.com/beefe/react-native-picker/tree/pure-javascript-version) diff --git a/android/src/main/java/com/beefe/picker/PickerViewModule.java b/android/src/main/java/com/beefe/picker/PickerViewModule.java index 999f8eade..40f2d8d59 100644 --- a/android/src/main/java/com/beefe/picker/PickerViewModule.java +++ b/android/src/main/java/com/beefe/picker/PickerViewModule.java @@ -101,6 +101,7 @@ public class PickerViewModule extends ReactContextBaseJavaModule implements Life private static final String PICKER_TEXT_COLOR = "pickerFontColor"; private static final String PICKER_TEXT_SIZE = "pickerFontSize"; + private static final String PICKER_TEXT_ELLIPSIS_LEN = "pickerTextEllipsisLen"; private static final String PICKER_EVENT_NAME = "pickerEvent"; private static final String EVENT_KEY_CONFIRM = "confirm"; @@ -116,6 +117,7 @@ public class PickerViewModule extends ReactContextBaseJavaModule implements Life private String confirmText; private String cancelText; private String titleText; + private int pickerTextEllipsisLen; private double[] weights; @@ -239,6 +241,10 @@ public void onClick(View v) { } }); + if(options.hasKey(PICKER_TEXT_ELLIPSIS_LEN)){ + pickerTextEllipsisLen = options.getInt(PICKER_TEXT_ELLIPSIS_LEN); + } + if (options.hasKey(IS_LOOP)) { isLoop = options.getBoolean(IS_LOOP); } @@ -298,6 +304,7 @@ public void onClick(View v) { pickerViewLinkage.setPickerData(pickerData, weights); pickerViewLinkage.setTextColor(pickerTextColor); pickerViewLinkage.setTextSize(pickerTextSize); + pickerViewLinkage.setTextEllipsisLen(pickerTextEllipsisLen); pickerViewLinkage.setIsLoop(isLoop); pickerViewLinkage.setOnSelectListener(new OnSelectedListener() { @@ -317,6 +324,7 @@ public void onSelected(ArrayList selectedList) { pickerViewAlone.setPickerData(pickerData, weights); pickerViewAlone.setTextColor(pickerTextColor); pickerViewAlone.setTextSize(pickerTextSize); + pickerViewAlone.setTextEllipsisLen(pickerTextEllipsisLen); pickerViewAlone.setIsLoop(isLoop); pickerViewAlone.setOnSelectedListener(new OnSelectedListener() { @@ -346,25 +354,26 @@ public void onSelected(ArrayList selectedList) { int height = barViewHeight + pickerViewHeight; if (dialog == null) { dialog = new Dialog(activity, R.style.Dialog_Full_Screen); + dialog.setContentView(view); + WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); + Window window = dialog.getWindow(); + if (window != null) { + if (MIUIUtils.isMIUI()) { + layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION; + }else { + //layoutParams.type = WindowManager.LayoutParams.TYPE_TOAST; + } + layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + layoutParams.format = PixelFormat.TRANSPARENT; + layoutParams.windowAnimations = R.style.PickerAnim; + layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; + layoutParams.height = height; + layoutParams.gravity = Gravity.BOTTOM; + window.setAttributes(layoutParams); + } } else { dialog.dismiss(); - } - dialog.setContentView(view); - WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); - Window window = dialog.getWindow(); - if (window != null) { - if (MIUIUtils.isMIUI()) { - layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION; - }else { - //layoutParams.type = WindowManager.LayoutParams.TYPE_TOAST; - } - layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; - layoutParams.format = PixelFormat.TRANSPARENT; - layoutParams.windowAnimations = R.style.PickerAnim; - layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; - layoutParams.height = height; - layoutParams.gravity = Gravity.BOTTOM; - window.setAttributes(layoutParams); + dialog.setContentView(view); } } } diff --git a/android/src/main/java/com/beefe/picker/view/LoopView.java b/android/src/main/java/com/beefe/picker/view/LoopView.java index 6540f5a33..3c07cc54a 100644 --- a/android/src/main/java/com/beefe/picker/view/LoopView.java +++ b/android/src/main/java/com/beefe/picker/view/LoopView.java @@ -67,6 +67,7 @@ enum ACTION { private String selectedItem; private int selectedIndex; private int preCurrentIndex; + private int textEllipsisLen = 7; // 显示几个条目 @@ -216,6 +217,10 @@ public final void setTextSize(float size) { } } + public final void setTextEllipsisLen(int len){ + textEllipsisLen = len; + } + public boolean hasItem(String item) { int result = items.indexOf(item); return result != -1; @@ -275,6 +280,33 @@ protected final void onItemSelected() { } } + protected final void drawText(Canvas canvas, String text, float posX, float posY, Paint paint) { + StringBuffer stringBuffer = new StringBuffer(); + char[] array = text.toCharArray(); + int sum = 0; + for(int i=0;i= (textEllipsisLen * 2)){ + break; + } + char bt = array[i]; + if(bt > 127 || bt == 94){ + sum += 2; + } + else{ + sum ++; + } + stringBuffer.append(String.valueOf(bt)); + } + String string = ""; + if(array.length != stringBuffer.toString().toCharArray().length){ + string = stringBuffer.toString() + "..."; + } + else{ + string = text; + } + canvas.drawText(string, posX, posY, paint); + } + @Override protected void onDraw(Canvas canvas) { if (items == null) { @@ -346,32 +378,32 @@ protected void onDraw(Canvas canvas) { // 条目经过第一条线 canvas.save(); canvas.clipRect(0, 0, getWidth(), firstLineY - translateY); - canvas.drawText(text, getX(text, paintOuterText), getY(paintOuterText), paintOuterText); + drawText(canvas, text, getX(text, paintOuterText), getY(paintOuterText), paintOuterText); canvas.restore(); canvas.save(); canvas.clipRect(0, firstLineY - translateY, getWidth(), (int) (itemHeight)); - canvas.drawText(text, getX(text, paintCenterText), getY(paintCenterText), paintCenterText); + drawText(canvas, text, getX(text, paintCenterText), getY(paintCenterText), paintCenterText); canvas.restore(); } else if (translateY <= secondLineY && maxTextHeight + translateY >= secondLineY) { // 条目经过第二条线 canvas.save(); canvas.clipRect(0, 0, getWidth(), secondLineY - translateY); - canvas.drawText(text, getX(text, paintCenterText), getY(paintCenterText), paintCenterText); + drawText(canvas, text, getX(text, paintCenterText), getY(paintCenterText), paintCenterText); canvas.restore(); canvas.save(); canvas.clipRect(0, secondLineY - translateY, getWidth(), (int) (itemHeight)); - canvas.drawText(text, getX(text, paintOuterText), getY(paintOuterText), paintOuterText); + drawText(canvas, text, getX(text, paintOuterText), getY(paintOuterText), paintOuterText); canvas.restore(); } else if (translateY >= firstLineY && maxTextHeight + translateY <= secondLineY) { // 中间条目 canvas.clipRect(0, 0, getWidth(), (int) (itemHeight)); - canvas.drawText(text, getX(text, paintCenterText), getY(paintCenterText), paintCenterText); + drawText(canvas, text, getX(text, paintCenterText), getY(paintCenterText), paintCenterText); selectedItem = text; selectedIndex = items.indexOf(text); } else { // 其他条目 canvas.clipRect(0, 0, getWidth(), (int) (itemHeight)); - canvas.drawText(text, getX(text, paintOuterText), getY(paintOuterText), paintOuterText); + drawText(canvas, text, getX(text, paintOuterText), getY(paintOuterText), paintOuterText); } canvas.restore(); } @@ -381,7 +413,13 @@ protected void onDraw(Canvas canvas) { private float getX(String text, Paint paint) { paint.getTextBounds(text, 0, text.length(), tempRect); - return (getWidth() - tempRect.width() * scaleX) / 2; + //return (getWidth() - tempRect.width() * scaleX) / 2; + if((getWidth() - tempRect.width() * scaleX)/2 > 0){ + return (getWidth() - tempRect.width() * scaleX) / 2; + } + else{ + return 0; + } } /** diff --git a/android/src/main/java/com/beefe/picker/view/PickerViewAlone.java b/android/src/main/java/com/beefe/picker/view/PickerViewAlone.java index 74ed494c3..b24e6b176 100644 --- a/android/src/main/java/com/beefe/picker/view/PickerViewAlone.java +++ b/android/src/main/java/com/beefe/picker/view/PickerViewAlone.java @@ -212,6 +212,17 @@ public void setTextSize(float size){ } } + public void setTextEllipsisLen(int len){ + int viewCount = pickerViewAloneLayout.getChildCount(); + for (int i = 0; i < viewCount; i++) { + View view = pickerViewAloneLayout.getChildAt(i); + if (view instanceof LoopView) { + LoopView loopView = (LoopView) view; + loopView.setTextEllipsisLen(len); + } + } + } + public void setIsLoop(boolean isLoop) { if (!isLoop) { int viewCount = pickerViewAloneLayout.getChildCount(); diff --git a/android/src/main/java/com/beefe/picker/view/PickerViewLinkage.java b/android/src/main/java/com/beefe/picker/view/PickerViewLinkage.java index efe4fbd87..f1e6be376 100644 --- a/android/src/main/java/com/beefe/picker/view/PickerViewLinkage.java +++ b/android/src/main/java/com/beefe/picker/view/PickerViewLinkage.java @@ -252,6 +252,12 @@ public void onItemSelected(String item, int index) { selectTwoIndex = index; ReadableArray arr = data.get(selectOneIndex).getArray(oneList.get(selectOneIndex)); + int arrSize = arr.size(); + //fix IndexOutOfBoundsException + //by zooble @2018-1-10 + if(index > arrSize){ + index = arrSize - 1; + } ReadableMap childMap = arr.getMap(index); String key = childMap.keySetIterator().nextKey(); ReadableArray sunArray = childMap.getArray(key); @@ -288,6 +294,17 @@ public void onItemSelected(String item, int index) { loopViewThree.setListener(new OnItemSelectedListener() { @Override public void onItemSelected(String item, int index) { + //fix IndexOutOfBoundsException + //by zooble @2018-1-10 + int arrOneSize = oneList.size(); + if(selectOneIndex >= arrOneSize){ + selectOneIndex = arrOneSize - 1; + } + int arrTwoSize = twoList.size(); + if(selectTwoIndex >= arrTwoSize){ + selectTwoIndex = arrTwoSize - 1; + } + returnData = new ReturnData(); returnData.setItem(oneList.get(selectOneIndex)); returnData.setIndex(loopViewOne.getSelectedIndex()); @@ -586,6 +603,20 @@ public void setTextSize(float size){ } } + public void setTextEllipsisLen(int len){ + switch (curRow) { + case 2: + loopViewOne.setTextEllipsisLen(len); + loopViewTwo.setTextEllipsisLen(len); + break; + case 3: + loopViewOne.setTextEllipsisLen(len); + loopViewTwo.setTextEllipsisLen(len); + loopViewThree.setTextEllipsisLen(len); + break; + } + } + public void setTextColor(int color){ switch (curRow) { case 2: diff --git a/example/PickerTest/PickerTest.js b/example/PickerTest/PickerTest.js index 59666aa06..aae4434e1 100644 --- a/example/PickerTest/PickerTest.js +++ b/example/PickerTest/PickerTest.js @@ -77,8 +77,6 @@ export default class PickerTest extends Component { _showDatePicker() { Picker.init({ pickerData: this._createDateData(), - pickerToolBarFontSize: 16, - pickerFontSize: 16, pickerFontColor: [255, 0 ,0, 1], onPickerConfirm: (pickedValue, pickedIndex) => { console.log('date', pickedValue, pickedIndex); diff --git a/index.js b/index.js index ec2af0f26..12a40379c 100644 --- a/index.js +++ b/index.js @@ -16,6 +16,7 @@ const options = { pickerCancelBtnColor: [1, 186, 245, 1], pickerTitleColor: [20, 20, 20, 1], pickerToolBarBg: [232, 232, 232, 1], + pickerTextEllipsisLen: 6, pickerBg: [196, 199, 206, 1], pickerRowHeight: 24, wheelFlex: [1, 1, 1], diff --git a/package.json b/package.json index e72531868..eaa65baca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-picker", - "version": "4.3.2", + "version": "4.3.4", "description": "A Native Picker with high performance.", "main": "index.js", "types": "index.d.ts",