I am trying to make a custom view that is square, using the width as the height. I am also using a pre-defined layout which I inflate as it's UI. As soon as I overrode onMeasure, the custom view no longer appears. Here is my code:
public class MyView extends RelativeLayout{
public MyView(Context context) {
super(context);
addView(setupLayout(context));
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
addView(setupLayout(context));
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
addView(setupLayout(context));
}
private View setupLayout(Context context) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View myView = inflater.inflate(R.layout.view_layout, null);
return myView;
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(widthMeasureSpec));
}
}
I have 2 questions:
- How do I override onMeasure so that it draws my view the way I am expecting it to?
- Is there any way I can make this more efficient in terms of the view hierarchy (i.e. not be putting a RelativeLayout inside a RelativeLayout)
-
1@trumpetlicks RlativeLayout is a descendant of View. What is your second point?Sam– Sam2012年06月30日 19:59:45 +00:00Commented Jun 30, 2012 at 19:59
-
It's a miracle that this one compiles. You have a constructor for a different class in it (MenuButton).tiguchi– tiguchi2012年06月30日 20:03:30 +00:00Commented Jun 30, 2012 at 20:03
-
1@NobuGames I'm willing to guess that this a simplified version of the author's class. The author felt the need to change the class name, they simply forgot to change that constructor's name too. There is no need for sarcasm, I'm willing to guess that you're not perfect either.Sam– Sam2012年06月30日 20:07:00 +00:00Commented Jun 30, 2012 at 20:07
-
@Sam You are right. I was being sarcastic. But my intention was actually pointing out an obvious error. I do not always take people's problem descriptions here for granted and try to see the problem in the code itself. And you are right I am not perfect, because it slipped my mind that it could have been just some editing mistake.tiguchi– tiguchi2012年06月30日 20:26:52 +00:00Commented Jun 30, 2012 at 20:26
1 Answer 1
You can use this code from Jan Němec's answer to a similar question :
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class SquareLayout extends LinearLayout {
public SquareLayout(Context context) {
super(context);
}
public SquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (width > (int)(mScale * height + 0.5)) {
width = (int)(mScale * height + 0.5);
} else {
height = (int)(width / mScale + 0.5);
}
super.onMeasure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
);
}
}
Or try to use this library project.
answered Jun 30, 2012 at 20:03
K_Anas
31.4k9 gold badges71 silver badges81 bronze badges
Sign up to request clarification or add additional context in comments.
4 Comments
user
Don't copy other users answers!
K_Anas
is that forbidden? we are here as community to help each other, the main goal is sharing information!! anyway I have edited my answer with a link to the original one.
BoltClock
Sharing an answer is not copying the answer and passing it off as your own without any links to the original source. And I don't see any edits on your answer.
Brad Larson
I've made the attribution very clear in my edit, so you can follow this style when referring to other answers in the future. However, if the question really can be answered by something from another question, the questions themselves might be duplicates, so you could also cast a close vote in that case.
default