Android self implementation percentage layout

Posted by goatboy on Wed, 01 Jan 2020 11:32:06 +0100

In development, component layout is the work that everyone must face in daily development. For Android, there are five common layouts, namely:

  • LinearLayout (linear layout)
  • Tablelayout (table layout)
  • Relativelayout
  • Absolute layout
  • FrameLayout (frame layout)

However, if we can layout the interface in a percentage way in the development, it will bring a lot of convenience to our adaptation work. Some time ago, Google officially provided the Android support percentage lib. For our developers, we only need to import this library to realize the percentage layout. Now let's forget about Google Library. In fact, we can achieve percentage layout.

/**
 * 
 * @ClassName: PercentRelativeLayout 
 * @Description: Custom percentage relative layout 
 * @author Monkey's rescuer http://blog.csdn.net/mynameishuangshua
 */
public class PercentRelativeLayout extends RelativeLayout{

    public PercentRelativeLayout(Context context) {
        super(context);
    }

    public PercentRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public PercentRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs); 
    }
    /**
     * Rewrite measurement method
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Get the width and height of the parent control first
        int width = View.MeasureSpec.getSize(widthMeasureSpec);
        int height = View.MeasureSpec.getSize(heightMeasureSpec);
        int count = this.getChildCount();
        for (int i = 0; i < count; i++) {// Loop iteration child control
            View child = this.getChildAt(i);// Take out each child control
            ViewGroup.LayoutParams lp = child.getLayoutParams();
            float widthPercent = 0;
            float hightPercent = 0;
            if (lp instanceof PercentRelativeLayout.LayoutParams) {// Support percentage layout
                widthPercent = ((PercentRelativeLayout.LayoutParams) lp).widthPercent;
                hightPercent = ((PercentRelativeLayout.LayoutParams) lp).heightPercent;
            }
            if (widthPercent != 0) {
                // Width * width percentage of parent container
                lp.width = (int) (width * widthPercent);
            }

            if (hightPercent != 0) {
                // Percentage of height * height of parent container
                lp.height = (int) (height * hightPercent);
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * Override layout method for child controls
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }

    /**
     * Override to get and analyze the layout properties of child controls
     */
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
//      return super.generateLayoutParams(attrs); / / here, you must return the following customized LayoutParams
        return new LayoutParams(getContext(), attrs);
    }

    public static class LayoutParams extends RelativeLayout.LayoutParams{

        private float widthPercent;
        private float heightPercent;

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
            TypedArray a = c.obtainStyledAttributes(attrs,R.styleable.precentRelativeLayout);
            widthPercent = a.getFloat(R.styleable.precentRelativeLayout_layout_widthPrecent, widthPercent);
            heightPercent = a.getFloat(R.styleable.precentRelativeLayout_layout_heightPrecent, heightPercent);
            a.recycle();
        }

        public LayoutParams(int w, int h) {
            super(w, h);
        }

        public LayoutParams(android.view.ViewGroup.LayoutParams source) {
            super(source);
        }

        public LayoutParams(android.widget.RelativeLayout.LayoutParams source) {
            super(source);
        }

    }
}

Custom properties file:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name= "precentRelativeLayout">
        <attr name="layout_widthPrecent" format="float"></attr>
        <attr name="layout_heightPrecent" format="float"></attr>
    </declare-styleable>
</resources>

Layout file:

<com.castiel.demo.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.castiel.demo"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        app:layout_heightPrecent="0.2"
        app:layout_widthPrecent="0.2"
        android:background="#28FF28"
        android:text="http://blog.csdn.net/mynameishuangshuai" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        app:layout_heightPrecent="0.3"
        app:layout_widthPrecent="0.3"
        android:background="#28FF28"
        android:text="Monkey's rescuer" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:layout_heightPrecent="0.2"
        app:layout_widthPrecent="0.2"
        android:background="#28FF28"
        android:text="castiel" />

</com.castiel.demo.PercentRelativeLayout>

Operation result:

Topics: Android Google xml encoding