package mobi.monaca.framework.nativeui.component;
import static mobi.monaca.framework.nativeui.UIUtil.TAG;
import static mobi.monaca.framework.nativeui.UIUtil.buildOpacity;
import static mobi.monaca.framework.nativeui.UIUtil.dip2px;
import static mobi.monaca.framework.nativeui.UIUtil.updateJSONObject;
import mobi.monaca.framework.nativeui.ComponentEventer;
import mobi.monaca.framework.nativeui.DefaultStyleJSON;
import mobi.monaca.framework.nativeui.UIContext;
import mobi.monaca.framework.nativeui.UIUtil;
import mobi.monaca.framework.nativeui.UIValidator;
import mobi.monaca.framework.nativeui.exception.NativeUIException;
import mobi.monaca.framework.psedo.R;
import mobi.monaca.framework.util.MyLog;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.res.Configuration;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.TextWatcher;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
public class SearchBoxComponent extends ToolbarComponent implements UIContext.OnRotateListener {
protected EditText searchEditText;
protected FrameLayout layout;
protected Button clearButton;
protected ComponentEventer eventer;
protected static final String[] SEARCH_BOX_VALID_KEYS = { "component", "style", "iosStyle", "androidStyle", "id", "event" };
protected static final String[] STYLE_VALID_KEYS = { "visibility", "disable", "opacity", "backgroundColor", "textColor", "placeholder", "focus", "value" };
@Override
public String[] getValidKeys() {
return SEARCH_BOX_VALID_KEYS;
}
public SearchBoxComponent(UIContext context, JSONObject searchBoxJSON) throws NativeUIException, JSONException {
super(context, searchBoxJSON);
UIValidator.validateKey(context, getComponentName() + " style", style, STYLE_VALID_KEYS);
buildEventer();
initView();
style();
try {
searchBoxJSON.put("focus", false);
} catch (JSONException e) {
throw new RuntimeException(e);
}
context.addOnRotateListener(this);
}
private void buildEventer() throws NativeUIException, JSONException {
this.eventer = new ComponentEventer(uiContext, getComponentJSON().optJSONObject("event"));
}
@Override
public void onRotate(int orientation) {
updateWidthForOrientation(orientation);
}
protected void updateWidthForOrientation(int orientation) {
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
searchEditText.setWidth(UIUtil.dip2px(uiContext, 136));
} else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
searchEditText.setWidth(UIUtil.dip2px(uiContext, 80));
}
searchEditText.invalidate();
}
public void updateStyle(JSONObject update) throws NativeUIException {
updateJSONObject(style, update);
style();
}
public JSONObject getStyle() {
// update editTextValue
try {
style.put("value", searchEditText.getText().toString());
} catch (JSONException e) {
Log.w(TAG, "update value failed");
}
return style;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
}
public View getView() {
return layout;
}
protected void initView() {
layout = new FrameLayout(uiContext);
searchEditText = new EditText(uiContext);
searchEditText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER) {
SpannableStringBuilder sp = (SpannableStringBuilder) searchEditText.getText();
String keyword = sp.toString();
eventer.onSearch(searchEditText, keyword);
return true;
}
return false;
}
});
searchEditText.setInputType(InputType.TYPE_CLASS_TEXT);
searchEditText.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
searchEditText.setBackgroundResource(R.drawable.monaca_searchbox_bg);
searchEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
try {
style.put("focus", hasFocus);
} catch (JSONException e) {
MyLog.e(TAG, e.getMessage());
}
}
});
searchEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
clearButton.setVisibility(searchEditText.getText().toString().equals("") ? View.GONE : View.VISIBLE);
}
});
layout.addView(searchEditText);
clearButton = new Button(uiContext);
clearButton.setBackgroundResource(R.drawable.monaca_search_clear);
clearButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
searchEditText.setText("");
searchEditText.requestFocus();
uiContext.showSoftInput(searchEditText);
}
});
Drawable drawable = uiContext.getResources().getDrawable(R.drawable.monaca_search_clear);
FrameLayout.LayoutParams p = new FrameLayout.LayoutParams(drawable.getMinimumWidth(), drawable.getMinimumHeight(), Gravity.RIGHT
| Gravity.CENTER_VERTICAL);
layout.addView(clearButton, p);
}
/*
* style memo: value placeHolder visibility disable textColor opacity
* backgroundColor focus
*/
protected void style() throws NativeUIException {
searchEditText.setText(style.optString("value", ""));
searchEditText.setHint(style.optString("placeHolder", ""));
searchEditText.setVisibility(style.optBoolean("visibility", true) ? View.VISIBLE : View.INVISIBLE);
searchEditText.setEnabled(!style.optBoolean("disable", false));
int color = UIValidator.parseAndValidateColor(uiContext, getComponentName() + " style", "textColor", "#000000", style);
searchEditText.setTextColor(color);
float opacity = UIValidator.parseAndValidateFloat(uiContext, getComponentName() + " style", "opacity", "1.0", style, 0.0f, 1.0f);
int integerOpacity = buildOpacity(opacity);
searchEditText.setTextColor(searchEditText.getTextColors().withAlpha(integerOpacity));
searchEditText.setTextSize(TypedValue.COMPLEX_UNIT_PX, uiContext.getFontSizeFromDip(Component.LABEL_TEXT_DIP));
searchEditText.setWidth(dip2px(uiContext, 65));
if (style.has("backgroundColor")) {
int backgroundColor = UIValidator.parseAndValidateColor(uiContext, getComponentName() + " style", "backgroundColor", "#ffffff", style);
searchEditText.getBackground().setColorFilter(backgroundColor, Mode.MULTIPLY);
}
searchEditText.getBackground().setAlpha(integerOpacity);
clearButton.getBackground().setAlpha(integerOpacity);
searchEditText.setHintTextColor(searchEditText.getHintTextColors().withAlpha(integerOpacity));
updateWidthForOrientation(uiContext.getUIOrientation());
}
@Override
public String getComponentName() {
return "SearchBox";
}
@Override
public JSONObject getDefaultStyle() {
return DefaultStyleJSON.searchBox();
}
}