简体   繁体   中英

Custom view sizes for different devices

I have made a custom view by extend the View class. Currently I have an int which defines the size of view. Then I override the onMeasure method and made the width and height equal to the int.

Like this:

private int DEFAULT_SIZE = 80;
public Paint mOuterCirclePaint = new Paint();

@Override
protected void onDraw(Canvas canvas) {

mOuterCirclePaint.setStyle(Style.STROKE);
    mOuterCirclePaint.setStrokeWidth(5.0f);
    mOuterCirclePaint.setDither(true);
    mOuterCirclePaint.setAntiAlias(true);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    setMeasuredDimension(
            DEFAULT_SIZE + 5
                    + (int) mOuterCirclePaint.getStrokeWidth() / 2,
            DEFAULT_SIZE + 5
                    + (int) mOuterCirclePaint.getStrokeWidth() / 2);

}


public void setSize(int defaultSize) {
    DEFAULT_SIZE = defaultSize;
    invalidate();

}

But this means my view does not scale well on different devices of different resolutions. On a high resolution device, the view appears small, but on a low resolution device, the view is large.

I don't think creating a new view for each resolution is a good idea. I have tried scaling the view my multiplying the DEFAULT_SIZE by the density of the device ( float scale = getResources().getDisplayMetrics().density; ), but this doesn't have an affect on the low res device, but makes the view take up more than the whole screen (you can't see it) on the high res device

So what is the best way to make a custom view for different devices? Am I on the right lines or is there a another way of doing it?

You could use dimension resources and use

int defaultSize = (int)context.getResources().getDimension(R.dimen.default_size);

in constructor of custom view with this in res/values/dimes.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="default_size">80dp</dimen>
</resources>

Now the size will be scaled due to density of the screen of device.

Here is simple example of measured view:

public class MeasuredView extends View
{
    private int m_defaultSize;

    public MeasuredView(Context context)
    {
        super(context);

        init(context);
    }

    public MeasuredView(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        init(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        setMeasuredDimension(m_defaultSize, m_defaultSize);
    }

    private void init(Context context)
    {
        m_defaultSize = (int)context.getResources().getDimension(R.dimen.default_value);
    }
}

On xhdpi size is 160 px, on hdpi its 120 and on mdpi its 80.

You should know that setSize(int defaultSize) takes argument value as pixels so if you want to set it as dp you can write method

public void setDefaultSizeDp(int defaultSizeDp)
    {
        int defaultSizePx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, defaultSizeDp, getResources().getDisplayMetrics());

        m_defaultSize = defaultSizePx;
        invalidate();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM