Skip to content

Instantly share code, notes, and snippets.

@alexfu
Last active August 29, 2015 14:00
Show Gist options
  • Save alexfu/11323314 to your computer and use it in GitHub Desktop.
Save alexfu/11323314 to your computer and use it in GitHub Desktop.
A FrameLayout that fits it's content into the viewable area (like fitSystemWindow). Works great for when fitSystemWindow isn't enough.
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.FrameLayout;
/**
* A FrameLayout that fits it's content into the viewable
* area (like fitSystemWindow).
*/
public class FitFrameLayout extends FrameLayout {
private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";
private int statusBarHeight = -1;
private int navigationBarHeight = -1;
private int actionBarHeight = -1;
private boolean hasTranslucentStatus = false;
private boolean hasTranslucentNavigation = false;
private boolean hasOverlayActionBar = false;
public FitFrameLayout(Context context) {
super(context);
init();
}
public FitFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FitFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
int[] attrs = new int[3];
attrs[0] = android.R.attr.windowActionBarOverlay;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
attrs[1] = android.R.attr.windowTranslucentStatus;
attrs[2] = android.R.attr.windowTranslucentNavigation;
TypedArray array = getContext().obtainStyledAttributes(attrs);
hasOverlayActionBar = array.getBoolean(0, false);
hasTranslucentStatus = array.getBoolean(1, false);
hasTranslucentNavigation = array.getBoolean(2, false);
} else {
TypedArray array = getContext().obtainStyledAttributes(attrs);
hasOverlayActionBar = array.getBoolean(0, false);
}
statusBarHeight = hasTranslucentStatus ?
getInternalDimensionSize(getResources(), STATUS_BAR_HEIGHT_RES_NAME) : -1;
navigationBarHeight = hasTranslucentNavigation ?
getInternalDimensionSize(getResources(), NAV_BAR_HEIGHT_RES_NAME) : -1;
actionBarHeight = hasOverlayActionBar ? getActionBarHeight(getContext()) : -1;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int top = calculateTopPadding();
int bottom = calcuateBottomPadding();
setPadding(getPaddingLeft(), top, getPaddingRight(), bottom);
}
private int calculateTopPadding() {
return (hasTranslucentStatus ? statusBarHeight : 0) +
(hasOverlayActionBar ? actionBarHeight : 0);
}
private int calcuateBottomPadding() {
return (hasTranslucentNavigation ? navigationBarHeight : 0);
}
// The following methods are "borrowed" from the SystemBarTint library.
// Credit to Jeff Gilfet.
private int getActionBarHeight(Context context) {
int result = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
TypedValue tv = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
result = context.getResources().getDimensionPixelSize(tv.resourceId);
}
return result;
}
private int getInternalDimensionSize(Resources res, String key) {
int result = 0;
int resourceId = res.getIdentifier(key, "dimen", "android");
if (resourceId > 0) {
result = res.getDimensionPixelSize(resourceId);
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment