Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shape Drawable gradientRadius only works in pixels. Isn't this useless? % values don't work

I want to use shape drawable with a radial gradient as a background for a View. According to the javadoc the radius of the gradient can be set as a specific value (presumably pixels) or as a percent:

android:gradientRadius

Radius of the gradient, used only with radial gradient.

May be a floating point value, such as "1.2".

May be a fractional value, which is a floating point number appended with either % or %p, such as "14.5%". The % suffix always means a percentage of the base size; the optional %p suffix provides a size relative to some parent container.

Correct me if I'm wrong, but using a pixel value here is completely useless since this gradient will look totally different from one screen density to another (tested, and yes this is true). I tried to go with the % and %p values, but they didn't work at all.

I dove into the Android source code to see how gradientRadius is being processed and found this in the GradientDrawable Class:

TypedValue tv = a.peekValue(
    com.android.internal.R.styleable.GradientDrawableGradient_gradientRadius);
    if (tv != null) {
        boolean radiusRel = tv.type == TypedValue.TYPE_FRACTION;
        st.mGradientRadius = radiusRel ?
         tv.getFraction(1.0f, 1.0f) : tv.getFloat();
    } else ...
}

Ah HA! So all adding % or %p does is divide my value by 100. (I tested this because the documentation for TypeValue.getFraction() is even more unclear). 65% became 0.65. Makes sense, but serves no useful purpose.

So what is the best way to use gradientRadius?

PS. I have added my background programmatically using a GradientDrawable and I am getting the desired results. I used GradientDrawable.setGradientRadius() with a value relative to the view width and get a consistent Gradient across devices.

like image 793
nathanielwolf Avatar asked Dec 21 '12 01:12

nathanielwolf


1 Answers

To work with all the screen size you have to set radius in dp. You can calculate px from dp by this method

 public float pxfromDp(float dp) {
    return dp * getResources().getDisplayMetrics().density;
}

So for example you want to set GradientDrawable.setGradientRadius(pxfromDp(7));

like image 50
Asheesh Avatar answered Sep 20 '22 17:09

Asheesh