Пример #1
0
 private void addSaveButton(ViewGroup parentView, Activity activity) {
   View view =
       activity.getLayoutInflater().inflate(R.layout.form_field_save_button, parentView, true);
   int viewId = View.generateViewId();
   view.setId(viewId);
   view.setOnClickListener((View.OnClickListener) activity);
 }
  private void createSubAssunto(int idAssunto) {
    SubAssunto subAssunto = new SubAssunto(idAssunto);
    ArrayAdapter<Assunto> adapter = getAssuntosAdapterByAssuntoPai(idAssunto);

    if (adapter.getCount() == 0) {
      Toast.makeText(
              this,
              R.string.acompanhamento_estudos_assunto_doesnt_contains_subassuntos,
              Toast.LENGTH_LONG)
          .show();
      return;
    }

    LinearLayout rootLinearLayout =
        (LinearLayout) findViewById(R.id.acompanhamento_estudos_linlyt_subassuntos);
    subAssunto.layoutContainer = new LinearLayout(this);
    subAssunto.layoutContainer.setOrientation(LinearLayout.HORIZONTAL);
    rootLinearLayout.addView(subAssunto.layoutContainer);

    subAssunto.spnSubAssuntos = new Spinner(this);
    subAssunto.spnSubAssuntos.setId(View.generateViewId());
    subAssunto.spnSubAssuntos.setAdapter(adapter);
    subAssunto.spnSubAssuntos.setOnItemSelectedListener(
        new AdapterView.OnItemSelectedListener() {
          @Override
          public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
            int startingIndexKey =
                calcularIndiceParaLimparSubAssuntos((Assunto) adapterView.getSelectedItem());
            clearSubAssuntos(startingIndexKey);
          }

          @Override
          public void onNothingSelected(AdapterView<?> adapterView) {}
        });
    subAssunto.spnSubAssuntos.setLayoutParams(
        new LinearLayout.LayoutParams(390, LinearLayout.LayoutParams.WRAP_CONTENT));
    subAssunto.layoutContainer.addView(subAssunto.spnSubAssuntos);

    subAssunto.btnExpandirSubAssuntos = new ImageButton(this);
    subAssunto.btnExpandirSubAssuntos.setImageResource(R.drawable.arrow_combo);
    subAssunto.btnExpandirSubAssuntos.setBackgroundColor(Color.TRANSPARENT);
    final int dicPosAssuntoToExpand = dicIdxAndIdSubAssuntos.size();
    subAssunto.btnExpandirSubAssuntos.setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View view) {
            SubAssunto correspondingSubAssunto =
                (SubAssunto) dicIdxAndIdSubAssuntos.get(dicPosAssuntoToExpand);
            int selectedId =
                ((Assunto) correspondingSubAssunto.spnSubAssuntos.getSelectedItem()).getId();
            createSubAssunto(selectedId);
          }
        });
    subAssunto.btnExpandirSubAssuntos.setLayoutParams(
        new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
    subAssunto.layoutContainer.addView(subAssunto.btnExpandirSubAssuntos);

    dicIdxAndIdSubAssuntos.put(dicIdxAndIdSubAssuntos.size(), subAssunto);
  }
Пример #3
0
 /**
  * set id
  *
  * @param view
  */
 public static void setId(View view) {
   if (view != null) {
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
       try { // samsung SM-N9009(4.3) crash here, so protected
         view.setId(View.generateViewId());
       } catch (Exception e) {
         view.setId(generateViewId());
       }
     } else {
       view.setId(generateViewId());
     }
   }
 }
  @SuppressLint("NewApi")
  public static int generateViewId() {

    if (Build.VERSION.SDK_INT < 17) {
      for (; ; ) {
        final int result = sNextGeneratedId.get();
        // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
        int newValue = result + 1;
        if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
        if (sNextGeneratedId.compareAndSet(result, newValue)) {
          return result;
        }
      }
    } else {
      return View.generateViewId();
    }
  }
