【问题标题】:View with round corners not smooth圆角视图不平滑
【发布时间】:2014-01-12 13:23:12
【问题描述】:

看看我下面的代码。

ShapeDrawable shapeDrawable = new ShapeDrawable(new RectShape());
    shapeDrawable.getPaint().setColor(Color.parseColor("#5a2705"));
    shapeDrawable.getPaint().setStyle(Style.STROKE);
    shapeDrawable.getPaint().setAntiAlias(true);
    shapeDrawable.getPaint().setStrokeWidth(2);
    shapeDrawable.getPaint().setPathEffect(new CornerPathEffect(10));

我将此作为背景应用到我的LinearLayout,但边缘不平滑。我该如何解决这个问题?

这是它的外观截图。

【问题讨论】:

  • 您是否尝试过使用RoundRectShape 而不是CornerPathEffect
  • 不,我没试过,你能告诉我怎么做吗?
  • 是的,我试过了,但边缘仍然不光滑,它仍然很难看,如我问题中的图片所示,请告诉我是否有其他方法

标签: android rounded-corners android-shapedrawable


【解决方案1】:

使用以编程方式创建的可绘制形状作为视图背景会导致笔划宽度的外半部分被裁剪掉(原因我不知道)。仔细查看您的图像,您会发现您的笔划只有 1 个像素宽,即使您要求 2 个像素宽。这就是边角看起来难看的原因。如果您分别尝试更大的笔划和半径(例如 10 和 40),这种效果会更加明显。

要么使用 XML drawable,它似乎没有这个问题,就像在 Harshit Jain 的回答中一样,或者如果您必须(或更喜欢)使用编程解决方案,请执行以下操作。

解决方案:使用图层列表将矩形插入剪裁量(笔划宽度的一半),如下所示:

float strokeWidth = 2;

ShapeDrawable shapeDrawable = new ShapeDrawable(new RectShape());
shapeDrawable.getPaint().setColor(Color.parseColor("#5a2705"));
shapeDrawable.getPaint().setStyle(Style.STROKE);
shapeDrawable.getPaint().setAntiAlias(true);
shapeDrawable.getPaint().setStrokeWidth(strokeWidth);
shapeDrawable.getPaint().setPathEffect(new CornerPathEffect(10));

Drawable[] layers = {shapeDrawable};
LayerDrawable layerDrawable = new LayerDrawable(layers);

int halfStrokeWidth = (int)(strokeWidth/2);
layerDrawable.setLayerInset(0, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth);

然后使用layerDrawable 作为您的背景。这是上面代码结果的屏幕截图:

【讨论】:

  • 这对我帮助很大!应该是公认的答案。
  • 谢谢!我将问题误解为拐角的外边缘和内边缘具有相同的半径,但实际上是剪裁。我将 drawRoundRect 与 RectF(0, 0, getWidth(), getHeight()) 一起使用。解决方案大致相同:将 RectF 插入一半 strokeWidth。
  • 谢谢@FletcherJohns,遇到了同样的问题,但这解决了它
【解决方案2】:

您可以尝试使用圆角矩形的布局创建一个单独的 xml 文件。如:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="color_here"/>
    <stroke android:width="5dp" android:color="color_here"/>
    <corners android:radius="2dp"/>
</shape>

您可以根据自己的喜好对其进行调整,并将此 XML 文件用作主 XML 中的背景。

您也可以尝试使用 SDK 自带的 9Patch

