PercentLayoutHelper

open class PercentLayoutHelper
kotlin.Any
   ↳ androidx.percentlayout.widget.PercentLayoutHelper

Helper for layouts that want to support percentage based dimensions.

This class collects utility methods that are involved in extracting percentage based dimension attributes and applying them to ViewGroup's children. If you would like to implement a layout that supports percentage based dimensions, you need to take several steps:

  1. You need a ViewGroup.LayoutParams subclass in your ViewGroup that implements PercentLayoutHelper.PercentLayoutParams.
  2. In your LayoutParams(Context c, AttributeSet attrs) constructor create an instance of PercentLayoutHelper.PercentLayoutInfo by calling PercentLayoutHelper#getPercentLayoutInfo(Context, AttributeSet). Return this object from public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo() method that you implemented for PercentLayoutHelper.PercentLayoutParams interface.
  3. Override ViewGroup.LayoutParams#setBaseAttributes(TypedArray, int, int) with a single line implementation PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr);
  4. In your ViewGroup override ViewGroup#generateLayoutParams(AttributeSet) to return your LayoutParams.
  5. In your ViewGroup#onMeasure(int, int) override, you need to implement following pattern:
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
          super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          if (mHelper.handleMeasuredStateTooSmall()) {
              super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          }
      }
      
  6. In your ViewGroup#onLayout(boolean, int, int, int, int) override, you need to implement following pattern:
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
          super.onLayout(changed, left, top, right, bottom);
          mHelper.restoreOriginalParams();
      }
      

Summary

Nested classes

open

Container for information about percentage dimensions and margins.

abstract

If a layout wants to support percentage based dimensions and use this helper class, its LayoutParams subclass must implement this interface.

Public constructors

<init>(@NonNull host: ViewGroup)

Public methods

open Unit
adjustChildren(widthMeasureSpec: Int, heightMeasureSpec: Int)

Iterates over children and changes their width and height to one calculated from percentage values.

open static Unit
fetchWidthAndHeight(params: LayoutParams!, array: TypedArray!, widthAttr: Int, heightAttr: Int)

Helper method to be called from ViewGroup.LayoutParams#setBaseAttributes override that reads layout_width and layout_height attribute values without throwing an exception if they aren't present.

open static PercentLayoutHelper.PercentLayoutInfo!

Constructs a PercentLayoutInfo from attributes associated with a View.

open Boolean

Iterates over children and checks if any of them would like to get more space than it received through the percentage dimension.

open Unit

Iterates over children and restores their original dimensions that were changed for percentage values.

Public constructors

<init>

PercentLayoutHelper(@NonNull host: ViewGroup)

Public methods

adjustChildren

open fun adjustChildren(widthMeasureSpec: Int, heightMeasureSpec: Int): Unit

Iterates over children and changes their width and height to one calculated from percentage values.

Parameters
widthMeasureSpec Int: Width MeasureSpec of the parent ViewGroup.
heightMeasureSpec Int: Height MeasureSpec of the parent ViewGroup.

fetchWidthAndHeight

open static fun fetchWidthAndHeight(params: LayoutParams!, array: TypedArray!, widthAttr: Int, heightAttr: Int): Unit

Helper method to be called from ViewGroup.LayoutParams#setBaseAttributes override that reads layout_width and layout_height attribute values without throwing an exception if they aren't present.

getPercentLayoutInfo

open static fun getPercentLayoutInfo(context: Context!, attrs: AttributeSet!): PercentLayoutHelper.PercentLayoutInfo!

Constructs a PercentLayoutInfo from attributes associated with a View. Call this method from LayoutParams(Context c, AttributeSet attrs) constructor.

handleMeasuredStateTooSmall

open fun handleMeasuredStateTooSmall(): Boolean

Iterates over children and checks if any of them would like to get more space than it received through the percentage dimension. If you are building a layout that supports percentage dimensions you are encouraged to take advantage of this method. The developer should be able to specify that a child should be remeasured by adding normal dimension attribute with wrap_content value. For example he might specify child's attributes as app:layout_widthPercent="60%p" and android:layout_width="wrap_content". In this case if the child receives too little space, it will be remeasured with width set to WRAP_CONTENT.

Return
Boolean: True if the measure phase needs to be rerun because one of the children would like to receive more space.

restoreOriginalParams

open fun restoreOriginalParams(): Unit

Iterates over children and restores their original dimensions that were changed for percentage values. Calling this method only makes sense if you previously called PercentLayoutHelper#adjustChildren(int, int).