Commit 0be959c1 authored by xwenliang's avatar xwenliang

native picker

parent ba944ad4
......@@ -2,13 +2,7 @@
[![npm version](https://img.shields.io/npm/v/react-native-picker.svg?style=flat-square)](https://www.npmjs.com/package/react-native-picker) <a href="https://david-dm.org/beefe/react-native-picker"><img src="https://david-dm.org/beefe/react-native-picker.svg?style=flat-square" alt="dependency status"></a>
A Picker written in pure javascript for cross-platform support.
It was most likely an example of how to build a cross-platform Picker Component use [react-native-picker-android](https://github.com/beefe/react-native-picker-android).
###Warn
if 0.14.2 <= react-native <=0.24 `npm install react-native-picker@2.0.5 --save`
if 0.24 < react-native `npm install react-native-picker --save`
A Native Picker with high performance
####Demo
......@@ -23,21 +17,19 @@ if 0.24 < react-native `npm install react-native-picker --save`
###Documentation
####Props
- <b>style</b> style of picker, you can set width and height of picker in this prop
- <b>pickerElevation</b> elevation of picker (for issue https://github.com/beefe/react-native-picker/issues/27)
- <b>pickerBtnText</b> string, tool bar's confirm btn text
- <b>pickerCancelBtnText</b> string, tool bar's cancel ben text
- <b>pickerBtnStyle</b> textStylePropType, tool bar's btn style
- <b>pickerToolBarStyle</b> viewStylePropType, tool bar's style
- <b>showDuration</b> number, animation of picker
- <b>showMask</b> boolean, default to be false, cancel the picker by tapping in the rest of the screen support when setted to be true
- <b>pickerTitle</b> string, title of picker
- <b>pickerTitleStyle</b> textStylePropType, style of title
- <b>pickerData</b> array
- <b>selectedValue</b> any
- <b>onPickerDone</b> function
- <b>onPickerCancel</b> function
- <b>onValueChange</b> function
- <b>pickerConfirmBtnText</b> string, 确认按钮文字
- <b>pickerCancelBtnText</b> string, 取消按钮文字
- <b>pickerTitleText</b> string, 标题文字
- <b>pickerConfirmBtnColor</b> ['255', '66', '00', 0.5], 确认按钮字体颜色
- <b>pickerCancelBtnColor</b> ['255', '66', '00', 0.5], 取消按钮字体颜色
- <b>pickerTitleColor</b> ['255', '66', '00', 0.5], 标题字体颜色
- <b>pickerToolBarBg</b> ['255', '66', '00', 0.5], 工具栏背景颜色
- <b>pickerBg</b> ['255', '66', '00', 0.5], picker背景颜色
- <b>pickerData</b> 数组或对象,picker数据
- <b>selectedValue</b> string,默认选中数据
- <b>onPickerConfirm</b> function,确认按钮回调
- <b>onPickerCancel</b> function,取消按钮回调
- <b>onPickerSelect</b> function,滚轮滚动时回调
####Methods
- <b>toggle</b> show or hide picker, default to be hiden
......@@ -53,21 +45,37 @@ if 0.24 < react-native `npm install react-native-picker --save`
npm install react-native-picker --save
```
####Step 2 - import and use in project
####Step 2 - link
```
react-native link
```
####Step 3 - import and use in project
```javascript
import Picker from 'react-native-picker'
<Picker
style={{
height: 300
}}
showDuration={300}
showMask={true}
pickerData={}//picker`s value List
selectedValue={}//default to be selected value
onPickerDone={}//when confirm your choice
/>
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.show();
```
###Notice
......@@ -104,11 +112,9 @@ if 0.24 < react-native `npm install react-native-picker --save`
```javascript
pickerData = {
{
a: [1,2,3,4],
b: [5,6,7,8],
...
}
};
selectedValue = ['a', 2];
```
......
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.facebook.react:react-native:0.20.1'
}
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/heng/Desktop/android-sdk-macosx/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.beefe.picker">
</manifest>
package com.beefe.picker;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.beefe.picker.view.OnSelectedListener;
import com.beefe.picker.view.PickerViewAlone;
import com.beefe.picker.view.PickerViewLinkage;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import java.util.ArrayList;
/**
* Created by heng on 16/9/5.
*/
public class PickerViewModule extends ReactContextBaseJavaModule {
private static final String REACT_CLASS = "BEEPickerManager";
private static final String PICKER_DATA = "pickerData";
private static final String SELECTED_VALUE = "selectedValue";
private static final String IS_LOOP = "isLoop";
private static final String PICKER_BG_COLOR = "pickerBg";
private static final String TEXT_BAR_COLOR = "pickerToolBarBg";
private static final String CONFIRM_TEXT = "pickerConfirmBtnText";
private static final String CONFIRM_TEXT_COLOR = "pickerConfirmBtnColor";
private static final String CANCEL_TEXT = "pickerCancelBtnText";
private static final String CANCEL_TEXT_COLOR = "pickerCancelBtnColor";
private static final String TITLE_TEXT = "pickerTitleText";
private static final String TITLE_TEXT_COLOR = "pickerTitleColor";
private static final String PICKER_EVENT_NAME = "pickerEvent";
private static final String EVENT_KEY_CONFIRM = "confirm";
private static final String EVENT_KEY_CANCEL = "cancel";
private static final String EVENT_KEY_SELECTED = "select";
private static final String ERROR_NOT_INIT = "please initialize";
private View view;
private PopupWindow popupWindow = null;
private boolean isLoop = true;
private String confirmText;
private String cancelText;
private String titleText;
private int[] pickerColor = new int[4];
private int[] barBgColor = new int[4];
private int[] confirmTextColor = new int[4];
private int[] cancelTextColor = new int[4];
private int[] titleTextColor = new int[4];
private ArrayList<String> curSelectedList = new ArrayList<>();
private RelativeLayout pickerParent;
private RelativeLayout barLayout;
private TextView cancelTV;
private TextView titleTV;
private TextView confirmTV;
private PickerViewLinkage pickerViewLinkage;
private PickerViewAlone pickerViewAlone;
public PickerViewModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return REACT_CLASS;
}
@ReactMethod
public void _init(ReadableMap options) {
Activity activity = getCurrentActivity();
if (activity != null && options.hasKey(PICKER_DATA)) {
view = activity.getLayoutInflater().inflate(R.layout.popup_picker_view, null);
pickerParent = (RelativeLayout) view.findViewById(R.id.pickerParent);
barLayout = (RelativeLayout) view.findViewById(R.id.barLayout);
cancelTV = (TextView) view.findViewById(R.id.cancel);
titleTV = (TextView) view.findViewById(R.id.title);
confirmTV = (TextView) view.findViewById(R.id.confirm);
pickerViewLinkage = (PickerViewLinkage) view.findViewById(R.id.pickerViewLinkage);
pickerViewAlone = (PickerViewAlone) view.findViewById(R.id.pickerViewAlone);
pickerParent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
commonEvent(EVENT_KEY_CANCEL);
hide();
}
});
if (options.hasKey(TEXT_BAR_COLOR)) {
ReadableArray array = options.getArray(TEXT_BAR_COLOR);
for (int i = 0; i < array.size(); i++) {
if (i == 3) {
barBgColor[i] = (int) (array.getDouble(i) * 255);
} else {
barBgColor[i] = array.getInt(i);
}
}
barLayout.setBackgroundColor(Color.argb(barBgColor[3], barBgColor[0], barBgColor[1], barBgColor[2]));
}
if (options.hasKey(CONFIRM_TEXT)) {
confirmText = options.getString(CONFIRM_TEXT);
}
confirmTV.setText(!TextUtils.isEmpty(confirmText) ? confirmText : "");
if (options.hasKey(CONFIRM_TEXT_COLOR)) {
ReadableArray array = options.getArray(CONFIRM_TEXT_COLOR);
for (int i = 0; i < array.size(); i++) {
if (i == 3) {
confirmTextColor[i] = (int) (array.getDouble(i) * 255);
} else {
confirmTextColor[i] = array.getInt(i);
}
}
confirmTV.setTextColor(Color.argb(confirmTextColor[3], confirmTextColor[0], confirmTextColor[1], confirmTextColor[2]));
}
confirmTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
commonEvent(EVENT_KEY_CONFIRM);
hide();
}
});
if (options.hasKey(TITLE_TEXT)) {
titleText = options.getString(TITLE_TEXT);
}
titleTV.setText(!TextUtils.isEmpty(titleText) ? titleText : "");
if (options.hasKey(TITLE_TEXT_COLOR)) {
ReadableArray array = options.getArray(TITLE_TEXT_COLOR);
for (int i = 0; i < array.size(); i++) {
if (i == 3) {
titleTextColor[i] = (int) (array.getDouble(i) * 255);
} else {
titleTextColor[i] = array.getInt(i);
}
}
titleTV.setTextColor(Color.argb(titleTextColor[3], titleTextColor[0], titleTextColor[1], titleTextColor[2]));
}
if (options.hasKey(CANCEL_TEXT)) {
cancelText = options.getString(CANCEL_TEXT);
}
cancelTV.setText(!TextUtils.isEmpty(cancelText) ? cancelText : "");
if (options.hasKey(CANCEL_TEXT_COLOR)) {
ReadableArray array = options.getArray(CANCEL_TEXT_COLOR);
for (int i = 0; i < array.size(); i++) {
if (i == 3) {
cancelTextColor[i] = (int) (array.getDouble(i) * 255);
} else {
cancelTextColor[i] = array.getInt(i);
}
}
cancelTV.setTextColor(Color.argb(cancelTextColor[3], cancelTextColor[0], cancelTextColor[1], cancelTextColor[2]));
}
cancelTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
commonEvent(EVENT_KEY_CANCEL);
hide();
}
});
if (options.hasKey(IS_LOOP)) {
isLoop = options.getBoolean(IS_LOOP);
}
String[] selectValue = {};
if (options.hasKey(SELECTED_VALUE)) {
ReadableArray array = options.getArray(SELECTED_VALUE);
selectValue = new String[array.size()];
String value = "";
for (int i = 0; i < array.size(); i++) {
switch (array.getType(i).name()) {
case "Boolean":
value = String.valueOf(array.getBoolean(i));
break;
case "Number":
try {
value = String.valueOf(array.getInt(i));
} catch (Exception e) {
value = String.valueOf(array.getDouble(i));
}
break;
case "String":
value = array.getString(i);
break;
}
selectValue[i] = value;
}
}
switch (options.getType(PICKER_DATA).name()) {
case "Map":
pickerViewLinkage.setVisibility(View.VISIBLE);
pickerViewAlone.setVisibility(View.GONE);
ReadableMap linkageData = options.getMap(PICKER_DATA);
if (linkageData != null) {
pickerViewLinkage.setLinkageData(linkageData, curSelectedList);
}
pickerViewLinkage.setIsLoop(isLoop);
if (options.hasKey(PICKER_BG_COLOR)) {
ReadableArray array = options.getArray(PICKER_BG_COLOR);
for (int i = 0; i < array.size(); i++) {
if (i == 3) {
pickerColor[i] = (int) (array.getDouble(i) * 255);
} else {
pickerColor[i] = array.getInt(i);
}
}
pickerViewLinkage.setBackgroundColor(Color.argb(pickerColor[3], pickerColor[0], pickerColor[1], pickerColor[2]));
}
pickerViewLinkage.setOnSelectListener(new OnSelectedListener() {
@Override
public void onSelected(ArrayList<String> selectedList) {
curSelectedList = selectedList;
commonEvent(EVENT_KEY_SELECTED);
}
});
pickerViewLinkage.setSelectValue(selectValue, curSelectedList);
break;
case "Array":
pickerViewAlone.setVisibility(View.VISIBLE);
pickerViewLinkage.setVisibility(View.GONE);
ReadableArray aloneData = options.getArray(PICKER_DATA);
if (aloneData != null) {
switch (aloneData.getType(0).name()) {
case "Array":
pickerViewAlone.setPickerViewDta(aloneData, curSelectedList);
break;
default:
pickerViewAlone.setAloneData(aloneData, curSelectedList);
break;
}
}
pickerViewAlone.setIsLoop(isLoop);
if (options.hasKey(PICKER_BG_COLOR)) {
ReadableArray array = options.getArray(PICKER_BG_COLOR);
for (int i = 0; i < array.size(); i++) {
if (i == 3) {
pickerColor[i] = (int) (array.getDouble(i) * 255);
} else {
pickerColor[i] = array.getInt(i);
}
}
pickerViewAlone.setBackgroundColor(Color.argb(pickerColor[3], pickerColor[0], pickerColor[1], pickerColor[2]));
}
pickerViewAlone.setOnSelectedListener(new OnSelectedListener() {
@Override
public void onSelected(ArrayList<String> selectedList) {
curSelectedList = selectedList;
commonEvent(EVENT_KEY_SELECTED);
}
});
pickerViewAlone.setSelectValue(selectValue, curSelectedList);
break;
}
if (popupWindow == null) {
popupWindow = new PopupWindow(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
popupWindow.setBackgroundDrawable(new ColorDrawable());
popupWindow.setFocusable(true);
popupWindow.setAnimationStyle(R.style.PopAnim);
popupWindow.setOutsideTouchable(true);
}
popupWindow.setContentView(view);
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
}
}
@ReactMethod
public void initOK(Callback callback) {
callback.invoke(popupWindow != null);
}
@ReactMethod
public void toggle() {
if (popupWindow == null)
return;
if (popupWindow.isShowing()) {
hide();
} else {
show();
}
}
@ReactMethod
public void show() {
if (popupWindow != null) {
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
}
}
@ReactMethod
public void hide() {
if (popupWindow != null) {
popupWindow.dismiss();
}
}
@ReactMethod
public void isPickerShow(Callback callback) {
if (popupWindow == null) {
callback.invoke(ERROR_NOT_INIT);
} else {
callback.invoke(null, popupWindow.isShowing());
}
}
private void commonEvent(String eventKey) {
WritableMap map = Arguments.createMap();
WritableArray array = Arguments.createArray();
for (String item : curSelectedList) {
array.pushString(item);
}
map.putArray(eventKey, array);
sendEvent(getReactApplicationContext(), PICKER_EVENT_NAME, map);
}
private void sendEvent(ReactContext reactContext,
String eventName,
@Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
package com.beefe.picker;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Created by heng on 16/9/5.
*/
public class PickerViewPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new PickerViewModule(reactContext));
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
package com.beefe.picker.view;
import java.util.TimerTask;
final class InertiaTimerTask extends TimerTask {
float a;
final float velocityY;
final LoopView loopView;
InertiaTimerTask(LoopView loopview, float velocityY) {
super();
loopView = loopview;
this.velocityY = velocityY;
a = Integer.MAX_VALUE;
}
@Override
public final void run() {
if (a == Integer.MAX_VALUE) {
if (Math.abs(velocityY) > 2000F) {
if (velocityY > 0.0F) {
a = 2000F;
} else {
a = -2000F;
}
} else {
a = velocityY;
}
}
if (Math.abs(a) >= 0.0F && Math.abs(a) <= 20F) {
loopView.cancelFuture();
loopView.handler.sendEmptyMessage(MessageHandler.WHAT_SMOOTH_SCROLL);
return;
}
int i = (int) ((a * 10F) / 1000F);
LoopView loopview = loopView;
loopview.totalScrollY = loopview.totalScrollY - i;
if (!loopView.isLoop) {
float itemHeight = loopView.lineSpacingMultiplier * loopView.maxTextHeight;
if (loopView.totalScrollY <= (int) ((float) (-loopView.initPosition) * itemHeight)) {
a = 40F;
loopView.totalScrollY = (int) ((float) (-loopView.initPosition) * itemHeight);
} else if (loopView.totalScrollY >= (int) ((float) (loopView.items.size() - 1 - loopView.initPosition) * itemHeight)) {
loopView.totalScrollY = (int) ((float) (loopView.items.size() - 1 - loopView.initPosition) * itemHeight);
a = -40F;
}
}
if (a < 0.0F) {
a = a + 20F;
} else {
a = a - 20F;
}
loopView.handler.sendEmptyMessage(MessageHandler.WHAT_INVALIDATE_LOOP_VIEW);
}
}
package com.beefe.picker.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class LoopView extends View {
private float scaleX = 1.05F;
enum ACTION {
// 点击,滑翔(滑到尽头),拖拽事件
CLICK, FLING, DRAG
}
private Context context;
Handler handler;
private GestureDetector gestureDetector;
OnItemSelectedListener onItemSelectedListener;
// Timer mTimer;
private ScheduledExecutorService mExecutor = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> mFuture;
private Paint paintOuterText;
private Paint paintCenterText;
private Paint paintIndicator;
List<String> items;
private int textSize;
int maxTextHeight;
private int colorGray;
private int colorBlack;
private int colorLightGray;
// 条目间距倍数
float lineSpacingMultiplier;
boolean isLoop;
// 第一条线Y坐标值
private int firstLineY;
private int secondLineY;
int totalScrollY;
int initPosition;
private String selectedItem;
private int selectedIndex;
private int preCurrentIndex;
// 显示几个条目
private int itemsVisible;
private int measuredHeight;
// 半圆周长
private int halfCircumference;
// 半径
private int radius;
private int mOffset = 0;
private float previousY;
private long startTime = 0;
private Rect tempRect = new Rect();
public LoopView(Context context) {
super(context);
initLoopView(context);
}
public LoopView(Context context, AttributeSet attributeset) {
super(context, attributeset);
initLoopView(context);
}
public LoopView(Context context, AttributeSet attributeset, int defStyleAttr) {
super(context, attributeset, defStyleAttr);
initLoopView(context);
}
private void initLoopView(Context context) {
this.context = context;
handler = new MessageHandler(this);
gestureDetector = new GestureDetector(context, new LoopViewGestureListener(this));
gestureDetector.setIsLongpressEnabled(false);
lineSpacingMultiplier = 2.0F;
isLoop = true;
itemsVisible = 9;
textSize = 0;
colorGray = 0xffafafaf;
colorBlack = 0xff313131;
colorLightGray = 0xffc5c5c5;
totalScrollY = 0;
initPosition = -1;
initPaints();
setTextSize(20F);
}
private void initPaints() {
paintOuterText = new Paint();
paintOuterText.setColor(colorGray);
paintOuterText.setAntiAlias(true);
paintOuterText.setTypeface(Typeface.MONOSPACE);
paintOuterText.setTextSize(textSize);
paintCenterText = new Paint();
paintCenterText.setColor(colorBlack);
paintCenterText.setAntiAlias(true);
paintCenterText.setTextScaleX(scaleX);
paintCenterText.setTypeface(Typeface.MONOSPACE);
paintCenterText.setTextSize(textSize);
paintIndicator = new Paint();
paintIndicator.setColor(colorLightGray);
paintIndicator.setAntiAlias(true);
if (android.os.Build.VERSION.SDK_INT >= 11) {
setLayerType(LAYER_TYPE_SOFTWARE, null);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
remeasure();
setMeasuredDimension(widthMeasureSpec, measuredHeight);
}
private void remeasure() {
if (items == null) {
return;
}
maxTextHeight = textSize;
halfCircumference = (int) (maxTextHeight * lineSpacingMultiplier * (itemsVisible - 1));
measuredHeight = (int) ((halfCircumference * 2) / Math.PI);
radius = (int) (halfCircumference / Math.PI);
firstLineY = (int) ((measuredHeight - lineSpacingMultiplier * maxTextHeight) / 2.0F);
secondLineY = (int) ((measuredHeight + lineSpacingMultiplier * maxTextHeight) / 2.0F);
if (initPosition == -1) {
if (isLoop) {
initPosition = (items.size() + 1) / 2;
} else {
initPosition = 0;
}
}
preCurrentIndex = initPosition;
}
void smoothScroll(ACTION action) {
cancelFuture();
if (action == ACTION.FLING || action == ACTION.DRAG) {
float itemHeight = lineSpacingMultiplier * maxTextHeight;
mOffset = (int) ((totalScrollY % itemHeight + itemHeight) % itemHeight);
if ((float) mOffset > itemHeight / 2.0F) {
mOffset = (int) (itemHeight - (float) mOffset);
} else {
mOffset = -mOffset;
}
}
mFuture = mExecutor.scheduleWithFixedDelay(new SmoothScrollTimerTask(this, mOffset), 0, 10, TimeUnit.MILLISECONDS);
}
protected final void scrollBy(float velocityY) {
cancelFuture();
// 修改这个值可以改变滑行速度
int velocityFling = 10;
mFuture = mExecutor.scheduleWithFixedDelay(new InertiaTimerTask(this, velocityY), 0, velocityFling, TimeUnit.MILLISECONDS);
}
public void cancelFuture() {
if (mFuture != null && !mFuture.isCancelled()) {
mFuture.cancel(true);
mFuture = null;
}
}
public final void setNotLoop() {
isLoop = false;
}
public final void setTextSize(float size) {
if (size > 0.0F) {
textSize = (int) (context.getResources().getDisplayMetrics().density * size);
paintOuterText.setTextSize(textSize);
paintCenterText.setTextSize(textSize);
}
}
public boolean hasItem(String item) {
int result = items.indexOf(item);
return result != -1;
}
public void setSelectedItem(String item) {
int selectedIndex = items.indexOf(item);
setSelectedPosition(selectedIndex);
}
public int getItemPosition(String item) {
return items.indexOf(item);
}
public final void setSelectedPosition(int initPosition) {
if (initPosition < 0) {
this.initPosition = 0;
} else {
if (items != null && items.size() > initPosition) {
this.initPosition = initPosition;
}
}
totalScrollY = 0;
cancelFuture();
invalidate();
}
public final void setListener(OnItemSelectedListener OnItemSelectedListener) {
onItemSelectedListener = OnItemSelectedListener;
}
public final void setItems(List<String> items) {
this.items = items;
remeasure();
invalidate();
}
public String getIndexItem(int index) {
return items.get(index);
}
public String getSelectedItem() {
return selectedItem;
}
public final int getSelectedIndex() {
return selectedIndex;
}
protected final void onItemSelected() {
if (onItemSelectedListener != null) {
postDelayed(new OnItemSelectedRunnable(this), 200L);
}
}
@Override
protected void onDraw(Canvas canvas) {
if (items == null) {
return;
}
String as[] = new String[itemsVisible];
int change = (int) (totalScrollY / (lineSpacingMultiplier * maxTextHeight));
preCurrentIndex = initPosition + change % items.size();
if (!isLoop) {
if (preCurrentIndex < 0) {
preCurrentIndex = 0;
}
if (preCurrentIndex > items.size() - 1) {
preCurrentIndex = items.size() - 1;
}
} else {
if (preCurrentIndex < 0) {
preCurrentIndex = items.size() + preCurrentIndex;
}
if (preCurrentIndex > items.size() - 1) {
preCurrentIndex = preCurrentIndex - items.size();
}
}
int j2 = (int) (totalScrollY % (lineSpacingMultiplier * maxTextHeight));
// 设置as数组中每个元素的值
int k1 = 0;
while (k1 < itemsVisible) {
int l1 = preCurrentIndex - (itemsVisible / 2 - k1);
if (isLoop) {
while (l1 < 0) {
l1 = l1 + items.size();
}
while (l1 > items.size() - 1) {
l1 = l1 - items.size();
}
as[k1] = items.get(l1);
} else if (l1 < 0) {
as[k1] = "";
} else if (l1 > items.size() - 1) {
as[k1] = "";
} else {
as[k1] = items.get(l1);
}
k1++;
}
canvas.drawLine(0.0F, firstLineY, getWidth(), firstLineY, paintIndicator);
canvas.drawLine(0.0F, secondLineY, getWidth(), secondLineY, paintIndicator);
int j1 = 0;
while (j1 < itemsVisible) {
canvas.save();
// L(弧长)=α(弧度)* r(半径) (弧度制)
// 求弧度--> (L * π ) / (π * r) (弧长X派/半圆周长)
float itemHeight = maxTextHeight * lineSpacingMultiplier;
double radian = ((itemHeight * j1 - j2) * Math.PI) / halfCircumference;
// 弧度转换成角度(把半圆以Y轴为轴心向右转90度,使其处于第一象限及第四象限
float angle = (float) (90D - (radian / Math.PI) * 180D);
if (angle >= 90F || angle <= -90F) {
canvas.restore();
} else {
int translateY = (int) (radius - Math.cos(radian) * radius - (Math.sin(radian) * maxTextHeight) / 2D);
canvas.translate(0.0F, translateY);
canvas.scale(1.0F, (float) Math.sin(radian));
String text = as[j1];
if (translateY <= firstLineY && maxTextHeight + translateY >= firstLineY) {
// 条目经过第一条线
canvas.save();
canvas.clipRect(0, 0, getWidth(), firstLineY - translateY);
canvas.drawText(text, getX(text, paintOuterText), maxTextHeight, paintOuterText);
canvas.restore();
canvas.save();
canvas.clipRect(0, firstLineY - translateY, getWidth(), (int) (itemHeight));
canvas.drawText(text, getX(text, paintCenterText), maxTextHeight, 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), maxTextHeight, paintCenterText);
canvas.restore();
canvas.save();
canvas.clipRect(0, secondLineY - translateY, getWidth(), (int) (itemHeight));
canvas.drawText(text, getX(text, paintOuterText), maxTextHeight, paintOuterText);
canvas.restore();
} else if (translateY >= firstLineY && maxTextHeight + translateY <= secondLineY) {
// 中间条目
canvas.clipRect(0, 0, getWidth(), (int) (itemHeight));
canvas.drawText(text, getX(text, paintCenterText), maxTextHeight, paintCenterText);
selectedItem = text;
selectedIndex = items.indexOf(text);
} else {
// 其他条目
canvas.clipRect(0, 0, getWidth(), (int) (itemHeight));
canvas.drawText(text, getX(text, paintOuterText), maxTextHeight, paintOuterText);
}
canvas.restore();
}
j1++;
}
}
private float getX(String text, Paint paint) {
paint.getTextBounds(text, 0, text.length(), tempRect);
return (getWidth() - tempRect.width() * scaleX) / 2;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean eventConsumed = gestureDetector.onTouchEvent(event);
float itemHeight = lineSpacingMultiplier * maxTextHeight;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startTime = System.currentTimeMillis();
cancelFuture();
previousY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float dy = previousY - event.getRawY();
previousY = event.getRawY();
totalScrollY = (int) (totalScrollY + dy);
// 边界处理。
if (!isLoop) {
float top = -initPosition * itemHeight;
float bottom = (items.size() - 1 - initPosition) * itemHeight;
if (totalScrollY < top) {
totalScrollY = (int) top;
} else if (totalScrollY > bottom) {
totalScrollY = (int) bottom;
}
}
break;
case MotionEvent.ACTION_UP:
default:
if (!eventConsumed) {
float y = event.getY();
double l = Math.acos((radius - y) / radius) * radius;
int circlePosition = (int) ((l + itemHeight / 2) / itemHeight);
float extraOffset = (totalScrollY % itemHeight + itemHeight) % itemHeight;
mOffset = (int) ((circlePosition - itemsVisible / 2) * itemHeight - extraOffset);
if ((System.currentTimeMillis() - startTime) > 120) {
// 处理拖拽事件
smoothScroll(ACTION.DRAG);
} else {
// 处理条目点击事件
smoothScroll(ACTION.CLICK);
}
}
break;
}
invalidate();
return true;
}
}
package com.beefe.picker.view;
import android.view.MotionEvent;
final class LoopViewGestureListener extends android.view.GestureDetector.SimpleOnGestureListener {
final LoopView loopView;
LoopViewGestureListener(LoopView loopview) {
loopView = loopview;
}
@Override
public final boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
loopView.scrollBy(velocityY);
return true;
}
}
package com.beefe.picker.view;
import android.os.Handler;
import android.os.Message;
final class MessageHandler extends Handler {
public static final int WHAT_INVALIDATE_LOOP_VIEW = 1000;
public static final int WHAT_SMOOTH_SCROLL = 2000;
public static final int WHAT_ITEM_SELECTED = 3000;
final LoopView loopview;
MessageHandler(LoopView loopview) {
this.loopview = loopview;
}
@Override
public final void handleMessage(Message msg) {
switch (msg.what) {
case WHAT_INVALIDATE_LOOP_VIEW:
loopview.invalidate();
break;
case WHAT_SMOOTH_SCROLL:
loopview.smoothScroll(LoopView.ACTION.FLING);
break;
case WHAT_ITEM_SELECTED:
loopview.onItemSelected();
break;
}
}
}
package com.beefe.picker.view;
public interface OnItemSelectedListener {
void onItemSelected(String item, int index);
}
package com.beefe.picker.view;
final class OnItemSelectedRunnable implements Runnable {
final LoopView loopView;
OnItemSelectedRunnable(LoopView loopview) {
loopView = loopview;
}
@Override
public final void run() {
loopView.onItemSelectedListener.onItemSelected(loopView.getSelectedItem(),loopView.getSelectedIndex());
}
}
package com.beefe.picker.view;
import java.util.ArrayList;
/**
* Created by heng on 16/9/6.
*/
public interface OnSelectedListener {
void onSelected(ArrayList<String> selectedList);
}
package com.beefe.picker.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import com.beefe.picker.R;
import com.facebook.react.bridge.ReadableArray;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by heng on 16/9/6.
*/
public class PickerViewAlone extends LinearLayout {
private LinearLayout pickerViewAloneLayout;
private OnSelectedListener onSelectedListener;
private int position;
public PickerViewAlone(Context context) {
super(context);
init(context);
}
public PickerViewAlone(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.picker_view_alone, this);
pickerViewAloneLayout = (LinearLayout) view.findViewById(R.id.pickerViewAloneLayout);
}
public void setOnSelectedListener(OnSelectedListener listener) {
this.onSelectedListener = listener;
}
public void setAloneData(ReadableArray array, final ArrayList<String> curSelectedList) {
ArrayList<String> values = arrayToList(array);
final LoopView loopView = new LoopView(getContext());
LayoutParams params = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.weight = 1.0f;
loopView.setLayoutParams(params);
loopView.setItems(values);
loopView.setSelectedPosition(0);
if (curSelectedList.size() > 0) {
curSelectedList.set(0, values.get(0));
} else {
curSelectedList.add(0, values.get(0));
}
loopView.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(String item, int index) {
if (onSelectedListener != null) {
curSelectedList.set(0, item);
onSelectedListener.onSelected(curSelectedList);
}
}
});
pickerViewAloneLayout.addView(loopView);
}
public void setPickerViewDta(ReadableArray array, final ArrayList<String> curSelectedList) {
final String[] selectedItems = new String[array.size()];
for (int i = 0; i < array.size(); i++) {
switch (array.getType(i).name()) {
case "Array":
ReadableArray childArray = array.getArray(i);
ArrayList<String> values = arrayToList(childArray);
final LoopView loopView = new LoopView(getContext());
LayoutParams params = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.weight = 1.0f;
loopView.setLayoutParams(params);
loopView.setItems(values);
loopView.setTag(i);
loopView.setSelectedPosition(0);
if (curSelectedList.size() > i) {
curSelectedList.set(i, values.get(0));
} else {
curSelectedList.add(i, values.get(0));
}
selectedItems[i] = values.get(0);
loopView.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(String item, int index) {
int viewCount = pickerViewAloneLayout.getChildCount();
for (int j = 0; j < viewCount; j++) {
View view = pickerViewAloneLayout.getChildAt(j);
if (view instanceof LoopView) {
LoopView loop = (LoopView) view;
if (loop.getTag() == loopView.getTag()) {
position = j;
break;
}
}
}
selectedItems[position] = item;
if (onSelectedListener != null) {
for (int i = 0; i < selectedItems.length; i++) {
curSelectedList.set(i, selectedItems[i]);
}
onSelectedListener.onSelected(curSelectedList);
}
}
});
pickerViewAloneLayout.addView(loopView);
break;
default:
break;
}
}
}
public void setSelectValue(String[] selectValue, final ArrayList<String> curSelectedList) {
int viewCount = pickerViewAloneLayout.getChildCount();
int valueCount = selectValue.length;
if (valueCount <= viewCount) {
setSelect(valueCount, selectValue, curSelectedList);
} else {
String[] values = Arrays.copyOf(selectValue, viewCount);
setSelect(viewCount, values, curSelectedList);
}
}
private void setSelect(int size, String[] values, ArrayList<String> curSelectedList) {
for (int i = 0; i < size; i++) {
View view = pickerViewAloneLayout.getChildAt(i);
if (view instanceof LoopView) {
LoopView loop = (LoopView) view;
if (loop.hasItem(values[i])) {
loop.setSelectedItem(values[i]);
curSelectedList.set(i, values[i]);
}
}
}
}
public void setIsLoop(boolean isLoop) {
if (!isLoop) {
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.setNotLoop();
}
}
}
}
private ArrayList<String> arrayToList(ReadableArray array) {
ArrayList<String> values = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
String value = "";
switch (array.getType(i).name()) {
case "Boolean":
value = String.valueOf(array.getBoolean(i));
break;
case "Number":
try {
value = String.valueOf(array.getInt(i));
} catch (Exception e) {
value = String.valueOf(array.getDouble(i));
}
break;
case "String":
value = array.getString(i);
break;
}
values.add(value);
}
return values;
}
}
package com.beefe.picker.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import com.beefe.picker.R;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by heng on 16/9/1.
*/
public class PickerViewLinkage extends LinearLayout {
private LoopView loopViewOne;
private LoopView loopViewTwo;
private LoopView loopViewThree;
private OnSelectedListener onSelectedListener;
private int curRow;
public PickerViewLinkage(Context context) {
super(context);
init(context);
}
public PickerViewLinkage(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public PickerViewLinkage(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.picker_view_linkage, this);
loopViewOne = (LoopView) view.findViewById(R.id.loopViewOne);
loopViewTwo = (LoopView) view.findViewById(R.id.loopViewTwo);
loopViewThree = (LoopView) view.findViewById(R.id.loopViewThree);
}
private void setRow(int row) {
switch (row) {
case 2:
curRow = 2;
loopViewTwo.setVisibility(VISIBLE);
loopViewOne.setVisibility(VISIBLE);
loopViewThree.setVisibility(GONE);
break;
case 3:
curRow = 3;
loopViewOne.setVisibility(VISIBLE);
loopViewTwo.setVisibility(VISIBLE);
loopViewThree.setVisibility(VISIBLE);
break;
default:
break;
}
}
private ArrayList<String> oneList = new ArrayList<>();
private ArrayList<String> twoList = new ArrayList<>();
private ArrayList<String> threeList = new ArrayList<>();
private ReadableArray array;
private ReadableMap map;
private ReadableMap childMap;
private int selectOneIndex;
private int selectTwoIndex;
private void checkItems(LoopView loopView, ArrayList<String> list) {
if (list != null && list.size() > 0) {
loopView.setItems(list);
loopView.setSelectedPosition(0);
}
}
public void setLinkageData(final ReadableMap map, final ArrayList<String> curSelectedList) {
this.map = map;
ReadableMapKeySetIterator iterator = map.keySetIterator();
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
oneList.add(key);
}
checkItems(loopViewOne, oneList);
if (curSelectedList.size() > 0) {
curSelectedList.set(0, oneList.get(0));
} else {
curSelectedList.add(0, oneList.get(0));
}
String name = map.getType(oneList.get(0)).name();
switch (name) {
case "Map":
setRow(3);
childMap = map.getMap(oneList.get(0));
ReadableMapKeySetIterator childIterator = childMap.keySetIterator();
twoList.clear();
while (childIterator.hasNextKey()) {
String key = childIterator.nextKey();
twoList.add(key);
}
checkItems(loopViewTwo, twoList);
if (curSelectedList.size() > 1) {
curSelectedList.set(1, twoList.get(0));
} else {
curSelectedList.add(1, twoList.get(0));
}
array = childMap.getArray(twoList.get(0));
threeList.clear();
threeList = arrayToList(array);
checkItems(loopViewThree, threeList);
if (curSelectedList.size() > 2) {
curSelectedList.set(2, threeList.get(0));
} else {
curSelectedList.add(2, threeList.get(0));
}
loopViewOne.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(String item, int index) {
selectOneIndex = index;
curSelectedList.set(0, item);
childMap = map.getMap(item);
ReadableMapKeySetIterator childIterator = childMap.keySetIterator();
twoList.clear();
while (childIterator.hasNextKey()) {
String key = childIterator.nextKey();
twoList.add(key);
}
checkItems(loopViewTwo, twoList);
curSelectedList.set(1, twoList.get(0));
array = childMap.getArray(twoList.get(0));
threeList.clear();
threeList = arrayToList(array);
checkItems(loopViewThree, threeList);
curSelectedList.set(2, threeList.get(0));
if (onSelectedListener != null) {
onSelectedListener.onSelected(curSelectedList);
}
}
});
loopViewTwo.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(String item, int index) {
selectTwoIndex = index;
array = childMap.getArray(item);
threeList.clear();
threeList = arrayToList(array);
checkItems(loopViewThree, threeList);
curSelectedList.set(0, oneList.get(selectOneIndex));
curSelectedList.set(1, item);
curSelectedList.set(2, threeList.get(0));
if (onSelectedListener != null) {
onSelectedListener.onSelected(curSelectedList);
}
}
});
loopViewThree.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(String item, int index) {
curSelectedList.set(0, oneList.get(selectOneIndex));
curSelectedList.set(1, twoList.get(selectTwoIndex));
curSelectedList.set(2, item);
if (onSelectedListener != null) {
onSelectedListener.onSelected(curSelectedList);
}
}
});
break;
case "Array":
setRow(2);
loopViewOne.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(String item, int index) {
selectOneIndex = index;
array = map.getArray(item);
twoList = arrayToList(array);
checkItems(loopViewTwo, twoList);
curSelectedList.set(0, item);
curSelectedList.set(1, twoList.get(0));
if (onSelectedListener != null) {
onSelectedListener.onSelected(curSelectedList);
}
}
});
array = map.getArray(oneList.get(0));
twoList = arrayToList(array);
checkItems(loopViewTwo, twoList);
curSelectedList.add(1, twoList.get(0));
loopViewTwo.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(String item, int index) {
curSelectedList.set(0, oneList.get(selectOneIndex));
curSelectedList.set(1, item);
if (onSelectedListener != null) {
onSelectedListener.onSelected(curSelectedList);
}
}
});
break;
default:
break;
}
}
private ArrayList<String> arrayToList(ReadableArray array) {
try {
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
String values = "";
switch (array.getType(i).name()) {
case "Boolean":
values = String.valueOf(array.getBoolean(i));
break;
case "Number":
try {
values = String.valueOf(array.getInt(i));
} catch (Exception e) {
values = String.valueOf(array.getDouble(i));
}
break;
case "String":
values = array.getString(i);
break;
}
list.add(values);
}
return list;
} catch (Exception e) {
return null;
}
}
public void setSelectValue(String[] selectValue, final ArrayList<String> curSelectedList) {
if (curRow <= selectValue.length) {
String[] values = Arrays.copyOf(selectValue, curRow);
selectValues(values, curSelectedList);
} else {
switch (selectValue.length) {
case 1:
if (loopViewOne.hasItem(selectValue[0])) {
selectOneIndex = loopViewOne.getItemPosition(selectValue[0]);
loopViewOne.setSelectedPosition(selectOneIndex);
curSelectedList.set(0, loopViewOne.getIndexItem(selectOneIndex));
} else {
loopViewOne.setSelectedPosition(0);
curSelectedList.set(0, loopViewOne.getIndexItem(0));
}
switch (curRow) {
case 3:
childMap = map.getMap(oneList.get(selectOneIndex));
ReadableMapKeySetIterator childIterator = childMap.keySetIterator();
twoList.clear();
while (childIterator.hasNextKey()) {
String key = childIterator.nextKey();
twoList.add(key);
}
loopViewTwo.setItems(twoList);
loopViewTwo.setSelectedPosition(0);
curSelectedList.set(1, loopViewTwo.getIndexItem(0));
array = childMap.getArray(twoList.get(0));
threeList.clear();
threeList = arrayToList(array);
loopViewThree.setItems(threeList);
loopViewThree.setSelectedPosition(0);
curSelectedList.set(2, loopViewThree.getIndexItem(0));
break;
case 2:
array = map.getArray(oneList.get(selectOneIndex));
twoList = arrayToList(array);
loopViewTwo.setItems(twoList);
loopViewTwo.setSelectedPosition(0);
curSelectedList.set(1, loopViewTwo.getIndexItem(0));
break;
}
break;
case 2:
switch (curRow) {
case 3:
if (loopViewOne.hasItem(selectValue[0])) {
selectOneIndex = loopViewOne.getItemPosition(selectValue[0]);
loopViewOne.setSelectedPosition(selectOneIndex);
curSelectedList.set(0, loopViewOne.getIndexItem(selectOneIndex));
} else {
loopViewOne.setSelectedPosition(0);
curSelectedList.set(0, loopViewOne.getIndexItem(0));
}
childMap = map.getMap(oneList.get(selectOneIndex));
ReadableMapKeySetIterator childIterator = childMap.keySetIterator();
twoList.clear();
while (childIterator.hasNextKey()) {
String key = childIterator.nextKey();
twoList.add(key);
}
loopViewTwo.setItems(twoList);
if (loopViewTwo.hasItem(selectValue[1])) {
selectTwoIndex = loopViewTwo.getItemPosition(selectValue[1]);
loopViewTwo.setSelectedPosition(selectTwoIndex);
curSelectedList.set(1, loopViewTwo.getIndexItem(selectTwoIndex));
} else {
loopViewTwo.setSelectedPosition(0);
curSelectedList.set(1, loopViewTwo.getIndexItem(0));
}
array = childMap.getArray(twoList.get(selectTwoIndex));
threeList.clear();
threeList = arrayToList(array);
loopViewThree.setItems(threeList);
loopViewThree.setSelectedPosition(0);
curSelectedList.set(2, loopViewThree.getIndexItem(0));
break;
}
break;
default:
break;
}
}
}
private void selectValues(String[] values, final ArrayList<String> curSelectedList) {
switch (values.length) {
case 3:
if (loopViewOne.hasItem(values[0])) {
selectOneIndex = loopViewOne.getItemPosition(values[0]);
loopViewOne.setSelectedPosition(selectOneIndex);
curSelectedList.set(0, loopViewOne.getIndexItem(selectOneIndex));
} else {
loopViewOne.setSelectedPosition(0);
curSelectedList.set(0, loopViewOne.getIndexItem(0));
}
childMap = map.getMap(oneList.get(selectOneIndex));
ReadableMapKeySetIterator childIterator = childMap.keySetIterator();
twoList.clear();
while (childIterator.hasNextKey()) {
String key = childIterator.nextKey();
twoList.add(key);
}
loopViewTwo.setItems(twoList);
if (loopViewTwo.hasItem(values[1])) {
selectTwoIndex = loopViewTwo.getItemPosition(values[1]);
loopViewTwo.setSelectedPosition(selectTwoIndex);
curSelectedList.set(1, loopViewTwo.getIndexItem(selectTwoIndex));
} else {
loopViewTwo.setSelectedPosition(0);
curSelectedList.set(1, loopViewTwo.getIndexItem(0));
}
array = childMap.getArray(twoList.get(selectTwoIndex));
threeList.clear();
threeList = arrayToList(array);
loopViewThree.setItems(threeList);
if (loopViewThree.hasItem(values[2])) {
int selectThreeIndex = loopViewThree.getItemPosition(values[2]);
loopViewThree.setSelectedPosition(selectThreeIndex);
curSelectedList.set(2, loopViewThree.getIndexItem(selectThreeIndex));
} else {
loopViewThree.setSelectedPosition(0);
curSelectedList.set(2, loopViewThree.getIndexItem(0));
}
break;
case 2:
if (loopViewOne.hasItem(values[0])) {
selectOneIndex = loopViewOne.getItemPosition(values[0]);
loopViewOne.setSelectedPosition(selectOneIndex);
curSelectedList.set(0, loopViewOne.getIndexItem(selectOneIndex));
} else {
loopViewOne.setSelectedPosition(0);
curSelectedList.set(0, loopViewOne.getIndexItem(0));
}
array = map.getArray(oneList.get(selectOneIndex));
twoList = arrayToList(array);
loopViewTwo.setItems(twoList);
if (loopViewTwo.hasItem(values[1])) {
selectTwoIndex = loopViewTwo.getItemPosition(values[1]);
loopViewTwo.setSelectedPosition(selectTwoIndex);
curSelectedList.set(1, loopViewTwo.getIndexItem(selectTwoIndex));
} else {
loopViewTwo.setSelectedPosition(0);
curSelectedList.set(1, loopViewTwo.getIndexItem(0));
}
break;
default:
break;
}
}
public void setIsLoop(boolean isLoop) {
if (!isLoop) {
loopViewOne.setNotLoop();
loopViewTwo.setNotLoop();
loopViewThree.setNotLoop();
}
}
public void setOnSelectListener(OnSelectedListener listener) {
this.onSelectedListener = listener;
}
}
package com.beefe.picker.view;
import java.util.TimerTask;
final class SmoothScrollTimerTask extends TimerTask {
int realTotalOffset;
int realOffset;
int offset;
final LoopView loopView;
SmoothScrollTimerTask(LoopView loopview, int offset) {
this.loopView = loopview;
this.offset = offset;
realTotalOffset = Integer.MAX_VALUE;
realOffset = 0;
}
@Override
public final void run() {
if (realTotalOffset == Integer.MAX_VALUE) {
realTotalOffset = offset;
}
realOffset = (int) ((float) realTotalOffset * 0.1F);
if (realOffset == 0) {
if (realTotalOffset < 0) {
realOffset = -1;
} else {
realOffset = 1;
}
}
if (Math.abs(realTotalOffset) <= 0) {
loopView.cancelFuture();
loopView.handler.sendEmptyMessage(MessageHandler.WHAT_ITEM_SELECTED);
} else {
loopView.totalScrollY = loopView.totalScrollY + realOffset;
loopView.handler.sendEmptyMessage(MessageHandler.WHAT_INVALIDATE_LOOP_VIEW);
realTotalOffset = realTotalOffset - realOffset;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromXDelta="0"
android:fromYDelta="100%"
android:toXDelta="0"
android:toYDelta="0" />
<!--<alpha-->
<!--android:fromAlpha="0.5"-->
<!--android:duration="500"-->
<!--android:toAlpha="1.0"-->
<!--/>-->
</set>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:duration="300"
android:toXDelta="0"
android:toYDelta="100%" />
<!--<alpha-->
<!--android:fromAlpha="1.0"-->
<!--android:duration="800"-->
<!--android:toAlpha="0.5"-->
<!--/>-->
</set>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:id="@+id/pickerViewAloneLayout"
android:layout_height="match_parent">
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.beefe.picker.view.LoopView
android:id="@+id/loopViewOne"
android:layout_width="0dp"
android:layout_weight="1.0"
android:layout_height="match_parent" />
<com.beefe.picker.view.LoopView
android:id="@+id/loopViewTwo"
android:layout_width="0dp"
android:layout_weight="1.0"
android:layout_height="match_parent" />
<com.beefe.picker.view.LoopView
android:id="@+id/loopViewThree"
android:layout_width="0dp"
android:layout_weight="1.0"
android:layout_height="match_parent" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000">
<RelativeLayout
android:id="@+id/pickerParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/barLayout" />
<RelativeLayout
android:id="@+id/barLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/pickerLayout">
<TextView
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:padding="9dp" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="9dp" />
<TextView
android:id="@+id/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:padding="9dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/pickerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<com.beefe.picker.view.PickerViewLinkage
android:id="@+id/pickerViewLinkage"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.beefe.picker.view.PickerViewAlone
android:id="@+id/pickerViewAlone"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
<resources>
<string name="app_name">react-native-picker</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="PopAnim">
<item name="android:windowEnterAnimation">@anim/popup_enter</item>
<item name="android:windowExitAnimation">@anim/popup_exit</item>
</style>
</resources>
\ No newline at end of file
......@@ -50,7 +50,23 @@ class PickerTest extends Component {
}
_onPressHandle() {
this.picker.toggle();
Picker.init({
pickerData: createDateData(),
selectedValue: ['2015年', '12月', '12日'],
onPickerConfirm: pickedValue => {
alert(JSON.stringify(pickedValue));
console.log(pickedValue);
},
onPickerCancel: pickedValue => {
alert(JSON.stringify(pickedValue));
console.log(pickedValue);
},
onPickerSelect: pickedValue => {
alert(JSON.stringify(pickedValue));
console.log(pickedValue);
}
});
Picker.show();
}
render() {
......@@ -59,18 +75,6 @@ class PickerTest extends Component {
<TouchableOpacity style={{marginTop: 20}} onPress={this._onPressHandle.bind(this)}>
<Text>Click Me</Text>
</TouchableOpacity>
<Picker
ref={picker => this.picker = picker}
style={{height: 260}}
showDuration={300}
showMask={true}
pickerData={createDateData()}
selectedValue={['2015年', '12月', '12日']}
onPickerDone={(pickedValue) => {
alert(JSON.stringify(pickedValue));
console.log(pickedValue);
}}
/>
</View>
);
}
......
......@@ -8,6 +8,6 @@
"dependencies": {
"react": "15.0.2",
"react-native": "^0.26.1",
"react-native-picker": "^3.0.3"
"react-native-picker": "beefe/react-native-picker"
}
}
'use strict';
import React, {Component, PropTypes} from 'react';
import {
StyleSheet,
View,
Text,
Animated,
Platform,
Dimensions,
PickerIOS
NativeModules,
NativeAppEventEmitter
} from 'react-native';
import PickerAndroid from 'react-native-picker-android';
let Picker = Platform.OS === 'ios' ? PickerIOS : PickerAndroid;
let PickerItem = Picker.Item;
let {width, height} = Dimensions.get('window');
const longSide = width > height ? width : height;
const shortSide = width > height ? height : width;
export default class PickerAny extends Component {
static propTypes = {
style: View.propTypes.style,
pickerElevation: PropTypes.number,
pickerBtnText: PropTypes.string,
pickerCancelBtnText: PropTypes.string,
pickerBtnStyle: Text.propTypes.style,
pickerTitle: PropTypes.string,
pickerTitleStyle: Text.propTypes.style,
pickerToolBarStyle: View.propTypes.style,
showMask: PropTypes.bool,
showDuration: PropTypes.number,
pickerData: PropTypes.any.isRequired,
selectedValue: PropTypes.any.isRequired,
onPickerDone: PropTypes.func,
onPickerCancel: PropTypes.func,
onValueChange: PropTypes.func
let ios = Platform.OS === 'ios';
let android = Platform.OS === 'android';
let Picker = NativeModules.BEEPickerManager;
export default {
init(options){
let opt = {
isLoop: false,
pickerConfirmBtnText: '确认',
pickerCancelBtnText: '取消',
pickerTitleText: '请选择',
pickerBg: [196, 199, 206, 1],
pickerToolBarBg: [232, 232, 232, 1],
pickerTitleColor: [20, 20, 20, 1],
pickerCancelBtnColor: [1, 186, 245, 1],
pickerConfirmBtnColor: [1, 186, 245, 1],
onPickerConfirm(){},
onPickerCancel(){},
onPickerSelect(){},
...options
};
static defaultProps = {
style: {
width: width
},
pickerBtnText: 'Done',
pickerCancelBtnText: 'Cancel',
showMask: false,
showDuration: 300,
onPickerDone: ()=>{},
onPickerCancel: ()=>{},
onValueChange: ()=>{}
let fnConf = {
confirm: opt.onPickerConfirm,
cancel: opt.onPickerCancel,
select: opt.onPickerSelect
};
constructor(props, context){
super(props, context);
}
componentWillMount(){
this.state = this._getStateFromProps(this.props);
}
componentWillReceiveProps(newProps){
let newState = this._getStateFromProps(newProps);
this.setState(newState);
}
shouldComponentUpdate(nextProps, nextState, context){
return true;
}
_getStateFromProps(props){
//the pickedValue must looks like [wheelone's, wheeltwo's, ...]
//this.state.selectedValue may be the result of the first pickerWheel
let {pickerData, selectedValue} = props;
let pickerStyle = pickerData.constructor === Array ? 'parallel' : 'cascade';
let firstWheelData;
let firstPickedData;
let secondPickedData;
let secondWheelData;
let secondPickedDataIndex;
let thirdWheelData;
let thirdPickedDataIndex;
let cascadeData = {};
let slideAnim = (this.state && this.state.slideAnim ? this.state.slideAnim : new Animated.Value(-height));
if(pickerStyle === 'parallel'){
//compatible single wheel sence
if(selectedValue.constructor !== Array){
selectedValue = [selectedValue];
}
if(pickerData[0].constructor !== Array){
pickerData = [pickerData];
}
}
else if(pickerStyle === 'cascade'){
//only support three stage
firstWheelData = Object.keys(pickerData);
firstPickedData = props.selectedValue[0];
secondPickedData = props.selectedValue[1];
cascadeData = this._getCascadeData(pickerData, selectedValue, firstPickedData, secondPickedData, true);
}
//save picked data
this.pickedValue = JSON.parse(JSON.stringify(selectedValue));
this.pickerStyle = pickerStyle;
return {
...props,
pickerData,
selectedValue,
//list of first wheel data
firstWheelData,
//first wheel selected value
firstPickedData,
slideAnim,
//list of second wheel data and pickedDataIndex
secondWheelData: cascadeData.secondWheelData,
secondPickedDataIndex: cascadeData.secondPickedDataIndex,
//third wheel selected value and pickedDataIndex
thirdWheelData: cascadeData.thirdWheelData,
thirdPickedDataIndex: cascadeData.thirdPickedDataIndex
};
}
_slideUp(){
this._isMoving = true;
Animated.timing(
this.state.slideAnim,
{
toValue: 0,
duration: this.state.showDuration,
}
).start((evt) => {
if(evt.finished) {
this._isMoving = false;
this._isPickerShow = true;
}
});
}
_slideDown(){
this._isMoving = true;
Animated.timing(
this.state.slideAnim,
{
toValue: -height,
duration: this.state.showDuration,
}
).start((evt) => {
if(evt.finished) {
this._isMoving = false;
this._isPickerShow = false;
}
});
}
_toggle(){
if(this._isMoving) {
Picker._init(opt);
if(this.inited){
return;
}
if(this._isPickerShow) {
this._slideDown();
}
else{
this._slideUp();
}
}
toggle(){
this._toggle();
}
show(){
if(!this._isPickerShow){
this._slideUp();
}
}
hide(){
if(this._isPickerShow){
this._slideDown();
}
}
isPickerShow(){
return this._isPickerShow;
}
this.inited = true;
_prePressHandle(callback){
this.pickerWheel.moveUp();
NativeAppEventEmitter.addListener('pickerEvent', event => {
if(ios){
fnConf[event['type']](event['selectedValue']);
}
_nextPressHandle(callback){
this.pickerWheel.moveDown();
}
_pickerCancel(){
this._toggle();
this.state.onPickerCancel();
else if(android){
for (let i in event){
typeof fnConf[i] === 'function' && fnConf[i](event[i]);
}
_pickerFinish(){
this._toggle();
this.state.onPickerDone(this.pickedValue);
}
_renderParallelWheel(pickerData){
return pickerData.map((item, index) => {
return (
<View style={styles.pickerWheel} key={index}>
<Picker
selectedValue={this.state.selectedValue[index]}
onValueChange={value => {
this.pickedValue.splice(index, 1, value);
//do not set state to another object!! why?
// this.setState({
// selectedValue: this.pickedValue
// });
this.setState({
selectedValue: JSON.parse(JSON.stringify(this.pickedValue))
});
this.state.onValueChange(JSON.parse(JSON.stringify(this.pickedValue)), index);
}} >
{item.map((value, index) => (
<PickerItem
key={index}
value={value}
label={value.toString()}
/>)
)}
</Picker>
</View>
);
});
}
_getCascadeData(pickerData, pickedValue, firstPickedData, secondPickedData, onInit){
let secondWheelData;
let secondPickedDataIndex;
let thirdWheelData;
let thirdPickedDataIndex;
//only support two and three stage
for(let key in pickerData){
//two stage
if(pickerData[key].constructor === Array){
secondWheelData = pickerData[firstPickedData];
if(onInit){
secondWheelData.forEach(function(v, k){
if(v === pickedValue[1]){
secondPickedDataIndex = k;
}
}.bind(this));
}
else{
secondPickedDataIndex = 0;
}
break;
}
//three stage
else{
secondWheelData = Object.keys(pickerData[firstPickedData]);
if(onInit){
secondWheelData.forEach(function(v, k){
if(v === pickedValue[1]){
secondPickedDataIndex = k;
}
}.bind(this));
}
else{
secondPickedDataIndex = 0;
}
thirdWheelData = pickerData[firstPickedData][secondPickedData];
if(onInit){
thirdWheelData.forEach(function(v, k){
if(v === pickedValue[2]){
thirdPickedDataIndex = k;
}
})
}
else{
thirdPickedDataIndex = 0;
}
break;
}
}
},
return {
secondWheelData,
secondPickedDataIndex,
thirdWheelData,
thirdPickedDataIndex
}
}
show(){
Picker.show();
},
_renderCascadeWheel(pickerData){
let thirdWheel = this.state.thirdWheelData && (
<View style={styles.pickerWheel}>
<Picker
ref={'thirdWheel'}
selectedValue={this.state.thirdPickedDataIndex}
onValueChange={(index) => {
this.pickedValue.splice(2, 1, this.state.thirdWheelData[index]);
this.setState({
thirdPickedDataIndex: index,
selectedValue: 'wheel3'+index
});
this.state.onValueChange(JSON.parse(JSON.stringify(this.pickedValue)), 2);
}} >
{this.state.thirdWheelData.map((value, index) => (
<PickerItem
key={index}
value={index}
label={value.toString()}
/>)
)}
</Picker>
</View>
);
hide(){
Picker.hide();
},
return (
<View style={[styles.pickerWrap, {width: this.state.style.width || width}]}>
<View style={styles.pickerWheel}>
<Picker
ref={'firstWheel'}
selectedValue={this.state.firstPickedData}
onValueChange={value => {
let secondWheelData = Object.keys(pickerData[value]);
let cascadeData = this._getCascadeData(pickerData, this.pickedValue, value, secondWheelData[0]);
//when onPicked, this.pickedValue will pass to the parent
//when firstWheel changed, second and third will also change
if(cascadeData.thirdWheelData){
this.pickedValue.splice(0, 3, value, cascadeData.secondWheelData[0], cascadeData.thirdWheelData[0]);
toggle(){
this.isPickerShow(show => {
if(show){
this.hide();
}
else{
this.pickedValue.splice(0, 2, value, cascadeData.secondWheelData[0]);
this.show();
}
this.setState({
selectedValue: 'wheel1'+value,
firstPickedData: value,
secondWheelData: cascadeData.secondWheelData,
secondPickedDataIndex: 0,
thirdWheelData: cascadeData.thirdWheelData,
thirdPickedDataIndex: 0
});
this.state.onValueChange(JSON.parse(JSON.stringify(this.pickedValue)), 0);
this.refs.secondWheel && this.refs.secondWheel.moveTo && this.refs.secondWheel.moveTo(0);
this.refs.thirdWheel && this.refs.thirdWheel.moveTo && this.refs.thirdWheel.moveTo(0);
}} >
{this.state.firstWheelData.map((value, index) => (
<PickerItem
key={index}
value={value}
label={value.toString()}
/>)
)}
</Picker>
</View>
<View style={styles.pickerWheel}>
<Picker
ref={'secondWheel'}
selectedValue={this.state.secondPickedDataIndex}
onValueChange={(index) => {
let thirdWheelData = pickerData[this.state.firstPickedData][this.state.secondWheelData[index]];
if(thirdWheelData){
this.pickedValue.splice(1, 2, this.state.secondWheelData[index], thirdWheelData[0]);
}
else{
this.pickedValue.splice(1, 1, this.state.secondWheelData[index]);
}
},
this.setState({
secondPickedDataIndex: index,
thirdWheelData,
thirdPickedDataIndex: 0,
selectedValue: 'wheel2'+index
isPickerShow(fn){
Picker.isPickerShow(hide => {
fn(!hide);
});
this.state.onValueChange(JSON.parse(JSON.stringify(this.pickedValue)), 1);
this.refs.thirdWheel && this.refs.thirdWheel.moveTo && this.refs.thirdWheel.moveTo(0);
}} >
{this.state.secondWheelData.map((value, index) => (
<PickerItem
key={index}
value={index}
label={value.toString()}
/>)
)}
</Picker>
</View>
{thirdWheel}
</View>
);
}
_renderWheel(pickerData){
let wheel = null;
if(this.pickerStyle === 'parallel'){
wheel = this._renderParallelWheel(pickerData);
}
else if(this.pickerStyle === 'cascade'){
wheel = this._renderCascadeWheel(pickerData);
}
return wheel;
}
render(){
let mask = this.state.showMask ? (
<View style={styles.mask} >
<Text style={{width: width, height: height}} onPress={this._pickerCancel.bind(this)}></Text>
</View>
) : null;
return (
<Animated.View style={[styles.picker, {
elevation: this.state.pickerElevation,
width: longSide,
height: this.state.showMask ? height : this.state.style.height,
bottom: this.state.slideAnim
}]}>
{mask}
<View style={[styles.pickerBox, this.state.style]}>
<View style={[styles.pickerToolbar, this.state.pickerToolBarStyle, {width: this.state.style.width || width}]}>
<View style={styles.pickerCancelBtn}>
<Text style={[styles.pickerFinishBtnText, this.state.pickerBtnStyle]}
onPress={this._pickerCancel.bind(this)}>{this.state.pickerCancelBtnText}</Text>
</View>
<Text style={[styles.pickerTitle, this.state.pickerTitleStyle]} numberOfLines={1}>
{this.state.pickerTitle}
</Text>
<View style={styles.pickerFinishBtn}>
<Text style={[styles.pickerFinishBtnText, this.state.pickerBtnStyle]}
onPress={this._pickerFinish.bind(this)}>{this.state.pickerBtnText}</Text>
</View>
</View>
<View style={[styles.pickerWrap, {width: this.state.style.width || width}]}>
{this._renderWheel(this.state.pickerData)}
</View>
</View>
</Animated.View>
);
}
};
\ No newline at end of file
let styles = StyleSheet.create({
picker: {
position: 'absolute',
bottom: 0,
left: 0,
backgroundColor: 'transparent',
},
pickerBox: {
position: 'absolute',
bottom: 0,
left: 0,
backgroundColor: '#bdc0c7'
},
mask: {
position: 'absolute',
top: 0,
backgroundColor: 'transparent',
height: height,
width: width
},
pickerWrap: {
flexDirection: 'row'
},
pickerWheel: {
flex: 1
},
pickerToolbar: {
height: 30,
backgroundColor: '#e6e6e6',
flexDirection: 'row',
borderTopWidth: 1,
borderBottomWidth: 1,
borderColor: '#c3c3c3',
alignItems: 'center'
},
pickerBtnView: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center'
},
pickerMoveBtn: {
color: '#149be0',
fontSize: 16,
marginLeft: 20
},
pickerCancelBtn: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
marginLeft: 20
},
pickerTitle: {
flex: 4,
color: 'black',
textAlign: 'center'
},
pickerFinishBtn: {
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-end',
alignItems: 'center',
marginRight: 20
},
pickerFinishBtnText: {
fontSize: 16,
color: '#149be0'
}
});
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
17D41E591D7EE0CA0031415E /* RCTBEEPickerManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17D41E581D7EE0CA0031415E /* RCTBEEPickerManager.h */; };
17D41E5B1D7EE0CA0031415E /* RCTBEEPickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D41E5A1D7EE0CA0031415E /* RCTBEEPickerManager.m */; };
17D41E631D7EE0EE0031415E /* BzwPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D41E621D7EE0EE0031415E /* BzwPicker.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
17D41E531D7EE0CA0031415E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
17D41E591D7EE0CA0031415E /* RCTBEEPickerManager.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
17D41E551D7EE0CA0031415E /* libRCTBEEPickerManager.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTBEEPickerManager.a; sourceTree = BUILT_PRODUCTS_DIR; };
17D41E581D7EE0CA0031415E /* RCTBEEPickerManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTBEEPickerManager.h; sourceTree = "<group>"; };
17D41E5A1D7EE0CA0031415E /* RCTBEEPickerManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTBEEPickerManager.m; sourceTree = "<group>"; };
17D41E611D7EE0EE0031415E /* BzwPicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BzwPicker.h; sourceTree = "<group>"; };
17D41E621D7EE0EE0031415E /* BzwPicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BzwPicker.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
17D41E521D7EE0CA0031415E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
17D41E4C1D7EE0CA0031415E = {
isa = PBXGroup;
children = (
17D41E571D7EE0CA0031415E /* RCTBEEPickerManager */,
17D41E561D7EE0CA0031415E /* Products */,
);
sourceTree = "<group>";
};
17D41E561D7EE0CA0031415E /* Products */ = {
isa = PBXGroup;
children = (
17D41E551D7EE0CA0031415E /* libRCTBEEPickerManager.a */,
);
name = Products;
sourceTree = "<group>";
};
17D41E571D7EE0CA0031415E /* RCTBEEPickerManager */ = {
isa = PBXGroup;
children = (
17D41E611D7EE0EE0031415E /* BzwPicker.h */,
17D41E621D7EE0EE0031415E /* BzwPicker.m */,
17D41E581D7EE0CA0031415E /* RCTBEEPickerManager.h */,
17D41E5A1D7EE0CA0031415E /* RCTBEEPickerManager.m */,
);
path = RCTBEEPickerManager;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
17D41E541D7EE0CA0031415E /* RCTBEEPickerManager */ = {
isa = PBXNativeTarget;
buildConfigurationList = 17D41E5E1D7EE0CA0031415E /* Build configuration list for PBXNativeTarget "RCTBEEPickerManager" */;
buildPhases = (
17D41E511D7EE0CA0031415E /* Sources */,
17D41E521D7EE0CA0031415E /* Frameworks */,
17D41E531D7EE0CA0031415E /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = RCTBEEPickerManager;
productName = RCTBEEPickerManager;
productReference = 17D41E551D7EE0CA0031415E /* libRCTBEEPickerManager.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
17D41E4D1D7EE0CA0031415E /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0720;
ORGANIZATIONNAME = "MFHJ-DZ-001-417";
TargetAttributes = {
17D41E541D7EE0CA0031415E = {
CreatedOnToolsVersion = 7.2.1;
};
};
};
buildConfigurationList = 17D41E501D7EE0CA0031415E /* Build configuration list for PBXProject "RCTBEEPickerManager" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 17D41E4C1D7EE0CA0031415E;
productRefGroup = 17D41E561D7EE0CA0031415E /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
17D41E541D7EE0CA0031415E /* RCTBEEPickerManager */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
17D41E511D7EE0CA0031415E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
17D41E5B1D7EE0CA0031415E /* RCTBEEPickerManager.m in Sources */,
17D41E631D7EE0EE0031415E /* BzwPicker.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
17D41E5C1D7EE0CA0031415E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
17D41E5D1D7EE0CA0031415E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
17D41E5F1D7EE0CA0031415E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../../react-native/React/**",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
17D41E601D7EE0CA0031415E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../../react-native/React/**",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
17D41E501D7EE0CA0031415E /* Build configuration list for PBXProject "RCTBEEPickerManager" */ = {
isa = XCConfigurationList;
buildConfigurations = (
17D41E5C1D7EE0CA0031415E /* Debug */,
17D41E5D1D7EE0CA0031415E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
17D41E5E1D7EE0CA0031415E /* Build configuration list for PBXNativeTarget "RCTBEEPickerManager" */ = {
isa = XCConfigurationList;
buildConfigurations = (
17D41E5F1D7EE0CA0031415E /* Debug */,
17D41E601D7EE0CA0031415E /* Release */,
);
defaultConfigurationIsVisible = 0;
};
/* End XCConfigurationList section */
};
rootObject = 17D41E4D1D7EE0CA0031415E /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:RCTBEEPickerManager.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "17D41E541D7EE0CA0031415E"
BuildableName = "libRCTBEEPickerManager.a"
BlueprintName = "RCTBEEPickerManager"
ReferencedContainer = "container:RCTBEEPickerManager.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "17D41E541D7EE0CA0031415E"
BuildableName = "libRCTBEEPickerManager.a"
BlueprintName = "RCTBEEPickerManager"
ReferencedContainer = "container:RCTBEEPickerManager.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "17D41E541D7EE0CA0031415E"
BuildableName = "libRCTBEEPickerManager.a"
BlueprintName = "RCTBEEPickerManager"
ReferencedContainer = "container:RCTBEEPickerManager.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>RCTBEEPickerManager.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>17D41E541D7EE0CA0031415E</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
//
// BzwPicker.h
// PickerView
//
// Created by Bao on 15/12/14.
// Copyright © 2015年 Microlink. All rights reserved.
//
#import <UIKit/UIKit.h>
#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
#define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
typedef void(^backBolock)(NSDictionary * );
@interface BzwPicker : UIView<UIPickerViewDataSource,UIPickerViewDelegate>
@property (strong,nonatomic)UIPickerView *pick;
@property(nonatomic,copy)backBolock bolock;
@property (strong, nonatomic) NSDictionary *pickerDic;//一开始进来的字典
@property (strong, nonatomic) NSArray *provinceArray;//省、市
@property (strong, nonatomic) NSArray *cityArray;//市,县
@property (strong, nonatomic) NSArray *townArray;//县,区
@property (strong, nonatomic) NSDictionary *selectedDic;//3级联动时候用到的
@property (strong,nonatomic)NSArray *selectArry;//2级联动时候用的
@property (strong,nonatomic)UIButton *leftBtn;//取消
@property (strong,nonatomic)UIButton *rightBtn;
@property(strong,nonatomic)NSString *leftStr;
@property(strong,nonatomic)NSString *centStr;
@property(strong,nonatomic)NSString *rightStr;
//用来判断进来的类型
@property(strong,nonatomic)id value;
@property(assign,nonatomic)BOOL Correlation;//判断有没有没有关联
@property(nonatomic,strong)NSString *numberCorrela;//关联是2行 还是3行
@property(nonatomic,strong)NSArray *noCorreArry;
//创建一个数组来传递返回的值
@property(nonatomic,strong)NSMutableArray *backArry;
@property(assign,nonatomic)BOOL noArryElementBool;
//创建一个数组 接收进来的选择Value
@property(strong,nonatomic)NSArray *selectValueArry;
-(instancetype)initWithFrame:(CGRect)frame dic:(NSDictionary *)dic leftStr:(NSString *)leftStr centerStr:(NSString *)centerStr rightStr:(NSString *)rightStr topbgColor:(NSArray *)topbgColor bottombgColor:(NSArray *)bottombgColor leftbtnbgColor:(NSArray *)leftbtnbgColor rightbtnbgColor:(NSArray *)rightbtnbgColor centerbtnColor:(NSArray *)centerbtnColor selectValueArry:(NSArray *)selectValueArry;
@end
//
// BzwPicker.m
// PickerView
//
// Created by Bao on 15/12/14.
// Copyright © 2015年 Microlink. All rights reserved.
//
#import "BzwPicker.h"
@implementation BzwPicker
-(instancetype)initWithFrame:(CGRect)frame dic:(NSDictionary *)dic leftStr:(NSString *)leftStr centerStr:(NSString *)centerStr rightStr:(NSString *)rightStr topbgColor:(NSArray *)topbgColor bottombgColor:(NSArray *)bottombgColor leftbtnbgColor:(NSArray *)leftbtnbgColor rightbtnbgColor:(NSArray *)rightbtnbgColor centerbtnColor:(NSArray *)centerbtnColor selectValueArry:(NSArray *)selectValueArry
{
self = [super initWithFrame:frame];
if (self)
{
self.backArry=[[NSMutableArray alloc]init];
self.selectValueArry=selectValueArry;
self.pickerDic=dic;
self.leftStr=leftStr;
self.rightStr=rightStr;
self.centStr=centerStr;
[self getStyle];
[self getnumStyle];
dispatch_async(dispatch_get_main_queue(), ^{
[self makeuiWith:topbgColor With:bottombgColor With:leftbtnbgColor With:rightbtnbgColor With:centerbtnColor];
[self selectRow];
});
}
return self;
}
-(void)makeuiWith:(NSArray *)topbgColor With:(NSArray *)bottombgColor With:(NSArray *)leftbtnbgColor With:(NSArray *)rightbtnbgColor With:(NSArray *)centerbtnColor
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.frame.size.width, 40)];
view.backgroundColor = [UIColor cyanColor];
[self addSubview:view];
self.leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.leftBtn.frame = CGRectMake(10, 5, 50, 30);
[self.leftBtn setTitle:self.leftStr forState:UIControlStateNormal];
[self.leftBtn setFont:[UIFont systemFontOfSize:16]];
self.leftBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[self.leftBtn addTarget:self action:@selector(cancleAction) forControlEvents:UIControlEventTouchUpInside];
[self.leftBtn setTitleColor:[self colorWith:leftbtnbgColor] forState:UIControlStateNormal];
[view addSubview:self.leftBtn];
view.backgroundColor=[self colorWith:topbgColor];
self.rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.rightBtn.frame = CGRectMake(view.frame.size.width-60,5, 50, 30);
[self.rightBtn setTitle:self.rightStr forState:UIControlStateNormal];
self.rightBtn.contentHorizontalAlignment=UIControlContentHorizontalAlignmentRight;
[self.rightBtn setTitleColor:[self colorWith:rightbtnbgColor] forState:UIControlStateNormal];
[view addSubview:self.rightBtn];
[self.rightBtn setFont:[UIFont systemFontOfSize:16]];
[self.rightBtn addTarget:self action:@selector(cfirmAction) forControlEvents:UIControlEventTouchUpInside];
UILabel *cenLabel=[[UILabel alloc]initWithFrame:CGRectMake(view.frame.size.width/2-25, 5, 50, 30)];
[cenLabel setFont:[UIFont systemFontOfSize:16]];
cenLabel.text=self.centStr;
[cenLabel setTextColor:[self colorWith:centerbtnColor]];
[view addSubview:cenLabel];
self.pick = [[UIPickerView alloc] initWithFrame:CGRectMake(-15, 40, self.frame.size.width+15, self.frame.size.height - 40)];
self.pick.delegate = self;
self.pick.dataSource = self;
self.pick.showsSelectionIndicator=YES;
[self addSubview:self.pick];
self.pick.backgroundColor=[self colorWith:bottombgColor];
if (_Correlation) {
NSDictionary *dic=(NSDictionary *)self.value;
self.selectedDic =[dic objectForKey:[self.provinceArray objectAtIndex:0]];
}
}
//返回显示的列数
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
if (_Correlation) {
//这里是关联的
if ([_numberCorrela isEqualToString:@"three"]) {
return 3;
}else if ([_numberCorrela isEqualToString:@"two"]){
return 2;
}
}
//这里是不关联的
if (_noArryElementBool) {
return 1;
}else{
return self.noCorreArry.count;
}
}
//返回当前列显示的行数
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (_Correlation) {
if (component == 0) {
return self.provinceArray.count;
} else if (component == 1) {
return self.cityArray.count;
} else {
return self.townArray.count;
}
}
NSLog(@"%@",[self.noCorreArry objectAtIndex:component]);
if (self.noCorreArry.count==1) {
return [self.noCorreArry count];
}else
{
if (_noArryElementBool) {
return [self.noCorreArry count];
}
return [[self.noCorreArry objectAtIndex:component] count];
}
}
#pragma mark Picker Delegate Methods
//返回当前行的内容,此处是将数组中数值添加到滚动的那个显示栏上
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (_Correlation) {
if (component == 0) {
return [NSString stringWithFormat:@"%@",[self.provinceArray objectAtIndex:row]];
} else if (component == 1) {
return [NSString stringWithFormat:@"%@",[self.cityArray objectAtIndex:row]];
} else {
return [NSString stringWithFormat:@"%@",[self.townArray objectAtIndex:row]];
}
}else{
if (_noArryElementBool) {
return [NSString stringWithFormat:@"%@",[self.noCorreArry objectAtIndex:row]];
}else{
return [NSString stringWithFormat:@"%@",[[self.noCorreArry objectAtIndex:component] objectAtIndex:row]];
}
}
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
if (_Correlation) {
return 110;
}else{
if (_noArryElementBool) {
//表示一个数组 特殊情况
return 110;
}else{
NSArray *arry=(NSArray *)self.value;
return SCREEN_WIDTH/arry.count;
}
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
[self.backArry removeAllObjects];
if (_Correlation) {
//这里是关联的
if ([_numberCorrela isEqualToString:@"three"]) {
if (component == 0)
{
NSDictionary *dic=(NSDictionary *)self.value;
NSInteger setline=[_pick selectedRowInComponent:0];
if (setline) {
self.selectedDic =[dic objectForKey:[self.provinceArray objectAtIndex:setline]];
}else{
self.selectedDic =[dic objectForKey:[self.provinceArray objectAtIndex:row]];
}
if (self.selectedDic) {
self.cityArray = [self.selectedDic allKeys];
}
else
{
self.cityArray = nil;
}
if (self.cityArray.count > 0)
{
NSInteger oldrow=[self.pick selectedRowInComponent:1];
if (oldrow) {
self.townArray=[self.selectedDic objectForKey:[self.cityArray objectAtIndex:oldrow]];
}else{
row=0;
self.townArray=[self.selectedDic objectForKey:[self.cityArray objectAtIndex:row]];
}
}
else
{
self.townArray = nil;
}
}
[pickerView selectedRowInComponent:1];
[pickerView reloadAllComponents];
[pickerView selectedRowInComponent:2];
if (component == 1)
{
if (self.selectedDic && self.cityArray.count > 0)
{
self.townArray=[self.selectedDic objectForKey:[self.cityArray objectAtIndex:row]];
}
else
{
self.townArray = nil;
}
[pickerView selectRow:1 inComponent:2 animated:YES];
}
[pickerView reloadComponent:2];
}else if ([_numberCorrela isEqualToString:@"two"]){
if (component == 0)
{
NSDictionary *dic=(NSDictionary *)self.value;
self.selectArry =[dic objectForKey:[self.provinceArray objectAtIndex:row]];
if (self.selectArry.count>0) {
self.cityArray = self.selectArry;
}
else
{
self.cityArray = nil;
}
}
[pickerView selectedRowInComponent:1];
[pickerView reloadComponent:1];
}
}
//返回选择的值就可以了
if (_Correlation) {
//有关联的,里面有分两种情况
if ([_numberCorrela isEqualToString:@"three"]) {
NSString *a=[self.provinceArray objectAtIndex:[self.pick selectedRowInComponent:0]];
NSString *b=[self.cityArray objectAtIndex:[self.pick selectedRowInComponent:1]];
NSString *c=[self.townArray objectAtIndex:[self.pick selectedRowInComponent:2]];
[self.backArry addObject:a];
[self.backArry addObject:b];
[self.backArry addObject:c];
}else if ([_numberCorrela isEqualToString:@"two"]){
NSString *a=[self.provinceArray objectAtIndex:[self.pick selectedRowInComponent:0]];
NSString *b=[self.cityArray objectAtIndex:[self.pick selectedRowInComponent:1]];
NSLog(@"%@---%@",a,b);
[self.backArry addObject:a];
[self.backArry addObject:b];
}
}else
{
if (_noArryElementBool) {
[self.backArry addObject:[self.noCorreArry objectAtIndex:row]];
}else{
//无关联的,直接给三个选项就行
for (NSInteger i=0; i<self.noCorreArry.count; i++) {
NSArray *eachAry=self.noCorreArry[i];
[self.backArry addObject:[eachAry objectAtIndex:[self.pick selectedRowInComponent:i]]];
}
}
}
NSMutableDictionary *dic=[[NSMutableDictionary alloc]init];
[dic setValue:self.backArry forKey:@"selectedValue"];
[dic setValue:@"select" forKey:@"type"];
self.bolock(dic);
}
//判断进来的类型是那种
-(void)getStyle
{
self.value=[self.pickerDic objectForKey:@"pickerData"];
if ([self.value isKindOfClass:[NSArray class]]) {
_Correlation=NO;
}else if ([self.value isKindOfClass:[NSDictionary class]]){
_Correlation=YES;
NSDictionary *dic=(NSDictionary *)self.value;
NSArray *dicValue=[dic allValues];
id fistObjct=[dicValue firstObject];
if ([fistObjct isKindOfClass:[NSDictionary class]]) {
_numberCorrela=@"three";
}else if ([fistObjct isKindOfClass:[NSArray class]]){
_numberCorrela=@"two";
}
}
}
-(void)getnumStyle{
if (_Correlation) {
//这里是关联的
if ([_numberCorrela isEqualToString:@"three"]) {
//省 市
NSDictionary *dic=(NSDictionary *)self.value;
self.provinceArray = [dic allKeys];
if (self.provinceArray.count > 0) {
self.cityArray = [[dic objectForKey:[self.provinceArray objectAtIndex:0]] allKeys];
}
if (self.cityArray.count > 0) {
self.townArray = [[dic objectForKey:[self.provinceArray objectAtIndex:0]] objectForKey:[self.cityArray objectAtIndex:0]];
}
}else if ([_numberCorrela isEqualToString:@"two"]){
NSDictionary *dic=(NSDictionary *)self.value;
self.provinceArray = [dic allKeys];
self.cityArray=[dic objectForKey:[self.provinceArray objectAtIndex:0]];
}
}else
{
//这里是不关联的
self.noCorreArry=(NSArray *)self.value;
id noArryElement=[self.noCorreArry firstObject];
if ([noArryElement isKindOfClass:[NSArray class]]) {
_noArryElementBool=NO;
}else{
_noArryElementBool=YES;
}
}
}
//按了取消按钮
-(void)cancleAction
{
NSMutableDictionary *dic=[[NSMutableDictionary alloc]init];
if (self.backArry.count>0) {
[dic setValue:self.backArry forKey:@"selectedValue"];
[dic setValue:@"cancel" forKey:@"type"];
self.bolock(dic);
}else{
[self getNOselectinfo];
[dic setValue:self.backArry forKey:@"selectedValue"];
[dic setValue:@"cancel" forKey:@"type"];
self.bolock(dic);
}
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:.2f animations:^{
[self setFrame:CGRectMake(0, SCREEN_HEIGHT, SCREEN_WIDTH, 250)];
}];
});
}
//按了确定按钮
-(void)cfirmAction
{
NSMutableDictionary *dic=[[NSMutableDictionary alloc]init];
if (self.backArry.count>0) {
[dic setValue:self.backArry forKey:@"selectedValue"];
[dic setValue:@"confirm" forKey:@"type"];
self.bolock(dic);
}else{
[self getNOselectinfo];
[dic setValue:self.backArry forKey:@"selectedValue"];
[dic setValue:@"confirm" forKey:@"type"];
self.bolock(dic);
}
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:.2f animations:^{
[self setFrame:CGRectMake(0, SCREEN_HEIGHT, SCREEN_WIDTH, 250)];
}];
});
}
-(void)selectRow
{
if (_Correlation) {
//关联的一开始的默认选择行数
NSDictionary *dic=(NSDictionary *)self.value;
if ([_numberCorrela isEqualToString:@"three"]) {
[self selectValueThree:dic];
}else if ([_numberCorrela isEqualToString:@"two"]){
[self selectValueTwo:dic];
}
}else{
//一行的时候
[self selectValueOne];
}
}
//三行时候的选择哪个的逻辑
-(void)selectValueThree:(NSDictionary *)dic
{
NSString *selectStr=[NSString stringWithFormat:@"%@",self.selectValueArry.firstObject];
for (NSInteger i=0; i<self.provinceArray.count; i++) {
NSString *str=[NSString stringWithFormat:@"%@",[self.provinceArray objectAtIndex:i]];
if ([selectStr isEqualToString:str]) {
[_pick selectRow:i inComponent:0 animated:NO];
break;
}
}
NSArray *selecityAry = [[dic objectForKey:selectStr] allKeys];
if (selecityAry.count>0) {
self.cityArray=selecityAry;
}
NSString *selectStrTwo;
if (self.selectValueArry.count>1) {
selectStrTwo=[NSString stringWithFormat:@"%@",self.selectValueArry[1]];
}
for (NSInteger i=0; i<self.cityArray.count; i++) {
NSString *str=[NSString stringWithFormat:@"%@",[self.cityArray objectAtIndex:i]];
if ([selectStrTwo isEqualToString:str]) {
[_pick selectRow:i inComponent:1 animated:NO];
break;
}
}
NSDictionary *threeDic=[dic objectForKey:[self.selectValueArry firstObject]];
if (threeDic) {
self.selectedDic=threeDic;
if (self.selectValueArry.count>1) {
NSArray *arry =[threeDic objectForKey:[self.selectValueArry objectAtIndex:1]];
if (arry.count>0) {
self.townArray=arry;
}
}
}
NSString *selectStrThree;
if (self.selectValueArry.count>2) {
selectStrThree=[NSString stringWithFormat:@"%@",self.selectValueArry[2]];
}
for (NSInteger i=0; i<self.townArray.count; i++) {
NSString *str=[NSString stringWithFormat:@"%@",[self.townArray objectAtIndex:i]];
if ([selectStrThree isEqualToString:str]) {
[_pick selectRow:i inComponent:2 animated:NO];
break;
}
}
[_pick reloadAllComponents];
}
//两行时候的选择哪个的逻辑
-(void)selectValueTwo:(NSDictionary *)dic
{
NSString *selectStr=[NSString stringWithFormat:@"%@",self.selectValueArry.firstObject];
for (NSInteger i=0; i<self.provinceArray.count; i++) {
NSString *str=[NSString stringWithFormat:@"%@",[self.provinceArray objectAtIndex:i]];
if ([selectStr isEqualToString:str]) {
[_pick selectRow:i inComponent:0 animated:NO];
break;
}
}
if ([dic objectForKey:selectStr]) {
self.cityArray =[dic objectForKey:selectStr];
}
NSString *selectTwoStr;
if (self.selectValueArry.count>1) {
selectTwoStr =[NSString stringWithFormat:@"%@",[self.selectValueArry objectAtIndex:1]];
}
for (NSInteger i=0; i<self.cityArray.count; i++) {
NSString *str=[NSString stringWithFormat:@"%@",[self.cityArray objectAtIndex:i]];
if ([selectTwoStr isEqualToString:str]) {
[_pick selectRow:i inComponent:1 animated:NO];
break;
}
}
[_pick reloadAllComponents];
}
//一行时候的选择哪个的逻辑
-(void)selectValueOne
{
if (_noArryElementBool) {
//这里表示数组里面就只有一个数组 比较特殊的情况[]
NSString *selectStr;
if (self.selectValueArry.count>0) {
selectStr=[NSString stringWithFormat:@"%@",[self.selectValueArry firstObject]];
}
for (NSInteger i=0; i<self.noCorreArry.count; i++) {
NSString *str=[NSString stringWithFormat:@"%@",[self.noCorreArry objectAtIndex:i]];
if ([selectStr isEqualToString:str]) {
[_pick selectRow:i inComponent:0 animated:NO];
break;
}
}
}else{
//这里就比较复杂了 [[],[],[]]
if (self.selectValueArry.count>0) {
if (self.selectValueArry.count>self.noCorreArry.count) {
for (NSInteger i=0; i<self.noCorreArry.count; i++) {
NSString *selectStr=[NSString stringWithFormat:@"%@",[self.selectValueArry objectAtIndex:i]];
NSArray *arry=[self.noCorreArry objectAtIndex:i];
for (NSInteger j=0; j<arry.count; j++) {
NSString *str=[NSString stringWithFormat:@"%@",[arry objectAtIndex:j]];
if ([selectStr isEqualToString:str]) {
[_pick selectRow:j inComponent:i animated:YES];
break;
}
}
}
}else{
for (NSInteger i=0; i<self.selectValueArry.count; i++) {
NSString *selectStr=[NSString stringWithFormat:@"%@",[self.selectValueArry objectAtIndex:i]];
NSArray *arry=[self.noCorreArry objectAtIndex:i];
for (NSInteger j=0; j<arry.count; j++) {
NSString *str=[NSString stringWithFormat:@"%@",[arry objectAtIndex:j]];
if ([selectStr isEqualToString:str]) {
[_pick selectRow:j inComponent:i animated:YES];
break;
}
}
}
}
}
}
}
-(void)getNOselectinfo
{
if (_Correlation) {
//有关联的,里面有分两种情况
if ([_numberCorrela isEqualToString:@"three"]) {
NSString *a=[self.provinceArray objectAtIndex:[self.pick selectedRowInComponent:0]];
NSString *b=[self.cityArray objectAtIndex:[self.pick selectedRowInComponent:1]];
NSString *c=[self.townArray objectAtIndex:[self.pick selectedRowInComponent:2]];
[self.backArry addObject:a];
[self.backArry addObject:b];
[self.backArry addObject:c];
}else if ([_numberCorrela isEqualToString:@"two"]){
NSString *a=[self.provinceArray objectAtIndex:[self.pick selectedRowInComponent:0]];
NSString *b=[self.cityArray objectAtIndex:[self.pick selectedRowInComponent:1]];
NSLog(@"%@---%@",a,b);
[self.backArry addObject:a];
[self.backArry addObject:b];
}
}else
{
if (_noArryElementBool) {
if (self.selectValueArry.count>0) {
NSString *selectStr=[NSString stringWithFormat:@"%@",[self.selectValueArry firstObject]];
[self.backArry addObject:selectStr];
}else{
[self.backArry addObject:[self.noCorreArry objectAtIndex:0]];
}
}else{
//无关联的,直接给三个选项就行
for (NSInteger i=0; i<self.noCorreArry.count; i++) {
NSArray *eachAry=self.noCorreArry[i];
[self.backArry addObject:[eachAry objectAtIndex:[self.pick selectedRowInComponent:i]]];
}
}
}
}
-(UIColor *)colorWith:(NSArray *)colorArry
{
NSString *ColorA=[NSString stringWithFormat:@"%@",colorArry[0]];
NSString *ColorB=[NSString stringWithFormat:@"%@",colorArry[1]];
NSString *ColorC=[NSString stringWithFormat:@"%@",colorArry[2]];
NSString *ColorD=[NSString stringWithFormat:@"%@",colorArry[3]];
UIColor *color=[[UIColor alloc]initWithRed:[ColorA integerValue]/255.0 green:[ColorB integerValue]/255.0 blue:[ColorC integerValue]/255.0 alpha:[ColorD floatValue]];
return color;
}
@end
//
// RCTBEEPickerManager.h
// RCTBEEPickerManager
//
// Created by MFHJ-DZ-001-417 on 16/9/6.
// Copyright © 2016年 MFHJ-DZ-001-417. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h"
@interface RCTBEEPickerManager : NSObject<RCTBridgeModule>
@end
//
// RCTBEEPickerManager.m
// RCTBEEPickerManager
//
// Created by MFHJ-DZ-001-417 on 16/9/6.
// Copyright © 2016年 MFHJ-DZ-001-417. All rights reserved.
//
#import "RCTBEEPickerManager.h"
#import "BzwPicker.h"
#import "RCTEventDispatcher.h"
@interface RCTBEEPickerManager()
@property(nonatomic,strong)BzwPicker *pick;
@end
@implementation RCTBEEPickerManager
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(_init:(NSDictionary *)indic){
UIViewController *result = nil;
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
if (window.windowLevel != UIWindowLevelNormal)
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow * tmpWin in windows)
{
if (tmpWin.windowLevel == UIWindowLevelNormal)
{
window = tmpWin;
break;
}
}
}
UIView *frontView = [[window subviews] objectAtIndex:0];
id nextResponder = [frontView nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]])
result = nextResponder;
else
result = window.rootViewController;
NSString *pickerConfirmBtnText=indic[@"pickerConfirmBtnText"];
NSString *pickerCancelBtnText=indic[@"pickerCancelBtnText"];
NSString *pickerTitleText=indic[@"pickerTitleText"];
NSArray *pickerConfirmBtnColor=indic[@"pickerConfirmBtnColor"];
NSArray *pickerCancelBtnColor=indic[@"pickerCancelBtnColor"];
NSArray *pickerTitleColor=indic[@"pickerTitleColor"];
NSArray *pickerToolBarBg=indic[@"pickerToolBarBg"];
NSArray *pickerBg=indic[@"pickerBg"];
NSArray *selectArry=indic[@"selectedValue"];
id pickerData=indic[@"pickerData"];
NSMutableDictionary *dataDic=[[NSMutableDictionary alloc]init];
dataDic[@"pickerData"]=pickerData;
[result.view.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isKindOfClass:[BzwPicker class]]) {
dispatch_async(dispatch_get_main_queue(), ^{
[obj removeFromSuperview];
});
}
}];
self.pick=[[BzwPicker alloc]initWithFrame:CGRectMake(0, SCREEN_HEIGHT, SCREEN_WIDTH, 250) dic:dataDic leftStr:pickerCancelBtnText centerStr:pickerTitleText rightStr:pickerConfirmBtnText topbgColor:pickerToolBarBg bottombgColor:pickerBg leftbtnbgColor:pickerCancelBtnColor rightbtnbgColor:pickerConfirmBtnColor centerbtnColor:pickerTitleColor selectValueArry:selectArry];
_pick.bolock=^(NSDictionary *backinfoArry){
dispatch_async(dispatch_get_main_queue(), ^{
[self.bridge.eventDispatcher sendAppEventWithName:@"pickerEvent" body:backinfoArry];
});
};
dispatch_async(dispatch_get_main_queue(), ^{
[result.view addSubview:_pick];
[UIView animateWithDuration:.3 animations:^{
[_pick setFrame:CGRectMake(0, SCREEN_HEIGHT-250, SCREEN_WIDTH, 250)];
}];
});
}
RCT_EXPORT_METHOD(show){
if (self.pick) {
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:.3 animations:^{
[_pick setFrame:CGRectMake(0, SCREEN_HEIGHT-250, SCREEN_WIDTH, 250)];
}];
});
}return;
}
RCT_EXPORT_METHOD(hide){
if (self.pick) {
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:.3 animations:^{
[_pick setFrame:CGRectMake(0, SCREEN_HEIGHT, SCREEN_WIDTH, 250)];
}];
});
}return;
}
RCT_EXPORT_METHOD(isPickerShow:(RCTResponseSenderBlock)getBack){
if (self.pick) {
CGFloat pickY=_pick.frame.origin.y;
if (pickY==SCREEN_HEIGHT) {
getBack(@[@YES]);
}else
{
getBack(@[@NO]);
}
}else{
getBack(@[@"picker不存在"]);
}
}
@end
{
"name": "react-native-picker",
"version": "3.0.5",
"description": "react-native-picker",
"version": "4.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/beefe/react-native-picker.git"
"url": "git@github.com:beefe/react-native-picker.git"
},
"keywords": [
"react-native",
"picker"
],
"author": {
"name": "zooble",
"email": "wenliang.web@gmail.com"
},
"dependencies": {
"react-native-picker-android": "~1.0.3"
},
"engines": {
"node": ">=4"
},
"license": "ISC",
"bugs": {
"url": "https://github.com/beefe/react-native-picker/issues"
},
"homepage": "https://github.com/beefe/react-native-picker#readme"
"author": "zooble",
"license": "MIT"
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment