I have currently implemented a custom ViewGroup class, that attempts to position items (buttons with drawables) evenly and diagonally across the screen.
Unfortunately if the items are too big they tend to overlap to make sure everything fits on the screen.
I am hoping that there’s an easier way to accomplish this with already existing layouts (API8+), or if there is something simple I can change in my ViewGroup class to make the child views smaller to avoid the overlapping. (Such as making each child view the exact size needed to evenly layout without overlap)
Here is my onMeasure class (not doing anything special. letting children measure themselfs)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
}
EDIT: If I change onMeasure to manually measure the children to a certain width/height they get clipped. It doesn’t seem like the child view (or its drawable) actually scales itself to fit inside the measurement.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int newChildWidth = width / getChildCount();
int newChildHeight = height / getChildCount();
final int size = getChildCount();
for (int i = 0; i < size; ++i) {
View child = getChildAt(i);
child.measure(MeasureSpec.EXACTLY | newChildWidth, MeasureSpec.EXACTLY | newChildHeight);
}
setMeasuredDimension(width, height);
}
So far you’ve got the right idea, if you want the child views to lay out exactly diagonal, it’s the job of the enclosing
ViewGroupto provide them theMeasureSpecto accomplish that andMeasureSpec.EXACTLYwill tell each child how large to be. You could also swap that out forMeasureSpec.AT_MOSTto allow children with less content to be smaller, they would just never exceed the size you provided, whereasEXACTLYmakes them all the same size every time.The problem you are describing now is one that cannot really be solved without some
Viewcustomization. Android views pretty exclusively operate in the paradigm of “resize the view to its content” and not “resize the content to the size of the view”. So if you tell aButtonto be smaller than the space it needs to draw its text/image contents, it will simply clip. The one exception to this rule isImageView. If you would like to circumvent this, you will need to customizeButtonto resize the text size and drawable based on the specs given to it inonMeasure()Another possible option, since you are customizing
ViewGroupanyway, is to make use of child static transformations. By callingsetStaticTransformationsEnabled(true)in yourViewGroupand overridinggetChildStaticTransformation()you could apply a scale factor to each child view that wants to be larger than your specific size. This transformation is similar to how animations work, so the whole view will be scaled down.HTH