Skip to content

Instantly share code, notes, and snippets.

@bangarharshit
Created September 10, 2016 07:10
Show Gist options
  • Save bangarharshit/d779773251db8f547cd31fb3be3c294d to your computer and use it in GitHub Desktop.
Save bangarharshit/d779773251db8f547cd31fb3be3c294d to your computer and use it in GitHub Desktop.
package com.drawers.myapplication;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Point;
import android.os.Build;
import android.util.AttributeSet;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
/**
* Custom view group to reduce multiple measures. Only 1 measure pass.
*
* D/Harshit CustomImageView: MeasureSpec: EXACTLY 120 MeasureSpec: EXACTLY 120 0
* D/Harshit ImageView2: MeasureSpec: EXACTLY 60 MeasureSpec: EXACTLY 60 0
* D/Harshit CustomTextView1: MeasureSpec: EXACTLY 900 MeasureSpec: AT_MOST 1344 0
* D/Harshit CustomTextView2: MeasureSpec: EXACTLY 900 MeasureSpec: AT_MOST 1287 0
*/
public class CustomViewGroup extends ViewGroup {
public CustomViewGroup(Context context) {
super(context);
}
public CustomViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childTop;
int childLeft;
int childRight;
int childBottom;
MarginLayoutParams layoutParams = (MarginLayoutParams) mProfilePhoto.getLayoutParams();
childLeft = getPaddingLeft() + layoutParams.leftMargin;
childRight = childLeft + mProfilePhoto.getMeasuredWidth();
childTop = getPaddingTop() + layoutParams.topMargin;
childBottom = childTop + mProfilePhoto.getMeasuredHeight();
int marginRight = layoutParams.rightMargin;
mProfilePhoto.layout(childLeft, childTop, childRight, childBottom);
layoutParams = (MarginLayoutParams) mMenu.getLayoutParams();
childTop = getPaddingTop() + layoutParams.topMargin;
childBottom = childTop + mMenu.getMeasuredHeight();
int width = getScreenWidth();
childLeft = width - mMenu.getMeasuredWidth() - layoutParams.rightMargin;
childRight = width - layoutParams.rightMargin;
mMenu.layout(childLeft, childTop, childRight, childBottom);
layoutParams = (MarginLayoutParams) mTitle.getLayoutParams();
childTop = getPaddingTop() + layoutParams.topMargin;
childBottom = childTop + mTitle.getMeasuredHeight();
childLeft = getPaddingLeft() + mProfilePhoto.getMeasuredWidth() + marginRight + layoutParams.leftMargin;
childRight = childLeft + mTitle.getMeasuredWidth();
mTitle.layout(childLeft, childTop, childRight, childBottom);
childTop = childBottom + layoutParams.bottomMargin;
childBottom = childTop + mSubtitle.getMeasuredHeight();
mSubtitle.layout(childLeft, childTop, childRight, childBottom);
}
private int getScreenWidth() {
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size.x;
}
private CustomImageView mProfilePhoto;
private ImageView2 mMenu;
private CustomTextView1 mTitle;
private CustomTextView2 mSubtitle;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// 1. Setup initial constraints.
int widthConstraints = getPaddingLeft() + getPaddingRight();
int heightConstraints = getPaddingTop() + getPaddingBottom();
int width = 0;
int height = 0;
mProfilePhoto = (CustomImageView) getChildAt(0);
mMenu = (ImageView2) getChildAt(1);
mTitle = (CustomTextView1) getChildAt(2);
mSubtitle = (CustomTextView2) getChildAt(3);
// 2. Measure the ProfilePhoto
measureChildWithMargins(
mProfilePhoto,
widthMeasureSpec,
widthConstraints,
heightMeasureSpec,
heightConstraints);
// 3. Update the contraints.
widthConstraints += mProfilePhoto.getMeasuredWidth();
width += mProfilePhoto.getMeasuredWidth();
height = Math.max(mProfilePhoto.getMeasuredHeight() + getPaddingTop(), height);
// 4. Measure the Menu.
measureChildWithMargins(
mMenu,
widthMeasureSpec,
widthConstraints,
heightMeasureSpec,
heightConstraints);
// 5. Update the constraints.
widthConstraints += mMenu.getMeasuredWidth();
width += mMenu.getMeasuredWidth();
height = Math.max(mMenu.getMeasuredHeight(), height);
// 6. Prepare the vertical MeasureSpec.
int verticalWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
MeasureSpec.getSize(widthMeasureSpec) - widthConstraints,
MeasureSpec.getMode(widthMeasureSpec));
int verticalHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
MeasureSpec.getSize(heightMeasureSpec) - heightConstraints,
MeasureSpec.getMode(heightMeasureSpec));
// 7. Measure the Title.
measureChildWithMargins(
mTitle,
verticalWidthMeasureSpec,
0,
verticalHeightMeasureSpec,
0);
// 8. Measure the Subtitle.
measureChildWithMargins(
mSubtitle,
verticalWidthMeasureSpec,
0,
verticalHeightMeasureSpec,
mTitle.getMeasuredHeight());
// 9. Update the sizes.
width += Math.max(mTitle.getMeasuredWidth(), mSubtitle.getMeasuredWidth());
height = Math.max(mTitle.getMeasuredHeight() + mSubtitle.getMeasuredHeight(), height);
// 10. Set the dimension for this ViewGroup.
setMeasuredDimension(
resolveSize(width, widthMeasureSpec),
resolveSize(height, heightMeasureSpec));
}
@Override
protected void measureChildWithMargins(
View child,
int parentWidthMeasureSpec,
int widthUsed,
int parentHeightMeasureSpec,
int heightUsed) {
MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
int childWidthMeasureSpec = getChildMeasureSpec(
parentWidthMeasureSpec,
widthUsed + lp.leftMargin + lp.rightMargin,
lp.width);
int childHeightMeasureSpec = getChildMeasureSpec(
parentHeightMeasureSpec,
heightUsed + + lp.topMargin + lp.bottomMargin,
lp.height);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
}
<?xml version="1.0" encoding="utf-8"?>
<com.drawers.myapplication.CustomViewGroup
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:paddingTop="@dimen/activity_vertical_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.drawers.myapplication.MainActivity">
<com.drawers.myapplication.CustomImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="32dp"
android:src="@android:drawable/sym_def_app_icon"
android:contentDescription="profile_photo"
/>
<com.drawers.myapplication.ImageView2
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="20dp"
android:src="@android:drawable/ic_menu_sort_by_size"/>
<com.drawers.myapplication.CustomTextView1
android:layout_width="match_parent"
android:text="Sherlock Spock"
android:textColor="#000"
android:layout_height="wrap_content"/>
<com.drawers.myapplication.CustomTextView2
android:layout_width="match_parent"
android:text="2hr. San Francisco, CA"
android:textColor="#000"
android:layout_height="wrap_content"/>
</com.drawers.myapplication.CustomViewGroup>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment