Flynn
Flynn

Reputation: 6211

Android: Custom View

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:

  1. How do I override onMeasure so that it draws my view the way I am expecting it to?
  2. 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)

Upvotes: 1

Views: 1869

Answers (1)

K_Anas
K_Anas

Reputation: 31466

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.

Upvotes: 1

Related Questions