Пример #5
0
  /**
   * Sets the layout align of subject of this view, the align has four places are left, top, right ,
   * and bottom
   *
   * @param align
   */
  public void setSubjectAlign(int align) {
    if (align != SUBJECT_ALIGN_LEFT
        && align != SUBJECT_ALIGN_TOP
        && align != SUBJECT_ALIGN_RIGHT
        && align != SUBJECT_ALIGN_BOTTOM) return;

    Debug.dumpLog(TAG, "sets layout params for resetting align of subject toolbar");

    int subjectScrollerId = 0;
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
      subjectScrollerId = GenerateIntID.generateViewId();
    else subjectScrollerId = View.generateViewId();

    FrameLayout subjectScroller = null;
    ScrollView.LayoutParams subjectWrapperLp = null;
    RelativeLayout.LayoutParams subjectScrollerLp = null;
    RelativeLayout.LayoutParams contentWrapperLp = null;
    switch (align) {
      case SUBJECT_ALIGN_LEFT:
        subjectScroller = new ScrollView(getContext());
        mSubjectWrapper.setOrientation(LinearLayout.VERTICAL);
        subjectWrapperLp =
            new ScrollView.LayoutParams(
                ScrollView.LayoutParams.WRAP_CONTENT, ScrollView.LayoutParams.MATCH_PARENT);
        subjectScrollerLp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        subjectScrollerLp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        contentWrapperLp =
            new LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        contentWrapperLp.addRule(RIGHT_OF, subjectScrollerId);
        break;
      case SUBJECT_ALIGN_TOP:
        subjectScroller = new HorizontalScrollView(getContext());
        mSubjectWrapper.setOrientation(LinearLayout.HORIZONTAL);
        subjectWrapperLp =
            new ScrollView.LayoutParams(
                ScrollView.LayoutParams.MATCH_PARENT, ScrollView.LayoutParams.WRAP_CONTENT);
        subjectScrollerLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        subjectScrollerLp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        subjectScrollerLp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        contentWrapperLp =
            new LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        contentWrapperLp.addRule(RelativeLayout.BELOW, subjectScrollerId);
        break;
      case SUBJECT_ALIGN_RIGHT:
        subjectScroller = new ScrollView(getContext());
        mSubjectWrapper.setOrientation(LinearLayout.VERTICAL);
        subjectWrapperLp =
            new ScrollView.LayoutParams(
                ScrollView.LayoutParams.WRAP_CONTENT, ScrollView.LayoutParams.MATCH_PARENT);
        subjectScrollerLp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        subjectScrollerLp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        contentWrapperLp =
            new LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        contentWrapperLp.addRule(LEFT_OF, subjectScrollerId);
        break;
      case SUBJECT_ALIGN_BOTTOM:
        subjectScroller = new HorizontalScrollView(getContext());
        mSubjectWrapper.setOrientation(LinearLayout.HORIZONTAL);
        subjectWrapperLp =
            new ScrollView.LayoutParams(
                ScrollView.LayoutParams.MATCH_PARENT, ScrollView.LayoutParams.WRAP_CONTENT);
        subjectScrollerLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        subjectScrollerLp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        contentWrapperLp =
            new LayoutParams(LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        contentWrapperLp.addRule(ABOVE, subjectScrollerId);
        break;
    }

    do {
      if (subjectScroller == null) break;
      if (subjectWrapperLp == null) break;
      if (subjectScrollerLp == null) break;
      if (contentWrapperLp == null) break;

      // release
      if (mSubjectScrollView != null) mSubjectScrollView.removeAllViews();

      // adjust layout
      mSubjectScrollView = subjectScroller;
      mSubjectScrollView.setId(subjectScrollerId);
      mSubjectWrapper.setLayoutParams(subjectWrapperLp);
      mSubjectScrollView.addView(mSubjectWrapper);
      mSubjectScrollView.setLayoutParams(subjectScrollerLp);
      this.addView(mSubjectScrollView);
      mContentWrapper.setLayoutParams(contentWrapperLp);
      if (mContentWrapper.getParent() == null) this.addView(mContentWrapper);

      mSubjectAlign = align;
      this.invalidate();

      Debug.dumpLog(TAG, "resets subject toolbar success");
    } while (false);
  }
Пример #6
0
  public static ScrollView generateTeamLayout(Context context, boolean pit) {
    RelativeLayout layout = new RelativeLayout(context);
    ScrollView scrollView = new ScrollView(context);
    BufferedReader reader =
        new BufferedReader(
            new InputStreamReader(
                context
                    .getResources()
                    .openRawResource(pit ? R.raw.team_config_pit : R.raw.team_config_match)));
    try {
      String line = reader.readLine(); // The version
      Log.d(
          MainActivity.APP_TAG,
          "Loaded " + (pit ? "pit" : "match") + " config file version " + line);
      if (pit) configVersionPit = line;
      else configVersionMatch = line;
      int last = -1;
      while ((line = reader.readLine()) != null) {
        TextView header = null;
        View[] view;
        int idOffset = Integer.MAX_VALUE;
        String[] l;
        if (line.contains(":")) {
          l = line.split(":");
          RelativeLayout.LayoutParams params =
              new RelativeLayout.LayoutParams(
                  RelativeLayout.LayoutParams.WRAP_CONTENT,
                  RelativeLayout.LayoutParams.WRAP_CONTENT);
          header = new TextView(context);
          header.setText(l[1].substring(2));
          header.setTextSize(20f);
          header.setId(idOffset - View.generateViewId());
          if (last != -1) {
            if (l[1].charAt(1) == '0') params.addRule(RelativeLayout.BELOW, last);
            else {
              params.addRule(RelativeLayout.RIGHT_OF, last);
              params.addRule(RelativeLayout.ALIGN_TOP, last);
            }
          }
          header.setPadding(
              header.getPaddingLeft(),
              header.getPaddingTop(),
              header.getPaddingRight() + 20,
              header.getPaddingBottom());
          header.setLayoutParams(params);
          boolean below = false;

          switch (Integer.parseInt(l[1].charAt(0) + "")) {
            case 0: // Checkbox
              view = new View[] {new CheckBox(context)};
              break;
            case 1: // Spinner
              Spinner spinner = new Spinner(context);
              ArrayList<String> l1 = new ArrayList<>();
              l1.add("None");
              l1.addAll(Arrays.asList(l[2].split(",")));
              spinner.setAdapter(
                  new ArrayAdapter<>(context, android.R.layout.simple_spinner_dropdown_item, l1));
              view = new View[] {spinner};
              break;
            case 2:
              { // Number
                EditText editText = new EditText(context);
                editText.setInputType(InputType.TYPE_CLASS_NUMBER);
                editText.setSingleLine();
                editText.setImeOptions(0x00000005); // Next
                view = new View[] {editText};
                break;
              }
            case 3:
              { // Text
                EditText editText = new EditText(context);
                editText.setSingleLine();
                editText.setImeOptions(0x00000005); // Next
                view = new View[] {editText};
                break;
              }
            case 4: // Text for Teams
              AutoCompleteTextView autoCompleteTextView = new AutoCompleteTextView(context);
              autoCompleteTextView.setAdapter(
                  new ArrayAdapter<>(
                      context, android.R.layout.simple_dropdown_item_1line, MainActivity.teamList));
              autoCompleteTextView.setSingleLine();
              autoCompleteTextView.setImeOptions(0x00000005); // Next
              view = new View[] {autoCompleteTextView};
              break;
            case 5:
              { // Multiline field
                EditText editText = new EditText(context);
                editText.setSingleLine(false);
                view = new View[] {editText};
                below = true;
                break;
              }
            case 6:
              { // Number Entry with Plus
                final EditText editText = new EditText(context);
                ImageButton button = new ImageButton(context);
                button.setImageResource(R.drawable.ic_action_new);
                button.setOnClickListener(
                    new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                        if (editText.getText().toString().equals("")) editText.setText("1");
                        else
                          editText.setText(
                              "" + (Integer.parseInt(editText.getText().toString()) + 1));
                      }
                    });
                editText.setInputType(InputType.TYPE_CLASS_NUMBER);
                editText.setSingleLine();
                editText.setImeOptions(0x00000005); // Next
                view = new View[] {editText, button};
                break;
              }
            default:
              Log.e(
                  MainActivity.APP_TAG,
                  "Invalid file format for team config, error at line: " + line);
              return null;
          }

          if (view.length == 1) {
            RelativeLayout.LayoutParams params1 =
                new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            if (below) params1.addRule(RelativeLayout.BELOW, header.getId());
            else {
              params1.addRule(RelativeLayout.ALIGN_TOP, header.getId());
              params1.addRule(RelativeLayout.RIGHT_OF, header.getId());
            }
            view[0].setId(Integer.parseInt(l[0]));
            view[0].setLayoutParams(params1);
          } else {
            for (int i = 0; i < view.length; i++) {
              RelativeLayout.LayoutParams params1 =
                  new RelativeLayout.LayoutParams(
                      RelativeLayout.LayoutParams.WRAP_CONTENT,
                      RelativeLayout.LayoutParams.WRAP_CONTENT);
              if (i == 0) {
                if (below) params1.addRule(RelativeLayout.BELOW, header.getId());
                else {
                  params1.addRule(RelativeLayout.ALIGN_TOP, header.getId());
                  params1.addRule(RelativeLayout.RIGHT_OF, header.getId());
                }
                view[0].setId(Integer.parseInt(l[0]));
                view[0].setLayoutParams(params1);
                continue;
              }
              params1.addRule(RelativeLayout.ALIGN_TOP, view[i - 1].getId());
              params1.addRule(RelativeLayout.RIGHT_OF, view[i - 1].getId());

              view[i].setId(Integer.parseInt(l[0]) + i);
              view[i].setLayoutParams(params1);
            }
          }
        } else {
          RelativeLayout.LayoutParams params =
              new RelativeLayout.LayoutParams(
                  RelativeLayout.LayoutParams.WRAP_CONTENT,
                  RelativeLayout.LayoutParams.WRAP_CONTENT);
          TextView v = new TextView(context);
          v.setText(line);
          v.setTextSize(30f);
          v.setId(idOffset - View.generateViewId());
          if (last != -1) params.addRule(RelativeLayout.BELOW, last);
          v.setLayoutParams(params);
          view = new View[] {v};
        }

        if (header != null) layout.addView(header);
        for (View v : view) layout.addView(v);
        last = view[view.length - 1].getId();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    scrollView.addView(layout);
    return scrollView;
  }
Пример #7
0
 public int getId() {
   if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return generateViewId();
   else return View.generateViewId();
 }
Пример #8
0
  // Set atributtes of XML to View
  @SuppressLint("NewApi")
  protected void setAttributes(AttributeSet attrs) {

    setBackgroundResource(R.drawable.background_checkbox);

    // Set size of view
    setMinimumHeight(Utils.dpToPx(16, getResources()));
    setMinimumWidth(Utils.dpToPx(16, getResources()));

    // Set background Color
    // Color by resource
    int bacgroundColor = attrs.getAttributeResourceValue(ANDROIDXML, "background", -1);
    if (bacgroundColor != -1) {
      setBackgroundColor(getResources().getColor(bacgroundColor));
    } else {
      // Color by hexadecimal
      // Color by hexadecimal
      int background = attrs.getAttributeIntValue(ANDROIDXML, "background", -1);
      if (background != -1) setBackgroundColor(background);
    }

    final boolean check = attrs.getAttributeBooleanValue(MATERIALDESIGNXML, "check", false);
    post(
        new Runnable() {

          @Override
          public void run() {
            setChecked(check);
            setPressed(false);
            changeBackgroundColor(getResources().getColor(android.R.color.transparent));
          }
        });

    checkView = new Check(getContext());
    checkView.setId(View.generateViewId());
    RelativeLayout.LayoutParams params =
        new LayoutParams(Utils.dpToPx(16, getResources()), Utils.dpToPx(16, getResources()));
    params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
    checkView.setLayoutParams(params);
    addView(checkView);

    // Adding text view to checkbox
    int textResource = attrs.getAttributeResourceValue(ANDROIDXML, "text", -1);
    String text = null;

    if (textResource != -1) {
      text = getResources().getString(textResource);
    } else {
      text = attrs.getAttributeValue(ANDROIDXML, "text");
    }

    if (text != null) {
      params.removeRule(RelativeLayout.CENTER_IN_PARENT);
      params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
      TextView textView = new TextView(getContext());
      RelativeLayout.LayoutParams textViewLayoutParams =
          new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
      textViewLayoutParams.addRule(RelativeLayout.RIGHT_OF, checkView.getId());
      textViewLayoutParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
      textViewLayoutParams.setMargins(10, 0, 0, 0);
      textView.setLayoutParams(textViewLayoutParams);
      textView.setText(text);
      textView.setTextSize(12);
      addView(textView);
    }
  }
Пример #9
0
 protected View buildControl() {
   View v = doBuildControl(ControlsMngr.getContext());
   view_id = v.generateViewId();
   v.setId(view_id);
   return v;
 }
Пример #10
0
  public void init(final Context context, AttributeSet attrs, int defStyleAttr) {
    FrameLayout.LayoutParams params =
        new FrameLayout.LayoutParams(
            LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
    textInputLayout = new TextInputLayout(context);
    textInputLayout.setLayoutParams(params);
    String hint = attrs.getAttributeValue(ANDROID_NS, "hint");
    if (hint != null) {
      textInputLayout.setHint(hint);
    }
    editText = new PermissionedEditText(context);
    editText.setSelectionListener(selectionListener);
    editText.setId(View.generateViewId());
    editText.setLayoutParams(params);
    int inputType = attrs.getAttributeIntValue(ANDROID_NS, "inputType", EditorInfo.TYPE_NULL);
    if (inputType != EditorInfo.TYPE_NULL) {
      editText.setInputType(inputType);
    }

    textInputLayout.addView(editText, params);
    addView(textInputLayout);

    overlay = new FrameLayout(context);
    overlay.setLayoutParams(
        new FrameLayout.LayoutParams(
            LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
    //        overlay.setBackgroundColor(Color.BLACK);
    overlay.setBackgroundResource(R.drawable.permission_overlay_bg);
    overlay.setOnTouchListener(
        new OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
              Toast.makeText(
                      getContext(), "This device does not have permission to view this field", 0)
                  .show();
            }
            return true;
          }
        });
    overlay.setVisibility(GONE);
    TextView overlayLabel = new TextView(context);
    overlayLabel.setTextSize(24);
    overlayLabel.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
    overlayLabel.setText(hint + " Unavailable");

    overlay.addView(overlayLabel);
    addView(overlay);

    actionButton = new ImageView(context);
    IconDrawable drawable = new IconDrawable(context, MaterialIcons.md_check);
    drawable.color(Color.GREEN);
    actionButton.setImageDrawable(drawable);
    actionButton.setLayoutParams(new FrameLayout.LayoutParams(100, 100, Gravity.RIGHT));
    actionButton.setOnTouchListener(
        new OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
              case MotionEvent.ACTION_DOWN:
                {
                  ImageView view = (ImageView) v;
                  view.getDrawable().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP);
                  view.invalidate();
                  break;
                }
              case MotionEvent.ACTION_UP:
                if (permissionedTextListener != null) {
                  int aId = 0;
                  if (mPrimaryAction != null) {
                    aId = mPrimaryAction.id;
                  }
                  permissionedTextListener.onAction(aId, PermissionedTextLayout.this);
                }
              case MotionEvent.ACTION_CANCEL:
                {
                  ImageView view = (ImageView) v;
                  view.getDrawable().clearColorFilter();
                  view.invalidate();
                  break;
                }
            }
            return true;
          }
        });
    actionButton.setVisibility(GONE);
    addView(actionButton);
  }
Пример #11
0
/** Created by Andrei on 07/03/14. */
public class SGeneric extends BaseElement
    implements TextView.OnEditorActionListener,
        View.OnClickListener,
        ActionValueNotifierClient,
        ActivityListener,
        Selectable {
  private LinearLayout elementView = null;
  private LinearLayout elementFrame = null;
  private FrameLayout selectorFrame;
  private TextView textView;
  private static EditText editText;
  private static int tv_id = View.generateViewId();
  private String command;
  private Runnable resumeTask = null;

  private String label;
  private String inputType = null;

  private STitleBar titleObj = null;
  private SDescription descriptionObj = null;

  private Object original = null;
  private Object stored = false;

  private Object lastEdit;
  private Object lastLive;

  public SGeneric(
      JSONObject element, LinearLayout layout, MainActivity.TabSectionFragment fragment) {
    super(element, layout, fragment);

    if (element.containsKey("action")) this.command = (String) element.get("action");
    else throw new IllegalArgumentException("SCheckBox has no action defined");

    if (this.element.containsKey("label")) this.label = Utils.localise(element.get("label"));

    if (element.containsKey("default")) this.original = element.get("default");

    if (element.containsKey("inputType")) this.inputType = (String) element.get("inputType");

    /** Add a description element inside our own with the same JSON object */
    if (element.containsKey("description"))
      descriptionObj = new SDescription(element, layout, fragment);

    if (element.containsKey("title")) titleObj = new STitleBar(element, layout, fragment);

    resumeTask =
        new Runnable() {
          @Override
          public void run() {
            try {
              refreshValue();
            } catch (ElementFailureException e) {
              Utils.createElementErrorView(e);
            }
          }
        };

    ActionValueNotifierHandler.register(this);
  }

  @Override
  public View getView() throws ElementFailureException {
    if (elementView != null) return elementView;

    LinearLayout v = new LinearLayout(Utils.mainActivity);
    v.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    v.setOrientation(LinearLayout.VERTICAL);
    elementView = v;

    /** Nesting another element's view in our own for title and description. */
    LinearLayout descriptionFrame = new LinearLayout(Utils.mainActivity);
    LayoutParams dfl = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    descriptionFrame.setOrientation(LinearLayout.VERTICAL);
    final int leftMargin = (int) (2 * Utils.density + 0.5f);
    dfl.setMargins(leftMargin, 0, 0, 0);
    descriptionFrame.setLayoutParams(dfl);
    elementView.addView(descriptionFrame);

    if (titleObj != null) {
      TextView titleView = (TextView) titleObj.getView();
      titleView.setBackground(null);
      descriptionFrame.addView(titleView);
    }

    if (descriptionObj != null) descriptionFrame.addView(descriptionObj.getView());

    textView = new TextView(Utils.mainActivity);
    textView.setLayoutParams(
        new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    textView.setGravity(Gravity.CENTER);
    textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
    textView.setTextColor(Color.parseColor("#AAAAAA"));
    textView.setId(tv_id);
    elementView.addView(textView);

    v.setOnLongClickListener(this);
    textView.setOnLongClickListener(this);

    elementFrame = new LinearLayout(Utils.mainActivity);
    elementFrame.setLayoutParams(
        new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    elementFrame.setOrientation(LinearLayout.VERTICAL);

    selectorFrame = new FrameLayout(Utils.mainActivity);
    LayoutParams sfl =
        new LayoutParams((int) (15 * Utils.density + 0.5f), LayoutParams.MATCH_PARENT);
    int margin = (int) (Utils.density + 0.5f);
    sfl.setMargins(0, margin, 0, margin);
    selectorFrame.setLayoutParams(sfl);

    selectorFrame.setBackgroundColor(Color.DKGRAY);
    selectorFrame.setVisibility(View.GONE);

    elementFrame.addView(selectorFrame);
    elementFrame.addView(v);

    elementView = elementFrame;

    String initialLive = getLiveValue();
    if (getStoredValue() == null) {
      Utils.db.setValue(command, initialLive);
      stored = lastLive;
    }

    lastEdit = lastLive;

    if (original == null) original = lastLive;

    textView.setOnClickListener(this);
    textView.setText(lastLive.toString());

    valueCheck();

    return elementView;
  }

  private void valueCheck() {
    if (lastEdit.equals(lastLive) && lastEdit.equals(stored)) {
      elementView.setBackground(null);

      if (ActionValueUpdater.isRegistered(this)) ActionValueUpdater.removeElement(this);
    } else {
      elementView.setBackgroundColor(
          Utils.mainActivity.getResources().getColor(R.color.element_value_changed));

      if (!ActionValueUpdater.isRegistered(this)) ActionValueUpdater.registerElement(this);
    }
  }

  /** OnKeyListener methods */
  @Override
  public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE
        || event.getAction() == KeyEvent.ACTION_DOWN
            && event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
      editText.clearFocus();
      Utils.imm.hideSoftInputFromWindow(elementView.getWindowToken(), 0);

      String text = v.getText().toString();
      try {
        lastEdit = Integer.parseInt(text);
      } catch (NumberFormatException ignored) {
        lastEdit = text;
      }

      textView.setText(text);
      textView.setVisibility(View.VISIBLE);
      elementFrame.removeView(editText);
      valueCheck();
      ActionValueNotifierHandler.propagate(this, ActionValueEvent.SET);
    }

    return false;
  }

  /** OnClickListener methods */
  @Override
  public void onClick(View view) {
    if (editText == null) {
      editText = new EditText(Utils.mainActivity);
      editText.setGravity(Gravity.CENTER);
      editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
    }

    if (inputType != null) {
      if (inputType.toLowerCase().equals("numeric"))
        editText.setInputType(InputType.TYPE_CLASS_NUMBER);
      else
        editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
    } else if (lastLive instanceof Integer) editText.setInputType(InputType.TYPE_CLASS_NUMBER);
    else editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);

    textView.setVisibility(View.GONE);
    if (editText.getParent() != null) {
      ((LinearLayout) editText.getParent()).findViewById(tv_id).setVisibility(View.VISIBLE);
      ((LinearLayout) editText.getParent()).removeView(editText);
    }

    elementFrame.addView(editText);
    editText.setOnEditorActionListener(this);
    editText.setText(lastEdit.toString());
    editText.requestFocus();
    editText.setSelection(0, editText.getText().length());
    Utils.imm.showSoftInput(editText, InputMethodManager.SHOW_FORCED);
  }

  /** Selectable methods */
  private boolean selectable = false;

  public void setSelectable(boolean flag) {
    selectable = flag;
  }

  @Override
  public boolean onLongClick(View view) {
    if (!selectable) return false;

    if (isSelected()) deselect();
    else select();

    return true;
  }

  @Override
  public void select() {
    selectorFrame.setVisibility(View.VISIBLE);
    ElementSelector.addElement(this);
  }

  @Override
  public void deselect() {
    selectorFrame.setVisibility(View.GONE);
    ElementSelector.removeElement(this);
  }

  @Override
  public boolean isSelected() {
    return selectorFrame.getVisibility() == View.VISIBLE;
  }

  /** ActionValueNotifierClient methods */
  @Override
  public String getId() {
    return command;
  }

  private ArrayDeque<ActionNotification> queue = new ArrayDeque<ActionNotification>();
  private boolean jobRunning = false;

  public void handleNotifications() {
    jobRunning = true;
    while (queue.size() > 0) {
      ActionNotification current = queue.removeFirst();
      switch (current.notification) {
        case REFRESH:
          try {
            refreshValue();
          } catch (ElementFailureException e) {
            e.printStackTrace();
          }
          break;

        case CANCEL:
          try {
            cancelValue();
          } catch (ElementFailureException e) {
            e.printStackTrace();
          }
          break;

        case RESET:
          setDefaults();
          break;

        case APPLY:
          try {
            applyValue();
          } catch (ElementFailureException e) {
            e.printStackTrace();
          }
          break;
      }
    }
    jobRunning = false;
  }

  private Runnable dequeJob =
      new Runnable() {
        @Override
        public void run() {
          handleNotifications();
        }
      };

  @Override
  public void onNotify(ActionValueNotifierClient source, ActionValueEvent notification) {
    L.d(notification.toString());
    queue.add(new ActionNotification(source, notification));

    if (queue.size() == 1 && !jobRunning) Synapse.handler.post(dequeJob);
  }

  /** ActionValueClient methods */
  @Override
  public String getLiveValue() throws ElementFailureException {
    try {
      String value = Utils.runCommand(command);
      try {
        lastLive = Integer.parseInt(value);
      } catch (NumberFormatException ignored) {
        lastLive = value;
      }
      return value;
    } catch (Exception e) {
      throw new ElementFailureException(this, e);
    }
  }

  @Override
  public String getSetValue() {
    return lastEdit.toString();
  }

  @Override
  public String getStoredValue() {
    String value = Utils.db.getValue(command);
    if (value == null) return null;

    try {
      stored = Integer.parseInt(value);
    } catch (NumberFormatException ignored) {
      stored = value;
    }

    return value;
  }

  @Override
  public void refreshValue() throws ElementFailureException {
    if (Utils.appStarted) getLiveValue();

    if (lastEdit.equals(lastLive)) return;

    lastEdit = lastLive;
    final ActionValueNotifierClient t = this;
    Utils.mainActivity.runOnUiThread(
        new Runnable() {
          @Override
          public void run() {
            textView.setText(lastLive.toString());
            valueCheck();
            ActionValueNotifierHandler.propagate(t, ActionValueEvent.REFRESH);
          }
        });
  }

  @Override
  public void setDefaults() {
    if (original != null) {
      lastEdit = lastLive = original;
      textView.setText(lastLive.toString());
      if (editText != null && editText.getParent() != null)
        if (((LinearLayout) editText.getParent()).findViewById(tv_id) == textView)
          editText.setText(lastLive.toString());
      valueCheck();
    }
    ActionValueNotifierHandler.propagate(this, ActionValueEvent.RESET);
  }

  private boolean commitValue() throws ElementFailureException {
    try {
      Utils.runCommand(command + " \"" + lastEdit.toString() + '"');
      String result = getLiveValue();

      if (!result.equals(getStoredValue())) Utils.db.setValue(command, result);

      try {
        stored = Integer.parseInt(result);
      } catch (NumberFormatException ignored) {
        stored = result;
      }

      lastLive = lastEdit = stored;
      textView.setText(lastLive.toString());
      if (editText != null && editText.getParent() != null)
        if (((LinearLayout) editText.getParent()).findViewById(tv_id) == textView)
          editText.setText(lastLive.toString());
      valueCheck();

      return true;
    } catch (Exception e) {
      throw new ElementFailureException(this, e);
    }
  }

  @Override
  public void applyValue() throws ElementFailureException {
    commitValue();
    ActionValueNotifierHandler.propagate(this, ActionValueEvent.APPLY);
  }

  @Override
  public void cancelValue() throws ElementFailureException {
    lastEdit = lastLive = stored;
    commitValue();
    ActionValueNotifierHandler.propagate(this, ActionValueEvent.CANCEL);
  }

  /** ActivityListener methods */
  @Override
  public void onMainStart() throws ElementFailureException {
    if (!Utils.mainActivity.isChangingConfigurations() && Utils.appStarted)
      Synapse.executor.execute(resumeTask);

    if (!Utils.mainActivity.isChangingConfigurations() && !Utils.appStarted)
      try {
        ActionValueNotifierHandler.addNotifiers(this);
      } catch (Exception e) {
        Utils.createElementErrorView(new ElementFailureException(this, e));
      }
  }

  @Override
  public void onStart() {}

  @Override
  public void onResume() {}

  @Override
  public void onPause() {}
}