comment on onMeasure implementations
This commit is contained in:
parent
000163ad21
commit
247fa77f9d
@ -108,6 +108,29 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
|
|||||||
public View onCreateMediaControlView(Bundle savedInstanceState) {
|
public View onCreateMediaControlView(Bundle savedInstanceState) {
|
||||||
boolean landscape = getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
boolean landscape = getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
|
||||||
if (landscape) {
|
if (landscape) {
|
||||||
|
/*
|
||||||
|
* When a horizontal LinearLayout measures itself, it first measures its children and
|
||||||
|
* settles their widths on the first pass, and only then figures out its height, never
|
||||||
|
* revisiting the widths measurements.
|
||||||
|
* When one has a child view that imposes a certain aspect ratio (such as an ImageView),
|
||||||
|
* then its width and height are related to each other, and so if one allows for a large
|
||||||
|
* height, then it will request for itself a large width as well. However, on the first
|
||||||
|
* child measurement, the LinearLayout imposes a very relaxed height bound, that the
|
||||||
|
* child uses to tell the width it wants, a value which the LinearLayout will interpret
|
||||||
|
* as final, even though the child will want to change it once a more restrictive height
|
||||||
|
* bound is imposed later.
|
||||||
|
*
|
||||||
|
* Our solution is, given that the heights of the children do not depend on their widths
|
||||||
|
* in this case, we first figure out the layout's height and only then perform the
|
||||||
|
* usual sequence of measurements.
|
||||||
|
*
|
||||||
|
* Note: this solution does not take into account any vertical paddings nor children's
|
||||||
|
* vertical margins in determining the height, as this View as well as its children are
|
||||||
|
* defined in code and no paddings/margins that would influence these computations are
|
||||||
|
* introduced.
|
||||||
|
*
|
||||||
|
* There were no resources online for this type of issue as far as I could gather.
|
||||||
|
*/
|
||||||
rootView = new LinearLayout(getContext()) {
|
rootView = new LinearLayout(getContext()) {
|
||||||
@Override
|
@Override
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
@ -118,6 +141,7 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
|
|||||||
int height = Integer.MIN_VALUE;
|
int height = Integer.MIN_VALUE;
|
||||||
View child = getChildAt(i);
|
View child = getChildAt(i);
|
||||||
ViewGroup.LayoutParams lp = child.getLayoutParams();
|
ViewGroup.LayoutParams lp = child.getLayoutParams();
|
||||||
|
// we only measure children whose layout_height is not MATCH_PARENT
|
||||||
if (lp.height >= 0) {
|
if (lp.height >= 0) {
|
||||||
height = lp.height;
|
height = lp.height;
|
||||||
} else if (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
} else if (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
|
||||||
@ -135,8 +159,10 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
rootView.setOrientation(LinearLayout.HORIZONTAL);
|
||||||
} else {
|
} else {
|
||||||
rootView = new LinearLayout(getContext());
|
rootView = new LinearLayout(getContext());
|
||||||
|
rootView.setOrientation(LinearLayout.VERTICAL);
|
||||||
}
|
}
|
||||||
FrameLayout.LayoutParams rootParams = new FrameLayout.LayoutParams(
|
FrameLayout.LayoutParams rootParams = new FrameLayout.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
@ -144,11 +170,6 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
|
|||||||
rootParams.setMargins(0, 0, 0,
|
rootParams.setMargins(0, 0, 0,
|
||||||
getContext().getResources().getDimensionPixelSize(R.dimen.media_router_controller_bottom_margin));
|
getContext().getResources().getDimensionPixelSize(R.dimen.media_router_controller_bottom_margin));
|
||||||
rootView.setLayoutParams(rootParams);
|
rootView.setLayoutParams(rootParams);
|
||||||
if (landscape) {
|
|
||||||
rootView.setOrientation(LinearLayout.HORIZONTAL);
|
|
||||||
} else {
|
|
||||||
rootView.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the session activity when a content item (album art, title or subtitle) is clicked.
|
// Start the session activity when a content item (album art, title or subtitle) is clicked.
|
||||||
View.OnClickListener onClickListener = v -> {
|
View.OnClickListener onClickListener = v -> {
|
||||||
@ -166,6 +187,21 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
|
|||||||
};
|
};
|
||||||
|
|
||||||
LinearLayout.LayoutParams artParams;
|
LinearLayout.LayoutParams artParams;
|
||||||
|
/*
|
||||||
|
* On portrait orientation, we want to limit the artView's height to 9/16 of the available
|
||||||
|
* width. Reason is that we need to choose the height wisely otherwise we risk the dialog
|
||||||
|
* being much larger than the screen, and there doesn't seem to be a good way to know the
|
||||||
|
* available height beforehand.
|
||||||
|
*
|
||||||
|
* On landscape orientation, we want to limit the artView's width to its available height.
|
||||||
|
* Otherwise, horizontal images would take too much space and severely restrict the space
|
||||||
|
* for episode title and play/pause button.
|
||||||
|
*
|
||||||
|
* Internal implementation of ImageView only uses the source image's aspect ratio, but we
|
||||||
|
* want to impose our own and fallback to the source image's when it is more favorable.
|
||||||
|
* Solutions were inspired, among other similar sources, on
|
||||||
|
* http://stackoverflow.com/questions/18077325/scale-image-to-fill-imageview-width-and-keep-aspect-ratio
|
||||||
|
*/
|
||||||
if (landscape) {
|
if (landscape) {
|
||||||
artView = new ImageView(getContext()) {
|
artView = new ImageView(getContext()) {
|
||||||
@Override
|
@Override
|
||||||
@ -228,6 +264,7 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
|
|||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
}
|
}
|
||||||
|
// When we fetch the bitmap, we want to know if we should set a background color or not.
|
||||||
artView.setTag(landscape);
|
artView.setTag(landscape);
|
||||||
|
|
||||||
artView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
artView.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||||
@ -239,6 +276,8 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
|
|||||||
ViewGroup wrapper = rootView;
|
ViewGroup wrapper = rootView;
|
||||||
|
|
||||||
if (landscape) {
|
if (landscape) {
|
||||||
|
// Here we wrap with a frame layout because we want to set different layout parameters
|
||||||
|
// for landscape orientation.
|
||||||
wrapper = new FrameLayout(getContext());
|
wrapper = new FrameLayout(getContext());
|
||||||
wrapper.setLayoutParams(new LinearLayout.LayoutParams(
|
wrapper.setLayoutParams(new LinearLayout.LayoutParams(
|
||||||
0,
|
0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user