public class EditorInfoCompatUtils {
  // EditorInfo.IME_FLAG_FORCE_ASCII has been introduced since API#16 (JellyBean).
  private static final Field FIELD_IME_FLAG_FORCE_ASCII =
      CompatUtils.getField(EditorInfo.class, "IME_FLAG_FORCE_ASCII");
  private static final Integer OBJ_IME_FLAG_FORCE_ASCII =
      (Integer) CompatUtils.getFieldValue(null, null, FIELD_IME_FLAG_FORCE_ASCII);

  private EditorInfoCompatUtils() {
    // This utility class is not publicly instantiable.
  }

  public static boolean hasFlagForceAscii(int imeOptions) {
    if (OBJ_IME_FLAG_FORCE_ASCII == null) return false;
    return (imeOptions & OBJ_IME_FLAG_FORCE_ASCII) != 0;
  }

  public static String imeActionName(int imeOptions) {
    final int actionId = imeOptions & EditorInfo.IME_MASK_ACTION;
    switch (actionId) {
      case EditorInfo.IME_ACTION_UNSPECIFIED:
        return "actionUnspecified";
      case EditorInfo.IME_ACTION_NONE:
        return "actionNone";
      case EditorInfo.IME_ACTION_GO:
        return "actionGo";
      case EditorInfo.IME_ACTION_SEARCH:
        return "actionSearch";
      case EditorInfo.IME_ACTION_SEND:
        return "actionSend";
      case EditorInfo.IME_ACTION_NEXT:
        return "actionNext";
      case EditorInfo.IME_ACTION_DONE:
        return "actionDone";
      case EditorInfo.IME_ACTION_PREVIOUS:
        return "actionPrevious";
      default:
        return "actionUnknown(" + actionId + ")";
    }
  }

  public static String imeOptionsName(int imeOptions) {
    final String action = imeActionName(imeOptions);
    final StringBuilder flags = new StringBuilder();
    if ((imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
      flags.append("flagNoEnterAction|");
    }
    if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0) {
      flags.append("flagNavigateNext|");
    }
    if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0) {
      flags.append("flagNavigatePrevious|");
    }
    if (hasFlagForceAscii(imeOptions)) {
      flags.append("flagForceAscii|");
    }
    return (action != null) ? flags + action : flags.toString();
  }
}
  private void init(AttributeSet attrs) {

    TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.SmoothCheckBox);
    int tickColor = ta.getColor(R.styleable.SmoothCheckBox_color_tick, COLOR_TICK);
    mAnimDuration = ta.getInt(R.styleable.SmoothCheckBox_duration, DEF_ANIM_DURATION);
    mFloorColor =
        ta.getColor(R.styleable.SmoothCheckBox_color_unchecked_stroke, COLOR_FLOOR_UNCHECKED);
    mCheckedColor = ta.getColor(R.styleable.SmoothCheckBox_color_checked, COLOR_CHECKED);
    mUnCheckedColor = ta.getColor(R.styleable.SmoothCheckBox_color_unchecked, COLOR_UNCHECKED);
    mStrokeWidth =
        ta.getDimensionPixelSize(
            R.styleable.SmoothCheckBox_stroke_width, CompatUtils.dp2px(getContext(), 0));
    ta.recycle();

    mFloorUnCheckedColor = mFloorColor;
    mTickPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mTickPaint.setStyle(Paint.Style.STROKE);
    mTickPaint.setStrokeCap(Paint.Cap.ROUND);
    mTickPaint.setColor(tickColor);

    mFloorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mFloorPaint.setStyle(Paint.Style.FILL);
    mFloorPaint.setColor(mFloorColor);

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setStyle(Paint.Style.FILL);
    mPaint.setColor(mCheckedColor);

    mTickPath = new Path();
    mCenterPoint = new Point();
    mTickPoints = new Point[3];
    mTickPoints[0] = new Point();
    mTickPoints[1] = new Point();
    mTickPoints[2] = new Point();

    setOnClickListener(
        new OnClickListener() {
          @Override
          public void onClick(View v) {
            toggle();
            mTickDrawing = false;
            mDrewDistance = 0;
            if (isChecked()) {
              startCheckedAnimation();
            } else {
              startUnCheckedAnimation();
            }
          }
        });
  }