7

我遇到了剪辑问题。

首先,我尝试仅使用 Xml 显示椭圆形。我有以下代码:

res/drawable/circle.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    <size
        android:width="240dp"
        android:height="240dp" />
    <solid
        android:color="#FFFFFF" />
    <stroke
        android:width="2dp"
        android:color="#EEEEEE" />
</shape>    

*res/layout/test.xml

....
<RelativeLayout
    android:id="@+id/circle_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1" >

    <ImageView
        android:src="@drawable/circle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>
....

它完美地工作,并给了我这个:截图

问题是,由于各种原因,我必须在程序上做同样的事情。

我有这个代码:

RelativeLayout layout = (RelativeLayout) findViewById(R.id.circle_layout);

ShapeDrawable drawable = new ShapeDrawable(new OvalShape());
drawable.getPaint().setColor(Color.parseColor("#EEEEEE"));
drawable.getPaint().setStyle(Style.STROKE);
drawable.getPaint().setStrokeWidth(dpToPx(2));
drawable.getPaint().setAntiAlias(true);
drawable.setIntrinsicHeight(dpToPx(240));
drawable.setIntrinsicWidth(dpToPx(240));

ImageView iv = new ImageView(this);
iv.setImageDrawable(drawable);

RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
iv.setLayoutParams(lp);

layout.addView(iv);

dpToPx 函数是:

private float scale = 0;

private float getScale() {
    if (scale == 0)
        scale  = this.getResources().getDisplayMetrics().densityDpi / 160f;
    return scale;
}

public float dpToPx(float dp) {
    return dp * getScale();
}

...这应该给我同样的东西吧?好吧,它给出了一个稍大的圆圈,顶部,右侧,底部和左侧边缘被剪裁。这是一个屏幕截图(屏幕区域与上一个屏幕相同):Screehshot

有人知道什么和为什么?

谢谢你。

编辑:

如果我将描边宽度设置为更高的值(12dp),我得到了这个:截图

4

5 回答 5

23

我在此页面上找到了解决方案:http ://www.betaful.com/2012/01/programmatic-shapes-in-android/

在 Android 中,当您使用笔画进行绘制时,它会在您正在绘制的形状的边界处绘制笔画的中心。如您所见,笔画被图像的边界裁剪。幸运的是,您可以在画布上执行转换。我们想要做的是将我们的笔划形状转换为比边界略小 - 并且有一个矩阵操作!

matrix.setRectToRect(new RectF(0, 0, canvas.getClipBounds().right, canvas.getClipBounds().bottom),
new RectF(strokeWidth/2, strokeWidth/2, canvas.getClipBounds().right - strokeWidth/2,
    canvas.getClipBounds().bottom - strokeWidth/2),
Matrix.ScaleToFit.FILL);

编辑

...在链接的评论部分找到更好更简单的解决方案:

正如您在 Android 文档中看到的,资源中的 shape Drawable 实际上映射到 GradientDrawable,而不是 ShapeDrawable:

因此,我的以下代码运行良好:

GradientDrawable drawable = new GradientDrawable();
drawable.setColor(Color.TRANSPARENT);
drawable.setShape(GradientDrawable.OVAL);
drawable.setStroke((int)dpToPx(2), Color.parseColor("#EEEEEE"));
drawable.setSize((int)dpToPx(240), (int)dpToPx(240));
于 2013-09-09T10:33:26.197 回答
0

您使用 setIntrinsicHeight,尝试将其设置为您的 Height/With - strokeWidth,因此在本例中将 Width 和 Height 设置为 238。

于 2013-09-09T07:58:05.383 回答
0

你应该删除这个:

 drawable.getPaint().setStrokeWidth(dpToPx(2));
于 2013-09-09T09:28:11.747 回答
0

我遇到了同样的问题。这可能是由于 Android 中的错误而发生的。解决方案是将 parentView的填充设置为某个值,然后在将来的某个时间点将其设置回所需的值。

// set stroke properties programmatically
viewWithStroke.background
        .let {it as GradientDrawable}
        .setStroke(newBorderThickness,newBorderColor)

// set padding to some value now, then to the desired value later as a
// work-around for the weird android bug where strokes get clipped because
// android is not refreshing the view layouts properly
val parentOfViewWithStroke = viewWithStroke.parent.let {it as ViewGroup}
parentOfViewWithStroke.setPadding(
        newBorderPadding+1,newBorderPadding+1,
        newBorderPadding+1,newBorderPadding+1)
viewWithStroke.post()
{
    parentOfViewWithStroke.setPadding(
            newBorderPadding,newBorderPadding,
            newBorderPadding,newBorderPadding)
}

PS:我尝试使用View.invalidate()View.requestLayout()无法正常工作。

于 2019-01-28T00:52:16.253 回答
-1

我有同样的剪裁问题,这个简单的配置给了我我需要的外观,没有任何剪裁:

红环.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    <solid android:color="@android:color/transparent" />
    <stroke
        android:width="2dp"
        android:color="#ff00" />
</shape>

用法:

<View
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@drawable/redring" />
于 2014-05-10T04:52:05.430 回答