| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package com.taobao.weex.appfram.pickers; |
| |
| import android.content.Context; |
| import android.content.DialogInterface; |
| import android.graphics.Color; |
| import android.os.Build; |
| import android.support.annotation.NonNull; |
| import android.support.annotation.Nullable; |
| import android.support.v7.app.AlertDialog; |
| import android.util.TypedValue; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.AdapterView; |
| import android.widget.ArrayAdapter; |
| import android.widget.Button; |
| import android.widget.Checkable; |
| import android.widget.ListView; |
| import android.widget.TextView; |
| |
| import com.taobao.weex.annotation.JSMethod; |
| import com.taobao.weex.bridge.JSCallback; |
| import com.taobao.weex.common.WXModule; |
| import com.taobao.weex.common.WXThread; |
| import com.taobao.weex.utils.WXResourceUtils; |
| import com.taobao.weex.utils.WXViewUtils; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Created by moxun on 16/10/27. |
| */ |
| |
| public class WXPickersModule extends WXModule { |
| |
| private static final String SUCCESS = "success"; |
| private static final String CANCEL = "cancel"; |
| private static final String ERROR = "error"; |
| |
| private static final String RESULT = "result"; |
| private static final String DATA = "data"; |
| |
| private static final String KEY_VALUE = "value"; |
| private static final String KEY_INDEX = "index"; |
| private static final String KEY_TITLE = "title"; |
| private static final String KEY_MAX = "max"; |
| private static final String KEY_MIN = "min"; |
| private static final String KEY_ITEMS = "items"; |
| |
| private static final String KEY_TITLE_COLOR = "titleColor"; |
| private static final String KEY_CANCEL_TITLE_COLOR = "cancelTitleColor"; |
| private static final String KEY_CONFIRM_TITLE = "confirmTitle"; |
| private static final String KEY_CANCEL_TITLE = "cancelTitle"; |
| private static final String KEY_CONFIRM_TITLE_COLOR = "confirmTitleColor"; |
| private static final String KEY_TITLE_BACKGROUND_COLOR = "titleBackgroundColor"; |
| private static final String KEY_TEXT_COLOR = "textColor"; |
| private static final String KEY_SELECTION_COLOR = "selectionColor"; |
| |
| private int selected; |
| |
| @JSMethod |
| public void pick(Map<String, Object> options, JSCallback callback) { |
| List<String> items = safeConvert(getOption(options, KEY_ITEMS, new ArrayList<String>())); |
| try { |
| performSinglePick(items, options, callback); |
| } catch (Throwable throwable) { |
| throwable.printStackTrace(); |
| } |
| } |
| |
| @JSMethod |
| public void pickDate(Map<String, Object> options, JSCallback callback) { |
| performPickDate(options, callback); |
| } |
| |
| @JSMethod |
| public void pickTime(Map<String, Object> options, JSCallback callback) { |
| performPickTime(options, callback); |
| } |
| |
| private List<String> safeConvert(List src) { |
| List<String> result = new ArrayList<>(src.size()); |
| for (Object obj : src) { |
| result.add(String.valueOf(obj)); |
| } |
| return result; |
| } |
| |
| private <T> T getOption(Map<String, Object> options, String key, T defValue) { |
| Object value = options.get(key); |
| if (value == null) { |
| return defValue; |
| } else { |
| try { |
| return (T) value; |
| } catch (Exception e) { |
| e.printStackTrace(); |
| return defValue; |
| } |
| } |
| } |
| |
| private int getColor(Map<String, Object> options, String key, int defValue) { |
| Object value = getOption(options, key, null); |
| if (value == null) { |
| return defValue; |
| } |
| return WXResourceUtils.getColor(value.toString(), defValue); |
| } |
| |
| private void performPickTime(Map<String, Object> options, final JSCallback callback) { |
| String value = getOption(options, KEY_VALUE, ""); |
| DatePickerImpl.pickTime( |
| mWXSDKInstance.getContext(), |
| value, |
| new DatePickerImpl.OnPickListener() { |
| @Override |
| public void onPick(boolean set, @Nullable String result) { |
| if (set) { |
| Map<String, Object> ret = new HashMap<>(2); |
| ret.put(RESULT, SUCCESS); |
| ret.put(DATA, result); |
| callback.invoke(ret); |
| } else { |
| Map<String, Object> ret = new HashMap<>(2); |
| ret.put(RESULT, CANCEL); |
| ret.put(DATA, null); |
| callback.invoke(ret); |
| } |
| } |
| }, |
| options); |
| } |
| |
| private void performPickDate(Map<String, Object> options, final JSCallback callback) { |
| String value = getOption(options, KEY_VALUE, ""); |
| String max = getOption(options, KEY_MAX, ""); |
| String min = getOption(options, KEY_MIN, ""); |
| DatePickerImpl.pickDate( |
| mWXSDKInstance.getContext(), |
| value, |
| max, |
| min, |
| new DatePickerImpl.OnPickListener() { |
| @Override |
| public void onPick(boolean set, @Nullable String result) { |
| if (set) { |
| Map<String, Object> ret = new HashMap<>(2); |
| ret.put(RESULT, SUCCESS); |
| ret.put(DATA, result); |
| callback.invoke(ret); |
| } else { |
| Map<String, Object> ret = new HashMap<>(2); |
| ret.put(RESULT, CANCEL); |
| ret.put(DATA, null); |
| callback.invoke(ret); |
| } |
| } |
| }, |
| options); |
| |
| } |
| |
| private void performSinglePick(final List<String> items, final Map<String, Object> options, final JSCallback callback) { |
| selected = getOption(options, KEY_INDEX, 0); |
| final int textColor = getColor(options, KEY_TEXT_COLOR, Color.TRANSPARENT); |
| final int selectionColor = getColor(options, KEY_SELECTION_COLOR, Color.TRANSPARENT); |
| final ArrayAdapter adapter = new ArrayAdapter<String>( |
| mWXSDKInstance.getContext(), |
| android.R.layout.simple_list_item_single_choice, |
| items) { |
| @NonNull |
| @Override |
| public View getView(int position, View convertView, @Nullable ViewGroup parent) { |
| View itemView = super.getView(position, convertView, parent); |
| |
| if (itemView != null && itemView instanceof Checkable) { |
| boolean needSelected = position == selected; |
| ((Checkable) itemView).setChecked(needSelected); |
| |
| if (needSelected) { |
| itemView.setBackgroundColor(selectionColor); |
| } else { |
| itemView.setBackgroundColor(Color.TRANSPARENT); |
| } |
| } |
| |
| if (itemView instanceof TextView && textColor != Color.TRANSPARENT) { |
| ((TextView) itemView).setTextColor(textColor); |
| } |
| |
| return itemView; |
| } |
| }; |
| final AlertDialog dialog = new AlertDialog.Builder(mWXSDKInstance.getContext()) |
| .setAdapter(adapter, null) |
| .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| //which == -1 |
| Map<String, Object> ret = new HashMap<>(2); |
| ret.put(RESULT, SUCCESS); |
| ret.put(DATA, selected); |
| callback.invoke(ret); |
| } |
| }) |
| .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| //which == -2 |
| Map<String, Object> ret = new HashMap<>(2); |
| ret.put(RESULT, CANCEL); |
| ret.put(DATA, -1); |
| callback.invoke(ret); |
| } |
| }) |
| .setCustomTitle(makeTitleView(mWXSDKInstance.getContext(), options)) |
| .create(); |
| |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
| //pre create the content view on dialog. |
| //if not , the content view will not be created until dialog.show() called |
| dialog.create(); |
| } |
| |
| final ListView listView = dialog.getListView(); |
| listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { |
| @Override |
| public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
| selected = position; |
| adapter.notifyDataSetChanged(); |
| } |
| }); |
| |
| dialog.getWindow().getDecorView().post(WXThread.secure(new Runnable() { |
| @Override |
| public void run() { |
| Button confirm = dialog.getButton(DialogInterface.BUTTON_POSITIVE); |
| Button cancel = dialog.getButton(DialogInterface.BUTTON_NEGATIVE); |
| |
| if (confirm != null) { |
| String confirmTitle = getOption(options, KEY_CONFIRM_TITLE, null); |
| int confirmColor = getColor(options, KEY_CONFIRM_TITLE_COLOR, Color.TRANSPARENT); |
| |
| if (confirmTitle != null) { |
| confirm.setText(confirmTitle); |
| confirm.setAllCaps(false); |
| } |
| |
| if (confirmColor != Color.TRANSPARENT) { |
| confirm.setTextColor(confirmColor); |
| confirm.setAllCaps(false); |
| } |
| } |
| |
| if (cancel != null) { |
| String cancelTitle = getOption(options, KEY_CANCEL_TITLE, null); |
| int cancelColor = getColor(options, KEY_CANCEL_TITLE_COLOR, Color.TRANSPARENT); |
| |
| if (cancelTitle != null) { |
| cancel.setText(cancelTitle); |
| } |
| |
| if (cancelColor != Color.TRANSPARENT) { |
| cancel.setTextColor(cancelColor); |
| } |
| } |
| } |
| })); |
| |
| dialog.show(); |
| } |
| |
| private TextView makeTitleView(Context context, Map<String, Object> options) { |
| String text = getOption(options, KEY_TITLE, null); |
| if (text == null) { |
| return null; |
| } |
| TextView textView = new TextView(context); |
| textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); |
| textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); |
| int padding = WXViewUtils.dip2px(12); |
| textView.setPadding(padding, padding, padding, padding); |
| textView.getPaint().setFakeBoldText(true); |
| textView.setBackgroundColor(getColor(options, KEY_TITLE_BACKGROUND_COLOR, Color.TRANSPARENT)); |
| textView.setTextColor(getColor(options, KEY_TITLE_COLOR, Color.BLACK)); |
| textView.setText(text); |
| return textView; |
| } |
| } |