package com.marshalchen.common.uimodule.tileView.layouts;
import android.content.Context;
import android.view.View;
/**
* The TranslationLayout extends {@link AnchorLayout}, but additionally supports
* a scale value. The views of this layout will not be scaled along width or height,
* but their positions will be multiplied by the TranslationLayout's scale value.
* This allows the contained views to maintain their visual appearance and distance
* relative to each other, while the total area of the group can be managed by the
* scale value.
*
* This is useful for positioning groups of markers, tooltips, or indicator views
* without scaling, while the reference element(s) are scaled.
*/
public class TranslationLayout extends AnchorLayout {
protected double scale = 1;
public TranslationLayout(Context context){
super(context);
}
/**
* Sets the scale (0-1) of the ZoomPanLayout
* @param scale (double) The new value of the ZoomPanLayout scale
*/
public void setScale(double d){
scale = d;
requestLayout();
}
/**
* Retrieves the current scale of the ZoomPanLayout
* @return (double) the current scale of the ZoomPanLayout
*/
public double getScale() {
return scale;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
int width = 0;
int height = 0;
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
TranslationLayout.LayoutParams lp = (TranslationLayout.LayoutParams) child.getLayoutParams();
// get anchor offsets
float aX = (lp.anchorX == null) ? anchorX : lp.anchorX;
float aY = (lp.anchorY == null) ? anchorY : lp.anchorY;
// offset dimensions by anchor values
int computedWidth = (int) (child.getMeasuredWidth() * aX);
int computedHeight = (int) (child.getMeasuredHeight() * aY);
// get offset position
int scaledX = (int) (0.5 + (lp.x * scale));
int scaledY = (int) (0.5 + (lp.y * scale));
// add computed dimensions to actual position
int right = scaledX + computedWidth;
int bottom = scaledY + computedHeight;
// if it's larger, use that
width = Math.max(width, right);
height = Math.max(height, bottom);
}
}
height = Math.max(height, getSuggestedMinimumHeight());
width = Math.max(width, getSuggestedMinimumWidth());
width = resolveSize(width, widthMeasureSpec);
height = resolveSize(height, heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
LayoutParams lp = (LayoutParams) child.getLayoutParams();
// get sizes
int w = child.getMeasuredWidth();
int h = child.getMeasuredHeight();
// get offset position
int scaledX = (int) (0.5 + (lp.x * scale));
int scaledY = (int) (0.5 + (lp.y * scale));
// user child's layout params anchor position if set, otherwise default to anchor position of layout
float aX = (lp.anchorX == null) ? anchorX : lp.anchorX;
float aY = (lp.anchorY == null) ? anchorY : lp.anchorY;
// apply anchor offset to position
int x = scaledX + (int) (w * aX);
int y = scaledY + (int) (h * aY);
// set it
child.layout(x, y, x + w, y + h);
}
}
}
}