【讨论】:

    【解决方案3】:

    为了满足这样的背景要求,我更喜欢使用 9-patch drawable。 以下是创建和使用 9-patch 可绘制资源的指南:

    1. 开发者文档:http://developer.android.com/tools/help/draw9patch.html

    2. 另一种解释:http://radleymarx.com/blog/simple-guide-to-9-patch/

    3. Online tool 创建 9-patch 图像。 (注意:保存图片时修改文件扩展名为*.9.png

    【讨论】:

    • 你推荐的在线工具很棒!!
    【解决方案4】:

    你可能想考虑checkingthis out。

    Rounded Image Views 文斯

    【讨论】:

    • 这对我的经验有很大帮助。还有很棒的 UI 页面。
    【解决方案5】:

    我已经用非常简单的方式解决了这个问题,

    我正在寻找可以通过编程而不是通过 xml 完成的代码,

    代码如下:

    GradientDrawable shape = new GradientDrawable();
        shape.setCornerRadius(10);
        shape.setColor(Color.WHITE);
        shape.setStroke(2, Color.parseColor("#996633"));
    

    你可以这样设置:view.setBackgroundDrawable(shape);

    @Tenfour04 发布的答案也可能解决问题,但我没有尝试过。

    希望对某人有所帮助。

    【讨论】:

      【解决方案6】:

      您可以尝试使用这样的选择器。这个解决方案是最好的,您只需将此选择器设置为布局的背景。

      <?xml version="1.0" encoding="utf-8"?>
      <shape xmlns:android="http://schemas.android.com/apk/res/android">
          <solid android:color="@color/white" />
          <stroke android:width="1dp" android:color="@color/grey" />
          <padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
          <corners android:radius="15dp" />
               <gradient
                android:angle="90"
                android:startColor="@color/white"
                android:centerColor="@color/grey"
                android:endColor="@color/white"
                android:type="linear" />
      </shape>
      

      选择你自己的颜色。 干杯!

      【讨论】:

        【解决方案7】:

        我最近遇到了这个问题并想出了一个不同的解决方案。恕我直言,最好的解决方案是创建自己的 Shape 实现并使用它来创建 ShapeDrawable

        下面是一个圆角矩形的简单实现,它可以让你插入它的边框。

        class InsetRoundRectShape(
            private var radiusArray: FloatArray = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f),
            private var inset: RectF = RectF()
        ): RectShape() {
        
            private var innerRect: RectF = RectF()
            private var path: Path = Path()
        
            constructor(radius: Float, inset: RectF): this(floatArrayOf(radius, radius, radius, radius, radius, radius, radius, radius), inset)
            constructor(radius: Float, inset: Float): this(radius, RectF(inset, inset, inset, inset))
        
            init {
                if (radiusArray.size < 8) {
                    throw ArrayIndexOutOfBoundsException("radius array must have >= 8 values")
                }
            }
        
            override fun draw(canvas: Canvas, paint: Paint) {
                canvas.drawPath(path, paint)
            }
        
            override fun getOutline(outline: Outline) {
                super.getOutline(outline)
        
                val radius = radiusArray[0]
                if(radiusArray.any { it != radius }) {
                    outline.setConvexPath(path)
                    return
                }
        
                val r = rect()
                outline.setRoundRect(ceil(r.left).toInt(), ceil(r.top).toInt(), floor(r.right).toInt(), floor(r.bottom).toInt(), radius)
            }
        
            override fun onResize(w: Float, h: Float) {
                super.onResize(w, h)
                val r = rect()
                path.reset()
                innerRect.set(r.left + inset.left, r.top + inset.top, r.right - inset.right, r.bottom - inset.bottom)
                if(innerRect.width() <= w && innerRect.height() <= h) {
                    path.addRoundRect(innerRect, radiusArray, Path.Direction.CCW)
                }
            }
        
            override fun clone(): InsetRoundRectShape {
                val shape = super.clone() as InsetRoundRectShape
                shape.radiusArray = radiusArray.clone()
                shape.inset = RectF(inset)
                shape.path = Path(path)
                return shape
            }
        }
        

        像这样创建 ShapeDrawable

        //Inset has to be half of strokeWidth
        ShapeDrawable(InsetRoundRectShape(10f, 4f)).apply {
            this.paint.color = Color.BLUE
            this.paint.style = Paint.Style.STROKE
            this.paint.strokeWidth = 8.dp
            this.invalidateSelf()
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-02-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-08
          相关资源
          最近更新 更多