渐变半径作为屏幕大小的百分比

我试图创build一个可绘制的径向渐变背景形状,其半径将根据屏幕大小进行调整(请参阅相关文档 )。

这是我的代码:

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <gradient android:endColor="#000" android:gradientRadius="50%p" android:startColor="#5d2456" android:type="radial" /> </shape> 

但它似乎不工作。 如果我删除“%P”,它的工作,但是然后半径将是静态的,因此不调整到屏幕大小…任何想法有什么不对?

从我testing的结果来看, %确实有效,但并不像你预期的那样。
首先

 android:gradientRadius="50" 

似乎采取的像素为50px的值

 android:gradientRadius="50%" 

转换为50%= 0.5像素,尝试

 android:gradientRadius="5000%" 

你会看到一个50px的半径。
使用%p有类似的结果。 显然这是我希望将来会改变的,因为它没有多less用处。 通常,XML ShapeDrawable资源会将其大小调整为某个外部容器,在这种情况下, gradientRadius将设置大小而不考虑容器。

我最终创build了一个自定义视图与以下重写onDraw方法:

 @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); int maxSize = Math.max(getHeight(), getWidth()); RadialGradient gradient = new RadialGradient( getWidth()/2, getHeight()/2, maxSize, new int[] {Color.RED, Color.BLACK}, new float[] {0, 1}, android.graphics.Shader.TileMode.CLAMP); paint.setDither(true); paint.setShader(gradient); canvas.drawRect(0, 0, getWidth(), getHeight(), paint); } 

在你的布局只需添加视图:

 <yourpackage.GradientView android:layout_width="match_parent" android:layout_height="match_parent" /> 

当然,可以为视图创build属性,例如。 颜色,允许通过XML自定义的百分比。

请注意gradientRadius百分比在棒棒糖中起作用。 但是,如果你必须支持pre-Lollipop,我扩展@ marnaish的答案添加XML属性。 我的gradientRadius被定义为父视图的宽度的百分比:

 public class RadialGradientView extends View { private final int endColor; private final int startColor; private final float gradientRadiusWidthPercent; private final float centerY; private final float centerX; private Paint paint; public RadialGradientView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RadialGradientView, 0, 0); startColor = a.getColor(R.styleable.RadialGradientView_startColor, Color.RED); endColor = a.getColor(R.styleable.RadialGradientView_endColor, Color.BLACK); gradientRadiusWidthPercent = a.getFloat(R.styleable.RadialGradientView_gradientRadiusWidthPercent, 1); centerX = a.getFloat(R.styleable.RadialGradientView_centerX, .5f); centerY = a.getFloat(R.styleable.RadialGradientView_centerY, .5f); a.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int parentHeight = MeasureSpec.getSize(heightMeasureSpec); paint = new Paint(Paint.ANTI_ALIAS_FLAG); RadialGradient gradient = new RadialGradient( parentWidth*centerX, parentHeight*centerY, parentWidth*gradientRadiusWidthPercent, new int[] {startColor, endColor}, null, android.graphics.Shader.TileMode.CLAMP); paint.setDither(true); paint.setShader(gradient); } @Override protected void onDraw(Canvas canvas) { canvas.drawRect(0, 0, getWidth(), getHeight(), paint); } } 

在attrs.xml中:

 <declare-styleable name="RadialGradientView"> <attr name="startColor" format="color|reference"/> <attr name="endColor" format="color|reference"/> <attr name="gradientRadiusWidthPercent" format="float"/> <attr name="centerX" format="float"/> <attr name="centerY" format="float"/> </declare-styleable> 

不幸的是,你不能从一个自定义的类创build一个XML drawable,所以你不能把它设置为一个View的android:background。 解决方法是使用FrameLayout将其作为背景进行分层。

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="100dp"> <com.RadialGradientView android:layout_width="match_parent" android:layout_height="match_parent" app:centerX=".3" app:centerY=".5" app:endColor="#0f0" app:startColor="#f00" app:gradientRadiusWidthPercent=".5" /> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="What's up world?"/> </FrameLayout> 

您可以在运行时创build一个可绘制的形状,类似于这篇文章https://stackoverflow.com/a/4943888/604504

这样你可以计算出检索屏幕大小后的百分比。