代码之家  ›  专栏  ›  技术社区  ›  Yash Sampat

Android九补丁-仅允许背景的特定区域拉伸

  •  5
  • Yash Sampat  · 技术社区  · 9 年前

    如何创建 View 有三角形穿孔的边界?

    enter image description here

    到目前为止,我一直在使用背景绘图来实现这一点。当 看法 固定。现在我的情况是 身高 看法 不是恒定的,所以我需要动态改变高度。我不能再使用固定高度的背景绘制。

    以下是原始背景图:

    enter image description here

    这是最终的结果 看法 需要看起来像:

    enter image description here

    另一种看待同一问题的方式是,我们可以允许图像的中心在不扭曲边界的情况下拉伸吗?如果我们能做到这一点,我们可以使用现有的可绘制文件作为背景。

    如何做到这一点?以前有人遇到过这个问题吗?框架是否有处理这类问题的现有方法?

    4 回复  |  直到 9 年前
        1
  •  2
  •   Yash Sampat    9 年前

    您可以生成一个九补丁png,而不是使用普通图像。

    使用 Simple Nine-patch Generator 为此。

    诀窍是左边的黑线。这告诉Android,png可以沿着这个区域垂直扩展。

    请参见以下示例:

    Nine Patch Example

    将其保存为九个补丁,格式为imagename.9.png

        2
  •  2
  •   Harish_N    9 年前

    您可以使用 NinePatch图像 如该视图所示。要了解如何创建NinePatch图像,请转到 Draw 9-patch

        3
  •  1
  •   Jeff Lockhart    6 年前

    9补丁机制不能为我的用例做类似的事情,因为它需要在水平和垂直方向上定义一个可拉伸区域。只有在 ImageView 能够被限制到源可绘制的精确宽度,以避免任何水平拉伸。

    如果需要允许视图水平拉伸,保持图像的顶部和底部边界部分的纵横比,而允许中间部分在两个方向上自由拉伸,则9补丁将不适用于此。我创建这个布局是为了实现这一点:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/backgroundImage"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <ImageView
            android:id="@+id/imageTop"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:adjustViewBounds="true"
            android:layout_weight="0"
            android:src="@drawable/image_top" />
    
        <ImageView
            android:id="@+id/imageMiddle"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:layout_weight="1"
            android:background="@drawable/image_middle" />
    
        <ImageView
            android:id="@+id/imageBottom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitXY"
            android:adjustViewBounds="true"
            android:layout_weight="0"
            android:src="@drawable/image_bottom" />
    
    </LinearLayout>
    

    图片_top.png enter image description here

    image_middle.png enter image description here (注意,如果不需要右侧的细微灰度梯度,此图像可以缩小到1像素高。)

    image_bottom.png enter image description here

    关键是 android:adjustViewBounds="true" 在边界图像上,同时使用 android:src 。然后中间的图像指定 android:background 并调整大小以填充父布局的高度 android:layout_height="match_parent" android:layout_weight="1" .

    android:scaleType="fitXY" 此外,为了在调整图像的视图边界以处理高分辨率显示器上对齐中的任何潜在微小像素差异后,强制对图像进行最终缩放,还必须进行调整。它们都会调整大小,以完全填充边界。

        4
  •  0
  •   beigirad    6 年前

    您可以在视图的背景中绘制锯齿形路径

    Rect rectZigzag = new Rect();
    private Path pathZigzag = new Path();
    private Paint paintZigzag;
    private void init(){
        this.paintZigzag = new Paint();
        this.paintZigzag.setColor(zigzagBackgroundColor);
        this.paintZigzag.setStyle(Style.FILL);
    }
    
    
    private void drawZigzag() {
        float left = rectZigzag.left;
        float right = rectZigzag.right;
        float top = rectZigzag.top;
        float bottom = rectZigzag.bottom;
        int width = (int) (right - left);
    
        pathZigzag.moveTo(right, bottom);
        pathZigzag.lineTo(right, top);
        pathZigzag.lineTo(left, top);
        pathZigzag.lineTo(left, bottom);
    
        int h = zigzagHeight;
        int seed = 2 * h;
        int count = width / seed;
        int diff = width - (seed * count);
        int sideDiff = diff / 2;
    
    
        float x = (float) (seed / 2);
        float upHeight = bottom - h;
        float downHeight = bottom;
    
        for (int i = 0; i < count; i++) {
            int startSeed = (i * seed) + sideDiff + (int) left;
            int endSeed = startSeed + seed;
    
            if (i == 0) {
                startSeed = (int) left + sideDiff;
            } else if (i == count - 1) {
                endSeed = endSeed + sideDiff;
            }
    
            this.pathZigzag.lineTo(startSeed + x, upHeight);
            this.pathZigzag.lineTo(endSeed, downHeight);
        }
    }
    

    refrence