我遇到了裁剪问题。
首先,我尝试仅显示带有Xml的椭圆形状。我有以下代码:
RES /抽拉/ 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 /布局/的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>
....
它完美无缺,并且给了我:Screenshot
问题是,出于各种原因,我必须以程序方式进行相同的操作。
我有这段代码:
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),我就得到了这个:Screenshot
答案 0 :(得分:22)
我在此页面上找到了解决方案:http://www.betaful.com/2012/01/programmatic-shapes-in-android/
在Android中,当您使用笔划绘制时,它会在您绘制的形状的边界处绘制笔划的中心。如您所见,笔划会被图像的边界裁剪掉。幸运的是,您可以在画布上执行转换。我们想要做的是将我们的笔触形状转换为略小于边界 - 并且有一个Matrix操作!
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文档中看到的那样,资源中的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));
答案 1 :(得分:0)
您使用setIntrinsicHeight,尝试将其设置为Height / With - strokeWidth,因此在这种情况下将Width和Height设置为238。
答案 2 :(得分:0)
你应该删除它:
drawable.getPaint().setStrokeWidth(dpToPx(2));
答案 3 :(得分:0)
我遇到了同样的问题。这可能是由于Android中的错误引起的。解决方案是将父View
的填充设置为某个值,然后在将来某个时候将其重新设置为所需的值。
// 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)
}
P.S .:我尝试使用View.invalidate()
和View.requestLayout()
,但无法正常工作。
答案 4 :(得分:-1)
我有同样的裁剪问题,这个简单的配置给了我所需的外观,没有任何裁剪:
redring.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" />