summaryrefslogtreecommitdiff
path: root/app/src/play/java/de/danoeh
diff options
context:
space:
mode:
authorDomingos Lopes <domingos86lopes+github@gmail.com>2016-07-02 11:22:09 -0400
committerDomingos Lopes <domingos86lopes+github@gmail.com>2016-07-02 11:22:09 -0400
commit247fa77f9d08420783ad94bcbe4596cec5c6f8e5 (patch)
tree355f144d432b255947f7ecada31e74c7315a97f3 /app/src/play/java/de/danoeh
parent000163ad219b7ebb84b23dcd96e13868a2c919a7 (diff)
downloadAntennaPod-247fa77f9d08420783ad94bcbe4596cec5c6f8e5.zip
comment on onMeasure implementations
Diffstat (limited to 'app/src/play/java/de/danoeh')
-rw-r--r--app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java49
1 files changed, 44 insertions, 5 deletions
diff --git a/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java b/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java
index f33af8823..93ec4e3f0 100644
--- a/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java
+++ b/app/src/play/java/de/danoeh/antennapod/dialog/CustomMRControllerDialog.java
@@ -108,6 +108,29 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
public View onCreateMediaControlView(Bundle savedInstanceState) {
boolean landscape = getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_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()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@@ -118,6 +141,7 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
int height = Integer.MIN_VALUE;
View child = getChildAt(i);
ViewGroup.LayoutParams lp = child.getLayoutParams();
+ // we only measure children whose layout_height is not MATCH_PARENT
if (lp.height >= 0) {
height = lp.height;
} else if (lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
@@ -135,8 +159,10 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
}
}
};
+ rootView.setOrientation(LinearLayout.HORIZONTAL);
} else {
rootView = new LinearLayout(getContext());
+ rootView.setOrientation(LinearLayout.VERTICAL);
}
FrameLayout.LayoutParams rootParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -144,11 +170,6 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
rootParams.setMargins(0, 0, 0,
getContext().getResources().getDimensionPixelSize(R.dimen.media_router_controller_bottom_margin));
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.
View.OnClickListener onClickListener = v -> {
@@ -166,6 +187,21 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
};
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) {
artView = new ImageView(getContext()) {
@Override
@@ -228,6 +264,7 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
ViewGroup.LayoutParams.MATCH_PARENT,
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.setScaleType(ImageView.ScaleType.FIT_CENTER);
@@ -239,6 +276,8 @@ public class CustomMRControllerDialog extends MediaRouteControllerDialog {
ViewGroup wrapper = rootView;
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.setLayoutParams(new LinearLayout.LayoutParams(
0,