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;
/**
* Author: heng
*
* Created by heng on 16/9/5.
*
* Edited by heng on 16/9/22.
* 1. PopupWindow height : full screen -> assignation
* 2. Added pickerToolBarHeight support
*/
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 TEXT_BAR_HEIGHT = "pickerToolBarHeight";
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 curSelectedList = new ArrayList<>();
private RelativeLayout barLayout;
private TextView cancelTV;
private TextView titleTV;
private TextView confirmTV;
private PickerViewLinkage pickerViewLinkage;
private PickerViewAlone pickerViewAlone;
private int pickerViewHeight;
private int barViewHeight;
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);
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);
if (options.hasKey(TEXT_BAR_HEIGHT)) {
try {
barViewHeight = options.getInt(TEXT_BAR_HEIGHT);
} catch (Exception e) {
barViewHeight = (int) options.getDouble(TEXT_BAR_HEIGHT);
}
} else {
barViewHeight = (int) (activity.getResources().getDisplayMetrics().density * 40);
}
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
barViewHeight);
barLayout.setLayoutParams(params);
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;
}
}
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);
}
}
}
ReadableArray pickerData = options.getArray(PICKER_DATA);
String name = pickerData.getType(0).name();
switch (name) {
case "Map":
pickerViewLinkage.setVisibility(View.VISIBLE);
pickerViewAlone.setVisibility(View.GONE);
pickerViewLinkage.setPickerData(pickerData, curSelectedList);
pickerViewLinkage.setIsLoop(isLoop);
if (options.hasKey(PICKER_BG_COLOR)) {
pickerViewLinkage.setBackgroundColor(Color.argb(pickerColor[3], pickerColor[0], pickerColor[1], pickerColor[2]));
}
pickerViewLinkage.setOnSelectListener(new OnSelectedListener() {
@Override
public void onSelected(ArrayList selectedList) {
curSelectedList = selectedList;
commonEvent(EVENT_KEY_SELECTED);
}
});
pickerViewLinkage.setSelectValue(selectValue, curSelectedList);
pickerViewHeight = pickerViewLinkage.getViewHeight();
break;
default:
pickerViewAlone.setVisibility(View.VISIBLE);
pickerViewLinkage.setVisibility(View.GONE);
pickerViewAlone.setPickerData(pickerData, curSelectedList);
pickerViewAlone.setIsLoop(isLoop);
if (options.hasKey(PICKER_BG_COLOR)) {
pickerViewAlone.setBackgroundColor(Color.argb(pickerColor[3], pickerColor[0], pickerColor[1], pickerColor[2]));
}
pickerViewAlone.setOnSelectedListener(new OnSelectedListener() {
@Override
public void onSelected(ArrayList selectedList) {
curSelectedList = selectedList;
commonEvent(EVENT_KEY_SELECTED);
}
});
pickerViewAlone.setSelectValue(selectValue, curSelectedList);
pickerViewHeight = pickerViewAlone.getViewHeight();
break;
}
if (popupWindow == null) {
int height = barViewHeight + pickerViewHeight;
popupWindow = new PopupWindow(WindowManager.LayoutParams.MATCH_PARENT, height);
popupWindow.setBackgroundDrawable(new ColorDrawable());
popupWindow.setAnimationStyle(R.style.PopAnim);
}
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);
}
}