Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Setting button height in XML based on it's width

I am working on layout in android XML in which I would like to set a buttons height to match it's width when setup to fill parent. Obviously this number will change based on screen size, so I cannot use a set pixel size. Can someone help me with getting the button width based on screen size and then passing that to the height setting?

Thank You, Josh

like image 330
Josh Avatar asked Nov 06 '22 07:11

Josh


1 Answers

I once had a similar problem and found no solution which works just from XML. You have to write your own Button-Class and overwrite the [onMeassure][1] method.

Example:

/**
 * @see android.view.View#measure(int, int)
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}

private int width; // saves the meassured width


/**
 * Determines the width of this view
 * 
 * @param measureSpec
 *            A measureSpec packed into an int
 * @return The width of the view, honoring constraints from measureSpec
 */
private int measureWidth(int measureSpec) {
    int result = 30;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    if (specMode == MeasureSpec.EXACTLY) {
        // We were told how big to be
        result = specSize;
    } else {
        result =1123; // meassure your with here somehow
        if (specMode == MeasureSpec.AT_MOST) {
            // Respect AT_MOST value if that was what is called for by measureSpec
            result = Math.min(result, specSize);
        }
    }
            width = result;
    return result;
}

/**
 * Determines the height of this view
 * 
 * @param measureSpec
 *            A measureSpec packed into an int
 * @return The height of the view, honoring constraints from measureSpec
 */
private int measureHeight(int measureSpec) {
    int result = 0;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    if (specMode == MeasureSpec.EXACTLY) {
        // We were told how big to be
        result = specSize;
    } else {
        result = width;
        if (specMode == MeasureSpec.AT_MOST) {
            // Respect AT_MOST value if that was what is called for by measureSpec
            result = Math.min(result, specSize);
        }
    }

    return result;
}

[1]: http://developer.android.com/reference/android/view/View.html#onMeasure(int, int)

like image 116
whlk Avatar answered Nov 11 '22 10:11

whlk