private static PercentLayoutInfo setMinMaxWidthHeightRelatedVal(
      TypedArray array, PercentLayoutInfo info) {
    // maxWidth
    PercentLayoutInfo.PercentVal percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_maxWidthPercent, true);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.maxWidthPercent = percentVal;
    }
    // maxHeight
    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_maxHeightPercent, false);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.maxHeightPercent = percentVal;
    }
    // minWidth
    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_minWidthPercent, true);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.minWidthPercent = percentVal;
    }
    // minHeight
    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_minHeightPercent, false);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.minHeightPercent = percentVal;
    }

    return info;
  }
  /**
   * Iterates over children and changes their width and height to one calculated from percentage
   * values.
   *
   * @param widthMeasureSpec Width MeasureSpec of the parent ViewGroup.
   * @param heightMeasureSpec Height MeasureSpec of the parent ViewGroup.
   */
  public void adjustChildren(int widthMeasureSpec, int heightMeasureSpec) {
    if (Log.isLoggable(TAG, Log.DEBUG)) {
      Log.d(
          TAG,
          "adjustChildren: "
              + mHost
              + " widthMeasureSpec: "
              + View.MeasureSpec.toString(widthMeasureSpec)
              + " heightMeasureSpec: "
              + View.MeasureSpec.toString(heightMeasureSpec));
    }
    int widthHint = View.MeasureSpec.getSize(widthMeasureSpec);
    int heightHint = View.MeasureSpec.getSize(heightMeasureSpec);

    if (Log.isLoggable(TAG, Log.DEBUG))
      Log.d(TAG, "widthHint = " + widthHint + " , heightHint = " + heightHint);

    for (int i = 0, N = mHost.getChildCount(); i < N; i++) {
      View view = mHost.getChildAt(i);
      ViewGroup.LayoutParams params = view.getLayoutParams();

      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "should adjust " + view + " " + params);
      }

      if (params instanceof PercentLayoutParams) {
        PercentLayoutInfo info = ((PercentLayoutParams) params).getPercentLayoutInfo();
        if (Log.isLoggable(TAG, Log.DEBUG)) {
          Log.d(TAG, "using " + info);
        }
        if (info != null) {
          supportTextSize(widthHint, heightHint, view, info);
          supportPadding(widthHint, heightHint, view, info);
          supportMinOrMaxDimesion(widthHint, heightHint, view, info);

          if (params instanceof ViewGroup.MarginLayoutParams) {
            info.fillMarginLayoutParams(
                (ViewGroup.MarginLayoutParams) params, widthHint, heightHint);
          } else {
            info.fillLayoutParams(params, widthHint, heightHint);
          }
        }
      }
    }
  }
 /**
  * Iterates over children and restores their original dimensions that were changed for percentage
  * values. Calling this method only makes sense if you previously called {@link
  * PercentLayoutHelper#adjustChildren(int, int)}.
  */
 public void restoreOriginalParams() {
   for (int i = 0, N = mHost.getChildCount(); i < N; i++) {
     View view = mHost.getChildAt(i);
     ViewGroup.LayoutParams params = view.getLayoutParams();
     if (Log.isLoggable(TAG, Log.DEBUG)) {
       Log.d(TAG, "should restore " + view + " " + params);
     }
     if (params instanceof PercentLayoutParams) {
       PercentLayoutInfo info = ((PercentLayoutParams) params).getPercentLayoutInfo();
       if (Log.isLoggable(TAG, Log.DEBUG)) {
         Log.d(TAG, "using " + info);
       }
       if (info != null) {
         if (params instanceof ViewGroup.MarginLayoutParams) {
           info.restoreMarginLayoutParams((ViewGroup.MarginLayoutParams) params);
         } else {
           info.restoreLayoutParams(params);
         }
       }
     }
   }
 }
  private static PercentLayoutInfo setWidthAndHeightVal(TypedArray array, PercentLayoutInfo info) {
    PercentLayoutInfo.PercentVal percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_widthPercent, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent width: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.widthPercent = percentVal;
    }
    percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_heightPercent, false);

    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent height: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.heightPercent = percentVal;
    }

    return info;
  }
  private static PercentLayoutInfo setTextSizeSupportVal(TypedArray array, PercentLayoutInfo info) {
    // textSizePercent 默认以高度作为基准
    PercentLayoutInfo.PercentVal percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_textSizePercent, false);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent text size: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.textSizePercent = percentVal;
    }

    return info;
  }
  /**
   * 设置paddingPercent相关属性
   *
   * @param array
   * @param info
   */
  private static PercentLayoutInfo setPaddingRelatedVal(TypedArray array, PercentLayoutInfo info) {
    // 默认padding以宽度为标准
    PercentLayoutInfo.PercentVal percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_paddingPercent, true);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.paddingLeftPercent = percentVal;
      info.paddingRightPercent = percentVal;
      info.paddingBottomPercent = percentVal;
      info.paddingTopPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_paddingLeftPercent, true);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.paddingLeftPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_paddingRightPercent, true);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.paddingRightPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_paddingTopPercent, true);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.paddingTopPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_paddingBottomPercent, true);
    if (percentVal != null) {
      info = checkForInfoExists(info);
      info.paddingBottomPercent = percentVal;
    }

    return info;
  }
  /**
   * Constructs a PercentLayoutInfo from attributes associated with a View. Call this method from
   * {@code LayoutParams(Context c, AttributeSet attrs)} constructor.
   */
  public static PercentLayoutInfo getPercentLayoutInfo(Context context, AttributeSet attrs) {
    PercentLayoutInfo info = null;
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PercentLayout_Layout);

    int index = R.styleable.PercentLayout_Layout_layout_widthPercent;
    String sizeStr = array.getString(index);
    PercentLayoutInfo.PercentVal percentVal = getPercentVal(sizeStr, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent width: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.widthPercent = percentVal;
    }
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_heightPercent);
    percentVal = getPercentVal(sizeStr, false);

    if (sizeStr != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent height: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.heightPercent = percentVal;
    }

    // value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginPercent, 1, 1, -1f);
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_marginPercent);
    // just for judge
    percentVal = getPercentVal(sizeStr, false);

    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.leftMarginPercent = getPercentVal(sizeStr, true);
      info.topMarginPercent = getPercentVal(sizeStr, false);
      info.rightMarginPercent = getPercentVal(sizeStr, true);
      info.bottomMarginPercent = getPercentVal(sizeStr, false);
    }
    // value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginLeftPercent, 1, 1,
    // -1f);
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_marginLeftPercent);
    percentVal = getPercentVal(sizeStr, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent left margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.leftMarginPercent = percentVal;
    }

    // value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginTopPercent, 1, 1,
    // -1f);
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_marginTopPercent);
    percentVal = getPercentVal(sizeStr, false);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent top margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.topMarginPercent = percentVal;
    }
    // value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginRightPercent, 1, 1,
    // -1f);
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_marginRightPercent);
    percentVal = getPercentVal(sizeStr, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent right margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.rightMarginPercent = percentVal;
    }
    // value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginBottomPercent, 1, 1,
    // -1f);
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_marginBottomPercent);
    percentVal = getPercentVal(sizeStr, false);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent bottom margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.bottomMarginPercent = percentVal;
    }
    // value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginStartPercent, 1, 1,
    // -1f);
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_marginStartPercent);
    percentVal = getPercentVal(sizeStr, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent start margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.startMarginPercent = percentVal;
    }
    // value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginEndPercent, 1, 1,
    // -1f);
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_marginEndPercent);
    percentVal = getPercentVal(sizeStr, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent end margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.endMarginPercent = percentVal;
    }

    // textSizePercent
    sizeStr = array.getString(R.styleable.PercentLayout_Layout_layout_textSizePercent);
    percentVal = getPercentVal(sizeStr, false);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent text size: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.textSizePercent = percentVal;
    }

    // maxWidth
    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_maxWidthPercent, true);
    if (percentVal != null) {
      checkForInfoExists(info);
      info.maxWidthPercent = percentVal;
    }
    // maxHeight
    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_maxHeightPercent, false);
    if (percentVal != null) {
      checkForInfoExists(info);
      info.maxHeightPercent = percentVal;
    }
    // minWidth
    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_minWidthPercent, true);
    if (percentVal != null) {
      checkForInfoExists(info);
      info.minWidthPercent = percentVal;
    }
    // minHeight
    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_minHeightPercent, false);
    Log.d(TAG, "minHeight = " + percentVal);
    if (percentVal != null) {
      checkForInfoExists(info);
      info.minHeightPercent = percentVal;
    }

    array.recycle();
    if (Log.isLoggable(TAG, Log.DEBUG)) {
      Log.d(TAG, "constructed: " + info);
    }
    return info;
  }
  private static PercentLayoutInfo setMarginRelatedVal(TypedArray array, PercentLayoutInfo info) {
    // 默认margin参考宽度
    PercentLayoutInfo.PercentVal percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginPercent, true);

    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.leftMarginPercent = percentVal;
      info.topMarginPercent = percentVal;
      info.rightMarginPercent = percentVal;
      info.bottomMarginPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginLeftPercent, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent left margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.leftMarginPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginTopPercent, false);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent top margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.topMarginPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginRightPercent, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent right margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.rightMarginPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginBottomPercent, false);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent bottom margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.bottomMarginPercent = percentVal;
    }
    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginStartPercent, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent start margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.startMarginPercent = percentVal;
    }

    percentVal =
        getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginEndPercent, true);
    if (percentVal != null) {
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
        Log.v(TAG, "percent end margin: " + percentVal.percent);
      }
      info = checkForInfoExists(info);
      info.endMarginPercent = percentVal;
    }

    return info;
  }