As I mentioned in the question, the app I'm working on will be displayed on either 720p or 1080p TV. This allows me to commit the following blasphemy: All view sizes/paddings/margins and text sizes are defined in PX, not DP, not SP. This way I can control the exact screen layout.
Now, contrary to what the documentation made me to believe, Android will not resize any layout element that has size defined in PX. It will only do it for drawables or DP/SP.
Thus I had to resize on my own.
I define the layouts for 1080p. in Activity.onCreate() get the root layout and pass it to:
private static final float RATIO_720_1080 = 720f/1080f;
/**
* If the screen is 720p, the resources will resize
* to fit the screen.
* @param root Root view where the resources are found.
*/
public void resizeViews(ViewGroup root) {
DisplayMetrics metrics = getResources().getDisplayMetrics();
// only resize if 720p
if (metrics.widthPixels != 1280) return;
int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
View v = root.getChildAt(i);
// digg deep
if (v instanceof ViewGroup) {
resizeViews((ViewGroup)v);
}
// do the size
ViewGroup.LayoutParams params = v.getLayoutParams();
// keep the match_parent constants intact
if (params.height > 0) {
params.height = Math.round(params.height * RATIO_720_1080);
}
if (params.width > 0) {
params.width = Math.round(params.width * RATIO_720_1080);
}
if (params instanceof ViewGroup.MarginLayoutParams) {
ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) params;
marginParams.setMargins(Math.round(marginParams.leftMargin * RATIO_720_1080),
Math.round(marginParams.topMargin * RATIO_720_1080),
Math.round(marginParams.rightMargin * RATIO_720_1080),
Math.round(marginParams.bottomMargin * RATIO_720_1080));
}
v.setLayoutParams(params);
v.setPadding(Math.round(v.getPaddingLeft() * RATIO_720_1080),
Math.round(v.getPaddingTop() * RATIO_720_1080),
Math.round(v.getPaddingRight() * RATIO_720_1080),
Math.round(v.getPaddingBottom() * RATIO_720_1080));
// text size
if (v instanceof TextView) {
float size = ((TextView)v).getTextSize();
size *= RATIO_720_1080;
((TextView)v).setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
}
}
}