背景
我想要一个填充的圆形,带有特定颜色和宽度的描边,并且内部有一张图像。
这在XML中很容易实现,例如(这只是一个示例):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<size
android:width="120dp" android:height="120dp"/>
<solid android:color="#ffff0000"/>
<stroke
android:width="3dp" android:color="#ff00ff00"/>
</shape>
</item>
<item
android:width="60dp" android:height="60dp" android:drawable="@android:drawable/btn_star"
android:gravity="center"/>
</layer-list>
问题
我需要以编程的方式更改上述内容的某些属性,因此无法使用XML文件,但是思路仍然相同。
问题在于,我找不到一种简单的方法来在OvalShape drawable上绘制描边,就像在XML中一样。我找不到可以实现此功能的函数。
我尝试过的
有一些解决方案在StackOverflow上,但我找不到一个有效的解决方案。我只发现了这里的一个,但它的描边线被切断了。
但是,我已经在某种程度上成功地解决了这个问题,通过仅使用XML本身进行描边:
stroke_drawable.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<stroke
android:width="4dp" android:color="@android:color/white"/>
</shape>
代码:
final int strokeDrawableResId = R.drawable.stroke_drawable;
Drawable innerDrawable = ResourcesCompat.getDrawable(getResources(), ..., null);
final Drawable strokeDrawable = ResourcesCompat.getDrawable(getResources(), strokeDrawableResId, null);
ShapeDrawable biggerCircle = new ShapeDrawable(new OvalShape());
int size = ...;
biggerCircle.setIntrinsicHeight(size);
biggerCircle.setIntrinsicWidth(size);
biggerCircle.getPaint().setColor(0xffff0000);
biggerCircle.setBounds(new Rect(0, 0, size, size));
LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{biggerCircle, strokeDrawable, innerDrawable});
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageDrawable(layerDrawable);
它可以工作,但它不完全是程序化的(笔画在XML中定义)。
问题
如何更改代码以完全编程化?
编辑:我尝试了这里建议的内容,但是我需要将所有内容放在一个可绘制对象中,而不是为背景添加额外的可绘制对象,因此我使用了LayerDrawable:
Drawable innerDrawable = ResourcesCompat.getDrawable(getResources(), android.R.drawable.btn_star, null);
int strokeWidth = 5;
int strokeColor = Color.parseColor("#ff0000ff");
int fillColor = Color.parseColor("#ffff0000");
GradientDrawable gD = new GradientDrawable();
gD.setColor(fillColor);
gD.setShape(GradientDrawable.OVAL);
gD.setStroke(strokeWidth, strokeColor);
LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{gD, innerDrawable});
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageDrawable(layerDrawable);
这种方法可以实现,但是内部的可绘制对象(即星号)似乎被拉伸了: